Waku Adapter
Minimal React Server Components framework by the creator of Zustand and Jotai. Verified: 'use server'/'use client' boundaries work correctly with RSC streaming.
Waku 0.21 · RSC · Minimal
React Server Components
True RSC support with streaming — server components fetch data without client-side waterfalls.
'use server' / 'use client'
Explicit boundary markers for server/client code splitting — verified working end-to-end.
Minimal footprint
Waku focuses on RSC fundamentals without meta-framework complexity. Great for learning RSC deeply.
Streaming SSR
Components stream to the client as they resolve. Users see content immediately, not a loading spinner.
TypeScript native
Full TypeScript support with typed server actions and RSC props.
Server actions
Form-based server mutations using the 'use server' directive — no API routes needed.
Setup
bash
npm create lunx-dev@latest my-waku-app -- --framework waku --ts cd my-waku-app && npm install && npm run dev
Server and client components
typescriptsrc/pages/index.tsx
// Server component — no 'use client' = runs on server import { db } from '../lib/db' import { LikeButton } from '../components/LikeButton' // client component async function PostList() { // Direct async data fetching — no useEffect, no loading states const posts = await db.post.findMany({ take: 10 }) return ( <ul> {posts.map(post => ( <li key={post.id}> <h2>{post.title}</h2> {/* Client component nested inside server component */} <LikeButton postId={post.id} initialLikes={post.likes} /> </li> ))} </ul> ) } export default function HomePage() { return ( <main> <h1>Latest Posts</h1> <PostList /> </main> ) }
typescriptsrc/components/LikeButton.tsx
'use client' // This component runs in the browser import { useState } from 'react' export function LikeButton({ postId, initialLikes }: { postId: string; initialLikes: number }) { const [likes, setLikes] = useState(initialLikes) const [liked, setLiked] = useState(false) async function handleLike() { if (liked) return setLikes(l => l + 1) setLiked(true) await fetch(`/api/posts/${postId}/like`, { method: 'POST' }) } return ( <button onClick={handleLike} disabled={liked}> ❤️ {likes} {liked ? '(liked!)' : 'Like'} </button> ) }