百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
W

waku

> 编程语言
开源

⛩️ 简洁的 React 框架

6.4K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

⛩️ 简洁的 React 框架

# Waku ⛩️ The minimal React framework visit [waku.gg](https://waku.gg) or `npm create waku@latest`
## Introduction **Waku** _(wah-ku)_ or **わく** is the minimal React framework. It's lightweight and designed for a fun developer experience, yet supports all the latest React 19 features like server components and actions. Built for marketing sites, headless commerce, and full-stack web apps, small or large. Whether Waku fits is about the architecture you want, not the size of your project: Waku keeps its framework surface minimal and composes with ecosystem libraries, while heavier frameworks own more of those concerns for you. ## Getting started Start a new Waku project with the `create` command for your preferred package manager. It will scaffold a new project with our default [Waku starter](https://github.com/wakujs/waku-examples/tree/main/fs-router/basic). ```sh npm create waku@latest ``` #### Commands - `waku dev` to start the local development server - `waku build` to generate a production build - `waku start` to serve the production build locally **Node.js version requirement:** `^26.0.0` or `^24.0.0` or `^22.15.0` For a guided path, start with the [Quick Start](https://waku.gg/guides/quick-start) guide and continue with the Learn series on [waku.gg/guides](https://waku.gg/guides), which builds a small app step by step. ## Rendering While there's a bit of a learning curve to modern React rendering, it introduces powerful new patterns of full-stack composability that are only possible with the advent of [server components](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). So please don't be intimidated by the `'use client'` directive! Once you get the hang of it, you'll appreciate how awesome it is to flexibly move server-client boundaries with a single line of code as your full-stack React codebase evolves over time. It's way simpler than maintaining separate codebases for your backend and frontend. And please don't fret about client components! Even if you only lightly optimize towards server components, your client bundle size will be smaller than that of a fully client-rendered React app. > Future versions of Waku may provide additional opt-in APIs to abstract some of the complexity away for an improved developer experience. #### Server components Server components can be made async and can securely perform server-side logic and data fetching. Feel free to access the local file-system and import heavy dependencies since they aren't included in the client bundle. They have no state, interactivity, or access to browser APIs since they run _exclusively_ on the server. ```tsx // server component import db from 'some-db'; import { Gallery } from '../components/gallery'; export const Store = async () => { const products = await db.query('SELECT * FROM products'); return ; }; ``` #### Client components A `'use client'` directive placed at the top of a file will create a server-client boundary when imported into a server component. All components imported below the boundary will be hydrated to run in the browser as well. They can use all traditional React features such as state, effects, and event handlers. ```tsx // client component 'use client'; import { useState } from 'react'; export const Counter = () => { const [count, setCount] = useState(0); return ( <> setCount((c) => c + 1)}>Increment </> ); }; ``` #### Shared components Simple React components that [meet all of the rules](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md#sharing-code-between-server-and-client) of both server and client components can be imported into either server or client components without affecting the server-client boundary. ```tsx // shared component export const Headline = ({ children }) => { return

{children}

; }; ``` #### Weaving patterns Server components can import client components and doing so will create a server-client boundary. Client components cannot import server components, but they can accept server components as props such as `children`. For example, you may want to add global context providers this way. ```tsx // ./src/pages/_layout.tsx import { Providers } from '../components/providers'; export default async function RootLayout({ children }) { return ( {children} ); } export const getConfig = async () => { return { render: 'static', } as const; }; ``` ```tsx // ./src/components/providers.tsx 'use client'; import { Provider } from 'jotai'; export const Providers = ({ children }) => { return {children}; }; ``` #### Server-side rendering Waku provides static prerendering (SSG) and server-side rendering (SSR) options for both layouts and pages including all of their server _and_ client components. Note that SSR is a distinct concept from RSC. #### tl;dr: Each layout and page in Waku is composed of a React component hierarchy. It begins with a server component at the top of the tree. Then at points down the hierarchy, you'll eventually import a component that needs client component APIs. Mark this file with a `'use client'` directive at the top. When imported into a server component, it will create a server-client boundary. Below this point, all imported components are hydrated and will run in the browser as well. Server components can be rendered below this boundary, but only via composition (e.g., `children` props). Together they form [a new "React server" layer](https://github.com/reactwg/server-components/discussions/4) that runs _before_ the traditional "React client" layer with which you're already familiar. Client components are still server-side rendered as SSR is separate from RSC. Please see the [linked diagrams](https://github.com/reactwg/server-components/discussions/4) for a helpful visual. #### Further reading To learn more about the modern React architecture, we recommend [Making Sense of React Server Components](https://www.joshwcomeau.com/react/server-components/) and [The Two Reacts](https://overreacted.io/the-two-reacts/). ## Routing Waku provides a minimal file-based "pages router" experience built for the server components era. Its underlying [low-level API](https://github.com/wakujs/waku/blob/main/docs/create-pages.mdx) is also available for those that prefer programmatic routing. This documentation covers file-based routing since many React developers prefer it, but please feel free to try both and see which you like more! ### Overview The directory for file-based routing in Waku projects is `./src/pages`. Layouts and pages can be created by making a new file with two exports: a default function for the React component and a named `getConfig` function that returns a configuration object to specify the render method and other options. Waku currently supports two rendering options: - `'static'` for static prerendering (SSG) - `'dynamic'` for server-side rendering (SSR) Layouts, pages, and slices are all `static` by default, while api handlers default to `dynamic`. For example, you can statically prerender a global header and footer in the root layout at build time, but dynamically render the rest of a home page at request time for personalized user experiences. ```tsx // ./src/pages/_layout.tsx import '../styles.css'; import { Providers } from '../components/providers'; import { Header } from '../components/header'; import { Footer } from '../components/footer'; // Create root layout export default async function RootLayout({ children }) { return ( {children} ); } export const getConfig = async () => { return { render: 'static', } as const; }; ``` ```tsx // ./src/pages/index.tsx // Create home page export default async function HomePage() { const data = await getData(); return ( <>

