Waku: The Minimal React Framework
Waku is a minimal React framework designed for building performant web applications with a focus on React Server Components (RSC) and React 19 features. Currently in its v1.0.0-alpha.7 release, it is under active development with frequent alpha releases that may introduce breaking changes, particularly in adapters and internal APIs. Waku is optimized for marketing sites, blogs, headless commerce, and web apps where a lightweight footprint and full-stack React composability are key differentiators. Unlike heavier frameworks, it emphasizes a lean approach, prioritizing a fun developer experience with modern React paradigms. It supports all the latest React 19 features, including server components and actions, aiming for smaller client bundle sizes by leveraging server-side rendering extensively. It requires Node.js `^24.0.0`, `^22.12.0`, or `^20.19.0`.
Common errors
-
Error: The 'use client' directive must be at the top of the file.
cause The 'use client' or 'use server' directives define server-client boundaries and must be the very first statement in a file, before any imports or code.fixEnsure `'use client';` or `'use server';` is the absolute first line of code in the file, including comments or blank lines. -
ERR_REQUIRE_ESM: require() of ES Module X from Y not supported. Instead change the require of X to a dynamic import() which is available in all CommonJS modules.
cause Waku is distributed as an ES Module (ESM). This error occurs when attempting to `require()` Waku or a related package from a CommonJS context.fixMigrate your project to use ES Modules (e.g., set `"type": "module"` in `package.json` and use `import` statements), or use dynamic `import()` for specific modules that are exclusively ESM. -
Module not found: Error: Can't resolve 'react-server-dom-webpack' in '...'
cause The `react-server-dom-webpack` package is a required peer dependency for Waku's React Server Components functionality and is missing or not installed correctly.fixInstall the missing peer dependency: `npm install react-server-dom-webpack@~19.2.4` (adjust the version to match Waku's `peerDependencies`). -
Your current Node.js version is X. Waku requires Node.js ^24.0.0 || ^22.12.0 || ^20.19.0.
cause The project's Node.js environment does not meet the specified engine requirements for Waku.fixUpgrade or switch your Node.js version to one within the supported range (e.g., Node.js 20.x, 22.x, or 24.x) using `nvm` or similar tools.
Warnings
- gotcha Waku is currently in an alpha state (v1.0.0-alpha.7). While public APIs are stated as stable, internal implementation details, adapters, and behavioral aspects may still undergo changes, potentially breaking existing setups between minor alpha versions. It is recommended for non-production projects only.
- breaking The main entry point for Cloudflare Workers deployments changed from `./dist/server/serve-cloudflare.js` to `./src/wa`. This requires updating your `wrangler.jsonc` configuration.
- breaking The `renderHtml` option, likely used in `waku.config.ts` for custom HTML rendering, was renamed. This affects projects using custom HTML configurations.
- breaking The directory for file-based API routes changed from `./src/pages/api/` to `./src/pages/_api/`. The `_api/` segment is stripped from the URL path by default.
- gotcha Waku has strict Node.js engine requirements. Running with an unsupported Node.js version will prevent the application from starting or building correctly.
- gotcha Waku requires `react`, `react-dom`, and `react-server-dom-webpack` as peer dependencies at specific versions (e.g., `~19.2.4`). Mismatched or missing peer dependencies can lead to runtime errors, especially with React Server Components.
Install
-
npm install waku -
yarn add waku -
pnpm add waku
Imports
- defineConfig
const defineConfig = require('waku').defineConfig;import { defineConfig } from 'waku'; - Router
import { Router } from 'waku/router'; - Link
import { Link } from 'waku/router'; - startDevServer
require('waku').startDevServer;import { startDevServer } from 'waku';
Quickstart
import { defineConfig } from 'waku';
export default defineConfig({
rootDir: 'src',
ssr: true,
// Add custom Vite config if needed
// vite: () => ({
// plugins: [],
// }),
});
// src/app.tsx
import { Router, Link } from 'waku/router';
export const App = () => (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/counter">Counter</Link>
</nav>
{/* Router handles rendering content based on current path */}
</Router>
);
// src/pages/counter.tsx
'use client';
import { useState } from 'react';
export const Counter = () => {
const [count, setCount] = useState(0);
return (
<>
<h1>Client Counter</h1>
<div>Count: {count}</div>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
</>
);
};
// To run this example, create a new Waku project:
// npm create waku@latest my-app
// cd my-app
// npm install
// npm run dev