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.
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:
Despite these many benefits, React Server Components also come with some limitations:
useEffect
and useState
as they run on the server and don’t have access to the client environment APIsNow that we understand RSCs, let’s look at how the Next.js and Waku frameworks are leveraging them to offer their capabilities to developers.
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:
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:
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.
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:
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 APIsHere’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.
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.
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:
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.
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:
However, I would choose Next.js if:
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.
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.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
2 Replies to "How Waku compares to Next.js"
Could you elaborate on the concept of React Server Components (RSCs) and their significance in modern web development?
Thanks for reading our blog! You may find these resources helpful for learning more about RSCs:
https://blog.logrocket.com/react-server-components-comprehensive-guide/
https://blog.logrocket.com/react-server-components-next-js-13/