v0.18
December 12, 2023

Introducing Waku

Learn about the minimal React framework and how it enables RSC features.

by Daishi Kato
author of Zustand and Jotai

React, as a pure client UI library, has traditionally relied on frameworks like Next.js, Gatsby, and Remix to implement their own proprietary server-side functionalities. This pattern is evolving with the introduction of React Server Components (RSC) to the core library.

RSC still relies on a framework (or at least a bundler) for implementation. However as frameworks introduce RSC on top of their existing static site generation (SSG) and server-side rendering (SSR) capabilities, learning and experimenting how to develop applications or libraries solely with RSC features are somewhat complicated.

Waku is introduced as a minimal React framework that allows us to explore the core RSC capabilities and discover RSC best practices independent of traditional SSG/SSR strategies, which are optional opt-in functionalities.

This website is developed with Waku. The GitHub repository also includes various examples where you can learn how to use Waku and RSC features.

Waku API

The current version of Waku is based on Vite and leans on the Vite API and its ecosystem as much as possible. Waku has a server entry API with a file named entries.tsx placed at the root of the src folder:

import { defineEntries } from 'waku/server';

export default defineEntries(
  // renderEntries
  async (input) => {
    return {
      App: <h1>Hello {input}!</h1>,
    };
  },
);

The input argument is passed from the client and the function in entries.tsx is responsible for returning an object of JSX elements. In this case, it returns one h1 element with the App key.

The client code can use the server like this:

import { createRoot } from 'react-dom/client';
import { Root, Slot } from 'waku/client';

const rootElement = (
  <Root initialInput="Waku">
    <Slot id="App" />
  </Root>
);

createRoot(document.getElementById('root')).render(rootElement);

The client will send a request initially to the server with the input argument specified in the Root component. It will get the response from the server and can render it with the Slot component.

The API is designed to be simple and extensible. We implement a reference router implementation called waku/router on top of this API for example.

Deploying Waku

We’re thankful that Vercel has helped sponsor Waku on GitHub. We’ve made it possible to deploy Waku to Vercel.

Vercel supports the deployment of any frontend framework. We use their Build Output API to produce output from Waku which can be deployed to Vercel.

Specifically, we use two features of the API to power the Waku’s RSC capabilities:

  • Overrides Configuration: Allows customization of the “content-type” header, which is required for the client to properly handle RSC payloads.

  • Vercel Functions: Allows defining a Waku server that receives an input from the client and returns an RSC payload.

This website is an example of Waku deployed on Vercel. If there are other providers you’d like to see us support, please let us know.