{data.title}

</> ); } const getData = async () => { /* ... */ }; export const getConfig = async () => { return { render: 'dynamic', } as const; }; ``` ### Pages Pages render a single route, segment route, or catch-all route based on the file system path (conventions below). All page components automatically receive two props related to the rendered route: `path` (string) and `query` (string). #### Single routes Pages can be rendered as a single route (e.g., `about.tsx` or `blog/index.tsx`). ```tsx // ./src/pages/about.tsx // Create about page export default async function AboutPage() { return <>{/* ...*/}</>; } export const getConfig = async () => { return { render: 'static', } as const; }; ``` ```tsx // ./src/pages/blog/index.tsx // Create blog index page export default async function BlogIndexPage() { return <>{/* ...*/}</>; } export const getConfig = async () => { return { render: 'static', } as const; }; ``` #### Segment routes Segment routes (e.g., `[slug].tsx` or `[slug]/index.tsx`) are marked with brackets. The rendered React component automatically receives a prop named by the segment (e.g., `slug`) with the value of the rendered segment (e.g., `'introducing-waku'`). If statically prerendering a segment route at build time, a `staticPaths` array must also be provided. ```tsx // ./src/pages/blog/[slug].tsx import type { PageProps } from 'waku/router'; // Create blog article pages export default async function BlogArticlePage({ slug, }: PageProps<'/blog/[slug]'>) { const data = await getData(slug); return <>{/* ...*/}</>; } const getData = async (slug) => { /* ... */ }; export const getConfig = async () => { return { render: 'static', staticPaths: ['introducing-waku', 'introducing-pages-router'], } as const; }; ``` ```tsx // ./src/pages/shop/[category].tsx import type { PageProps } from 'waku/router'; // Create product category pages export default async function ProductCategoryPage({ category, }: PageProps<'/shop/[category]'>) { const data = await getData(category); return <>{/* ...*/}</>; } const getData = async (category) => { /* ... */ }; export const getConfig = async () => { return { render: 'dynamic', } as const; }; ``` Static paths (or other config values) can also be generated programmatically. ```tsx // ./src/pages/blog/[slug].tsx import type { PageProps } from 'waku/router'; // Create blog article pages export default async function BlogArticlePage({ slug, }: PageProps<'/blog/[slug]'>) { const data = await getData(slug); return <>{/* ...*/}</>; } const getData = async (slug) => { /* ... */ }; export const getConfig = async () => { const staticPaths = await getStaticPaths(); return { render: 'static', staticPaths, } as const; }; const getStaticPaths = async () => { /* ... */ }; ``` #### Nested segment routes Routes can contain multiple segments (e.g., `/shop/[category]/[product]`) by creating folders with brackets as well. ```tsx // ./src/pages/shop/[category]/[product].tsx import type { PageProps } from 'waku/router'; // Create product category pages export default async function ProductDetailPage({ category, product, }: PageProps<'/shop/[category]/[product]'>) { return <>{/* ...*/}</>; } export const getConfig = async () => { return { render: 'dynamic', } as const; }; ``` For static prerendering of nested segment routes, the `staticPaths` array is instead composed of ordered arrays. ```tsx // ./src/pages/shop/[category]/[product].tsx import type { PageProps } from 'waku/router'; // Create product detail pages export default async function ProductDetailPage({ category, product, }: PageProps<'/shop/[category]/[product]'>) { return <>{/* ...*/}</>; } export const getConfig = async () => { return { render: 'static', staticPaths: [ ['same-category', 'some-produ

GitHub Issues· 0 开放

在 GitHub 查看全部

暂无开放 Issues,或尚未同步最近议题。

核心特点

  • •waku dev to start the local development server
  • •waku build to generate a production build
  • •waku start to serve the production build locally
  • •'static' for static prerendering (SSG)
  • •'dynamic' for server-side rendering (SSR)

> 标签

TypeScript

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言