Megan Lee
Posted on April 10, 2024
Written by Peter Ekene Eze✏️
Waku is a new lightweight React framework built primarily on top of React Server Components (RSCs). It offers a great developer experience for working with RSCs. Keep in mind that Waku is designed for small projects and only ready for use in development; it’s not yet recommended for enterprises or very complex web applications.
In this article, we’ll compare Waku with Next.js to understand the pros and cons of each React framework. Before we dive into the Waku vs. Next.js comparison, let's first understand their common denominator: React Server Components.
What are React Server Components?
RSCs are a new feature introduced in React 18. They allow you to render UI components directly on the server. This is different from traditional React components that render on the client side after the initial page load.
Essentially, RSCs are React components with the ability to run on the server. They’re written in the same syntax as regular React components, but they have specific limitations and functionalities due to their server-side execution.
Additionally, RSCs offer other benefits, like:
- Improved initial load performance: RSCs render content on the server, so the client has less work to do and can deliver a faster experience to users
- Improved search engine optimization benefits: Since RSCs are rendered on the server, search engines can directly index the content which can in turn improve your search engine rankings
- Easier server-side data fetching: You can directly access and fetch data from databases or APIs on the server within your components. This resolves a lot of React's current data-fetching complexities and makes it easier to think about data fetching and management
Despite these many benefits, React Server Components also come with some limitations:
- Can’t access the DOM or use features like
useEffect
anduseState
as they run on the server and don’t have access to the client environment APIs - Currently an experimental feature in React, so their API and functionalities might change in future releases
- Introduce a steep learning curve
Now that we understand RSCs, let’s look at how the Next.js and Waku frameworks are leveraging them to offer their capabilities to developers.
RSCs in Next.js
Next.js is a robust framework for building user interfaces. From v13 and onwards, Next.js uses React Server Components by default — they require no extra configuration to use.
Here's an example of a React Server Component in Next.js:
import db from 'some-db';
async function Legos() {
const URL = db.connect('some_value');
const data = await db.query(URL, 'SELECT * FROM legos');
return (
<>
<h3>My Legos</h3>
{data.map((lego) => (
<div key={lego.id}>
<h2>{lego.title}</h2>
<img src={lego.image} />
</div>
))}
</>
);
}
In this example, we can perform operations that we ordinarily wouldn't be able to do in regular React components. For instance, we can:
- Fetch data directly from the database without worrying about exposing credentials to the client
- Use async functional components.
Additionally, Next.js offers three different rendering modes for RSCs: static, dynamic, and streaming. This is one of the biggest benefits of RSCs in Next.js. Let’s look at these rendering patterns in a bit more detail:
- Static: This is the default rendering pattern for RSCs in Next.js. All the routes in your application are rendered at build time, similar to static site generation (SSG)
- Dynamic: This is the pattern that allows you to generate routes at request time in response to user interactions
- Streaming: This pattern maintains an open channel to continuously render the UI from the server to the client
The Next.js framework offers many features other than support for RSCs. You can check out our guide to the Next.js App Router or our archive of Next.js tutorials for more information.
RSCs in Waku
This heading can be misleading, as Waku is entirely built on RSCs to offer a tailored experience for users who want to go all-in on the feature. As a result, Waku is great when you want to work with RSCs, but doesn’t really offer many other features. We’ll go through a few noteworthy items below.
Waku supports RCSs natively and doesn’t require any additional configurations. It does introduce a small learning curve due to the different boilerplate structure that it ships.
Waku implements a similar rendering pattern to Next.js. For separation of concerns, it encourages server-client boundaries with the use client
and use server
directives. However, you'll likely never use the use server
directive, as every component is a server component by default until marked with the use client
directive.
To better understand Waku's approach to rendering RSCs, imagine your app structure like a tree where the top-level component is a server component. As you travel further down the tree, you might encounter components that need access to browser-specific features that are unavailable on the server.
So what do you do? That's where use client
comes in. By marking a component with this directive, you're essentially saying, "This component and its children require the client environment."
What happens below this boundary? Let’s see:
- Client-rendered components: All components imported below the
use client
directive become client-side components. They hydrate and run in the browser — in other words, they will have access to the DOM and other browser APIs - Server components within the boundary: You can still nest server components within the client-rendered region, but only as children props. Doing that will create a "React server" layer that executes before the traditional client-side rendering
Here's an example of a server component in Waku:
// server component
import db from 'some-db';
import { ProductGallery } from '../components/gallery.js';
export const ProductsPage = async () => {
const products = await db.query('SELECT * FROM products');
return <ProductGallery products={products} />;
};
In this example, we import a <ProductGallery />
component and fetch products from the database. Using the ProductGallery
component, we display all the products fetched by passing them to the component as props.
Additional Waku features
In addition to server components and client components, Waku also supports shared components and weaving patterns. Shared components are React components that don’t violate any of the rules of either server or client components. As a result, they can be used in both server and client components without any problems. For example:
// a shared component
export const Catalogue = ({ children }) => {
return <h3>{children}</h3>;
};
Weaving patterns, as the name suggests, allow you to weave both server and client components together in an interesting way. Server components can import and use client components, but client components cannot directly import server components. They can, however, accept server components as props.
Limitations of Waku
While Waku aims to make using RSCs more fun, it’s still a relatively new feature. As such, there are some limitations that you should keep in mind:
- Waku is in rapid development and some features are currently missing.
- It’s not recommended for enterprise applications ye
- It introduces a steep learning curve if you're coming from Next.js
- It isn’t production-ready
- There are not enough resources and educational materials available yet
However, Waku has a budding community that’s likely to grow stronger and more supportive as more developers explore this framework and discover its advantages when working with RSCs.
When to use Waku vs. Next.js
Ultimately, the question we’re trying to answer is, when should you use Waku and when should you use Next.js? I would consider Waku if:
- I'm building an application that is heavily dependent on RSCs and want a minimalist framework focused on that experience
- I'm experimenting with a new way to build React projects that promises a great developer experience
However, I would choose Next.js if:
- I need a full-fledged framework with features beyond RSCs
- I want a more established framework with a larger community and easier learning curve
- I want to build anything else outside the confines of RSCs
In my opinion, there's no clear advantage or compelling reason why I would use Waku instead of Next.js beyond development. Everything that Waku currently offers, Next.js also offers in addition to other amazing features, production readiness, a huge collaborative community, and a host of learning resources.
LogRocket: Full visibility into production Next.js apps
Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your Next.js apps — start monitoring for free.
Posted on April 10, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.