Introduction
Waku is a React framework that supports React Server Components (RSCs), a new feature that will be available in a future version of React. RSCs allow developers to render UI components on the server, improving performance and enabling server-side features. To use RSCs, a framework is necessary for bundling, optionally server, router and so on.
Waku takes a minimalistic approach, providing a minimal API that allows for multiple feature implementations and encourages growth in the ecosystem. For example, the minimal API is not tied to a specific router. This flexibility makes it easier to build new features.
Waku uses Vite internally, and while it is still a work in progress, it will eventually support all of Vite's features. It can even work as a replacement for Vite + React client components. While using RSCs is optional, it is highly recommended for improved user and developer experiences.
Why develop a React framework?
We believe that React Server Components (RSCs) are the future of React. The challenge is that we can't utilize RSCs with the React library alone. Instead, they require a React framework for bundling, at the very least.
Currently, only a few React frameworks support RSCs, and they often come with more features than RSCs. It would be nice to have a minimal framework that implements RSCs, which should help learning how RSCs work.
Learning is the start, but it's not what we aim at. Our assumption is that RSC best practices are still to explore. The minimal implementation should clarify the fundamentals of RSCs and enable the creation of additional features. Our goal is to establish an ecosystem that covers a broader range of use cases.
How to create a new project
To start a new Waku project, you can use any of the following commands, depending on your preferred package manager:
These commands will create an example app that you can use as a starting point for your project.
Minimum requirement: Node.js 18.16.0
Practices
Minimal
Server API
To use React Server Components in Waku, you need to create an entries.ts file in the project root directory with a renderEntries function that returns a server component module. Here's an example:
The id parameter is the ID of the React Server Component that you want to load on the server. You specify the RSC ID from the client.
Client API
To render a React Server Component on the client, you can use the Root and Slot components from waku/client with the RSC ID to create a wrapper component. Here's an example:
The initialInput prop can be passed to the Root Component, overriding the default input which is "". You can also re-render a React Server Component with new input. Here's an example just to illustrate the idea:
Additional Server API
In addition to the renderEntries function, you can also optionally specify getBuildConfig function in entries.ts. Here's an example:
The getBuildConfig function is used for build-time optimization. It renders React Server Components during the build process to produce the output that will be sent to the client. Note that rendering here means to produce RSC payload not HTML content.
How to try it
If you create a project with something like npm create waku@latest, it will create the minimal example app.
Router
Waku provides a router built on top of the minimal API, and it serves as a reference implementation.
Client API
To use the router, it is required to use the Router component instead of using Root and Slot directly. The following code demonstrates how to use the Router component as the root component:
The Router component internally uses Root and Slot and handles nested routes.
Server API
In entries.ts, we use defineRouter to export getEntry and getBuildConfig at once. Here's a simple example code without builder:
The implementation of the defineRouter is config-based. However, it isn't too difficult to make a file-based router. Here's a file-based example code with builder:
Due to the limitation of bundler, we cannot automatically allow infinite depth of routes.
How to try it
You can try an example app in the repository by cloning it and running the following commands:
Alternatively, you could create a project with something like npm create waku@latest and copy files from the example folder in the repository.
Deploy
Vercel
Then change the setting as follows (needs redeploy for the first time):