Waku: The Minimalist React Framework with Server Components
waku.gg
waku.gg
Vercel’s opinions about routing and caching are two areas ripe for different perspectives. Next.js 13’s approach to routing is working fine for me, I enjoy a simple file-based router, but I know there are many people who do not like it. I anticipate it becoming hard to navigate as complexity and number of routes increases. The caching layer is highly opinionated and not for everyone. Both of these areas strike me as decisions influenced heavily by Vercel’s needs: file-based routing seems to make it easier to create serverless functions on their platform and aggressive caching is crucial when your customers pay by the request! If you don’t like their decisions on these things but React Server Components resonate with you, you’re out of luck until a strong alternative emerges.
So to the Waku maintainers, please keep going! I hope we read about this and many other frameworks soon.
Yes, SSR is a thing that is useful for building websites.
It is not useful, at all for building apps. Apps (as in, mobile apps) cannot be rendered on the sever. You need an api.
Unless you plan not to have an app, why would you choose to build your website in a way that is inconsistent with your design patterns, api design, etc. for you app.
Fundamentally, there is a parity between a javascript client to an api and a mobile client to an api.
The api can be implemented in anything.
You consume the api in an application. The application runs on the client device.
SSR is an optimisation for the web side of this, that forces you to use a node/js implementation for at least part of your backend, and mixes (eg. In blazor) where the application logic lives.
There’s no question the next.js RSC will do exactly the same thing; a blending of logic that means you don’t need an api, you just have a site.
…but you do need an api. Because unless you’re crazy, you need an app.
I don’t care about ideals and what ifs; that’s the blunt reality for most companies.
It’s weird. I bet that this is going to be a fad, and before you know it, people will use it because it’s “recommended” and then it’ll be a lot of complaints once they realise it’s actually quite problematic.
But sadly I think that era has come to an end, with every content company scrambling to lock data away to levy a fee for LLM training.
If anything, the need for everything to have an app or be a SPA is a fad. The complexity felt by every tiny team and product who thinks they must have multiple languages and deployment pipelines and microservices just because $BIGTECH does it is tragic. I’ve been a professional React developer for years, I love React and I have primarily built complex SPAs that truly required this technology, but I’ve also seen so many companies and people pouring energy into APIs and SPAs and apps that just should have been nice web sites sprinkled with JavaScript.
RSC is right at home with the countless server-rendered frameworks that were born before the “API ALL THE THINGS!” era. I’m building a product right now and it feels like being back in Rails, except I have TypeScript and I can drop into a client component at any time. And I can build an API endpoint when I need to for views that absolutely must have that SPA feel, since sometimes you do need that. Or ask anyone working with Phoenix LiveView, or modern Rails with Hotwire, or folks building in Django with htmx. The orthodoxy of “you must have an app” can’t be put to bed fast enough.
That's ridiculous. Browsers exist for a reason.
I'd rather see them do 1 method very well than 2 methods haphazardly
Or gate-kept app stores?
But even then, it ignores the technical hurdles an individual or organization must leap to build an app. Languages and ecosystems to learn, full of idiosyncrasies and best practices. Complexities of deployment pipelines, seeking incompatibilities between devices. I’ve worked with Android before and lemme tell you, I’ll move to a different industry before I do that again. (Kotlin is wonderful, at least!)
Compared to web, where you pick the browsers you want to support and it works. Where there is constant warfare between vendors to improve performance and get closer to the native experience. Where you have a massive pool of talent and a low barrier to entry. How is this even close?
The pendulum is swinging back from building everything as an SPA to a mix of server-rendered and client side content. It will probably overcorrect as things tend to do in software but the trend makes sense.
Debug ability. It’s so helpful being able to isolate the network layer and treat each layer independently.
State ownership. It’s nice to know that this is client side state, or this server side state. RSC obscures this.
Honestly I feel like the hype is mainly so people can avoid http requests.
RSC = React Server Component.
SSR in the React world is ultimately only used on initial page load, until the front-end client is fully hydrated.
RSCs are rendered on server side, useful for components that rely on backend data. This also reduces front-end bundle sizes, as any rendering dependencies for RSCs are kept on the backend.
You can have an API that handles all the important stuff (authn, authz, database access, 3P services...).
Your mobile/desktop/CLI/smart toaster apps can speak directly to that.
For the web, you can additionally have a web server that just serves HTML/CSS/JS, pre-rendered or not. This server can act as just another client "app", i.e, access the API on behalf of users. No special treatment, no business logic, just a dumb HTML shooter. And definitely no secret tokens.
https://nextjs.org/docs/app/building-your-application/data-f...
Spoiler: you don’t get an api.
https://nextjs.org/docs/app/building-your-application/routin...
https://nextjs.org/docs/app/building-your-application/deploy...
Pretty sure that's the whole point of htmx.
But this is what I love about Remix. You write your server and client code in the same place, but the server code is just an api, so can be reused directly.
I really don't understand the claim you're making when nothing about uses Next prohibits you from having an API. It is exactly what you say, an optimization/use case for web clients. But nothing about this prohibits other clients from doing their own thing consuming the exact same api's if you choose to do so.
Yea, technically you could, but why choose something far more complex that actually actively makes your app like experience worse?
Apps want to handle data local-first, offline-first, with optimistic mutations, cached data between screens, instant animations with interactions between screens, etc. The ideal data model for this is something like firebase, parse, graphql, tinybase, etc.
So now some bozo on your team bought into the hype and blindly wants to shove RSC into it and you’ve completely ruined the elegance of your stack. Instead of having a single codebase with a single abstraction for data fetching that’s clearly better than server-first, you now have two abstractions, and the server based one ruins all the things that make apps better than sites.
It also doesn’t make anything faster for web. You can avoid shipping some JS without RSC, the React team just decided for some reason to couple avoiding sending parts of the tree with a whole new data fetching model, a complete self-own and big mistake. It’s no wonder Vercel the server selling company loves them.
I'm honestly not even arguing for the hype since I don't use Next.js myself for any production projects at this time, I was simply pointing out that its not as if choosing to use it automatically means you can't use an API which is what the grandparent makes it seem like with their rant about still needing an API.
There are some teams that truly do want a server rendered app that Next.js provides as well as other features. They can use it for that if they so choose.
I'm honestly not even arguing RSC's are better or not because I know there are tradeoffs on both ends and we don't use them ourselves at where I work. Like I said, I was just poiting out it isn't a simple one or the other.
There are plenty of teams out there that use a backend for frontend architecture that basically is a data transformation layer for their API to clients. For your web stack that could be next.js.
over
database -> server side program -> HTML -> network -> browser renderer
Consider a product or article catalogue with search/filtering/ordering/pagination. This is something that can make sense to do in a SPA while you want it to degrade gracefully and work for clients without JS (including SEO).
Or for that matter, a Discourse/Reddit-like discussion board?
yes and no. sure, you can't do standard SSR like for websites. but i've seen a number of spins[1] on "Server-driven UI", meaning "server defines the app views as a big blob of JSON". usually, it's payload looking something like this:
[
{ "type": "Heading", "text": "Our cool products" },
{ "type": "List", "children": [
{ "type": "ProductCard", "id": 123, },
{ "type": "ProductCard", "id": 456, }
...
] }
]
the app "interprets" this and displays the corresponding components in the specified arrangement.the kicker is that, in a sense, RSC is just a less ad-hoc way to do this kind of thing! instead of `type` tags you get "client references", React handles the relevant parsing/serialization, and a lot of other good stuff on top. it's also quite seamless w.r.t writing components -- react does a very good job of abstracting away all the serialization business. and importantly, you can have an actual ecosystem of RSC packages around it, which a bespoke in-house method of doing this won't have.
now, RSC for react native has barely even been teased, but i'll bet good money that they have at least a prototype somewhere. and yeah, of course this would require your app to be in React Native. but that's the selling point -- IF all your stuff is in react, you get a bunch of power and some good DX.
---
[1] some examples off the top of my head:
- Facebook (not public, described by an employee): https://twitter.com/acdlite/status/1632217463772393473
- AirBnb: https://medium.com/airbnb-engineering/a-deep-dive-into-airbn...
- a Polish site called allegro.pl, though I can't find the conf talk about it right now...
> It is not useful, at all for building apps. Apps (as in, mobile apps) cannot be rendered on the sever. You need an api.
Yet.
React Server Components as a pattern and paradigm are not unique to web sites and the team has designed it with React Native in mind. We are just starting with web to flesh out the ideas and work with the ecosystem first.
RSCs (and SSR) are both technologies totally possible to use with RN, theoretically, we just haven’t built out the support yet. At the most basic, instead of rendering to HTML that the server sends down, it would render to commands that React Native’s native code would execute. Similar to the distinction between React DOM and React Native.
So we are excited about these technologies even though they are currently web only, and it’ll still be a while until we bring them to React Native.
Evan Bacon from Expo also experimented with RSC for React Native: https://x.com/baconbrix/status/1629909713910480898?s=46
Theres a popular Youtuber I watched a ton of, thinking I was getting an unbiased perspective on which web dev libraries to use. A few months in I realized everything on the channel was a subtle ad for a few companies.
i dont think there's anything wrong with taking ad money. but consumers should be made aware of biases.
Funny story I worked at Vercel. I made this library Tamagui which solves many hard problems in the style space.
One day t3 makes a YouTube video talking about styling solutions in React and he comes up with a Venn diagram explaining how no solutions solves the intersection. I was shocked! Tamagui did it exactly, it was the entire hard problem I set out to solve in creating it, and he left it out despite it having gained lots of attention right before that. I DMed him telling him he should check it out as I think it’s the holy grail he’s searching for. He replied dismissively saying something like “I don’t think so”.
Turns out Vercel are trying to kill solutions like Tamagui because they are having a hard time supporting so many style solutions between their two huge projects RSC and Turbopack, they are invested in Tailwind in multiple ways and are trying to consolidate styling around it for their own ecosystem benefit.
The rabbit hole goes deeper, but that’s what I’ll say.
oh ok ... i think you're thinking of t3.gg(aka theo).
> Turns out Vercel are trying to kill solutions like Tamagui because they are having a hard time supporting so many style solutions between their two huge projects RSC and Turbopack, and further the higher ups there are investors in Tailwind and are trying to consolidate styling around it for their own ecosystem benefit.
> The rabbit hole goes deeper, but that’s what I’ll say.
fascinating ... the whole react ecosystem has become a bit of a mess with open source contributors and investors (hoping for a return) mixed in.
No one is trying to kill Tamagui. Why would we want that?
> the higher ups there are investors in Tailwind
I don’t know any investors in Tailwind at Vercel. I’m certainly not one. I don’t think they’ve even taken outside investment. And it’d be against our ethical and fiduciary responsibilities to favor one solution over another on that basis.
> are trying to consolidate styling around it for their own ecosystem benefit
Tailwind is a great solution that’s earned the hearts and minds of the community, and that’s why we include it as an option in `create-next-app`.
It’s an option because you can bring your own styling solutions to Next if you’d like (like yours: https://tamagui.dev/docs/guides/next-js)
Maybe your perception is backwards? Large parts of the ecosystem are consolidating on Tailwind, and it’s our job to provide sensible defaults according to that.
Here are my options: - Take no sponsors, make no money, stop YouTube - Work my ass off to convince companies I trust that it’s worth supporting my channel - Grift away to whoever will pay the most
I think I found a good balance. Nobody has ever paid me to say something I don’t believe. I am confident in every recommendation I’ve ever made.
Wild if people start adding one more distributed stateful component to their apps because Search Engines forced them too.
Imagine a tree-based navigation component. It’ll render out a series of <a> tags, probably nested inside <ul>s and <li>s. Then the initial page state JS blob will contain the exact same information so that React can, somewhat uselessly, hydrate this tree-based navigation component. So page load is slower because it has to parse the state info then run a load of useless VDOM diffing against an already complete DOM.
This has long been an irritation of mine with React. It’s all so unnecessary but React makes it really difficult to have part of your page render statically. At least server components are an attempt to fix that.
Ah, yes thanks for that clarification and your comment.
Naively, you can implement a component that fetches some data (eg, post) and renders. Some descendants may also need to fetch data and render it. But now you’re blocking the descendants from rendering until the first fetch completes, so you have a waterfall load that takes unnecessarily long.
An alternative has always been to fetch everything at the route/top level. But now it starts to feel a bit strange that your route component needs to know about everything its descendants need.
RSCs promise to allow you implement the former pattern which gives better maintainability without the performance hit of a waterfall since the entire render-fetch-data-render back and forth is done on the backend near your data.
Can we please go back to separating clients from servers? Or, at the very least, treat your rendering server as just another untrusted client.
If the secret you're protecting is the source code itself, that's a valid concern, though React offers `server-only` for that purpose.
The boundary between server and client is pretty explicit and you can't pass props from one to the other accidentally, but admittedly, that won't stop an inexperienced developer refactoring the codebase at 3am to mess up, I guess.
It actually doesn’t matter how the server got a hold of the secret. If the value is in closure for some function the client has to execute (such as the component render function, or any client side effect etc), it will be sent to the client, silently. There are actually documented instances of this already happening.
And this is just one problem that was already discovered.
Are you referring to Server Actions? That's a feature separate to RSC, from what I can tell not supported by the framework in TFA, and the React maintainers are aware of what you mentioned. Server Actions are currently unreleased and undocumented (though NextJS already supports them in alpha), and you can expect their behaviour to change in significant ways.
For those who don't know, essentially the following Server Actions code:
const serverComponent = () => {
const secret = "my secret";
const myServerAction = () => {
"use server";
submitSecretToDB(secret);
}
return <button onClick={myServerAction} />
};
will roughly render to the following HTML: <button onClick="post('/myServerAction', {secret: 'my secret'})"></button>
which is unexpected because you probably wouldn't expect RSCs to leave behind this value used in code (as RSCs are executed on the server). But this is not the RSC's fault, it's the server action which is compiled down in an unintuitive way. React devs have discussed potential fixes (eg. encryption) on Twitter, I'm not sure whether they've been implemented yet or not.This still fits into the "kitchen sink" type frameworks I try to avoid. SSR has its place, but a huge portion of SPAs are better served by the flexibility of not requiring an app server. And tightly coupling those two just seems like a bad idea for a UI framework to me.
Keeping the frontend and backend decoupled. Being able to host the UI anywhere that can serve HTML/JS and not have to worry about maintaining/monitoring another server. Deployments are just a CDN cache invalidation, not cycling a container somewhere. SSR is great if you're worried about SEO, but it's generally total overkill for most apps.
I guess keeping frontend and backend decoupled is a matter of preference. I don't mind coupling my backend and frontend, and think it's a huge developer productivity gain to colocate components with data fetching.
If you already need a server to serve data, I actually think it just makes sense to use that server also to serve html.
vite-plugin-ssr (soon called Vike) and RakkasJS comparison: https://dev.to/redbar0n/comment/28nbg
Is it really "weird" or there's some connection or intents between these 2 events?
They also wrote an article a couple of years back and remix and server components