But it really is a magnificent piece of technology. Because they're called "Server Components" people think that "server" means run-time, but as a friend pointed out, 15 years ago people were running wordpress servers and caching pages ahead-of-time. As Dan mentions here: "server" doesn't imply it has to execute at run-time.
But there are also massive advantages to running a server at run-time that seem lost on people. I do think over time the concepts behind RSCs will filter out into most web frameworks because they are so powerful. It's the best functionality of the old-world SSR languages (PHP, rails) combined with the best functionality of the new-world client frameworks (React). You get to pick and choose when to lean on either, and they work together through composition.
I wish people were a bit more patient and spent a bit more time trying to understand these concepts before bashing them. Part of that is the fault of names, communication, and lack of documentation. But the underlying technology is rigid and strong. It's here to stay, even if it arrives in other forms.
1) No easy way to try outside a framework (now there is with Parcel RSC, but eventual first-class support in Vite will likely be the real tipping point).
2) Poor developer experience in the only official integration (Next.js). Both due to build performance problems (which Turbopack helps with but it still hasn’t fully shipped), due to bad error messages (massively improved recently), and due to confusing overly aggressive caching (being reworked to much more intuitive now but the rework won’t ship for some time yet).
Time will tell but I’m optimistic that as there are more places to try them, and the integrations are higher-quality, people will see their strong sides too.
I really appreciate when frameworks leverage standards and/or indicate the boundaries of the framework as much as possible.
https://www.youtube.com/watch?v=zqhE-CepH2g
Convinced me to start new project with React just because of the RSCs.
And one of my pet peeves is people seeing the former and dismissing it as "everything old is new again" without considering the gains we've made in the meantime with the latter.
I don't think that is true. React had one great feature that gives it its name: reactivity. People kept using it despite the bad abstractions added later like hooks, graphql and now RSC. The difference is that now react fatigue is way bigger than the hype, nobody loses a job by stating that RSC is terrible.
The enshittification of the web partly is shipping giant JS bundles for no reason. (Developer needs > Consumer)
Is it because each component is expected to abstract over async, relying on the promise state?
More concisely: it’s not always the case that prop drilling is possible within a component hierarchy. In a more involved application you store this object in context.
Is what you are describing compatible with this pattern? How does this inform the design of RSCs and as a developer, how can I expect this to affect me?
One way would be to put it into Client context near the top, then it will be available in Client context below. So if it’s just for the Client stuff, your existing approach works.
For data fetching, a more common approach is not to do any “passing down” at all. Instead, have components that need that data below read that data independently. Slap React.cache around the function that gets the data so that all calls are reused across a single request. Then the first call kicks it off and the other calls will wait for the same Promise under the hood. And you can kick off preloading somewhere up above in the tree if you want to eagerly begin.
That should cover most cases.
Dan's blog is rendered as static, works without javascript and still lets him write complex client-side components when he calls for it. And if one day he decides to add a page that renders content dynamically, he can do so in the same patterns and framework that he's already using.
The goal is developer-choice. No need to pick static or dynamic holistically, have access to both when you need them. No need to pick between hydrating the entire website vs. rendering exclusively on the server. No need to pick between writing client-side amenable code or server-only code.
How many platforms have a "marketing" website for / and a platform website for /dashboard? No need to split them, just use a framework that accommodates both seamlessly. It's more powerful, even though it does come with a learning curve.
React might sound like a weird choice to you but its composition model including server and static stuff is quite powerful. See here for a slightly contrived but representative example: https://overreacted.io/impossible-components/#a-sortable-lis...
With LLMs to help wrestle the boilerplate, I've found I can whip up a fast static site using advanced ergonomic abstractions that make the whole process a joy! In the past, wrestling the Node and NPM ecosystem was a a complete nightmare. Now it's, a dream — with the occasional storm cloud.
That's it. It's not a clever way to arrive at the conclusion that the server is useful, but they got there in the end.
Components (be it Astro, Svelte, React, etc.) have a lovely API for sharing code across web pages. I used Hugo before and hit the limits of shortcodes pretty quickly. I can't comment on Jekyll though.
Furthermore, if the need for some dynamically rendered pages or client-side interactivity comes up, it is very easy to integrate this later on. I can build static, server-rendered and client-rendered pages (and everything in between) with the same set of tools, which means less mental load when I develop.
All of this makes very little sense, but every couple years a guru will shout new commandments from his social media mountaintop and reshape the landscape. It's more of a religious ritual at this point, really.
On a more serious note, it's also because the market is saturated with developers who specialize on React, and this is what's easy and makes sense to reuse their knowledge and code (vs say, setting up a caching reverse proxy and dealing with invalidation).
```
RSC means React Server Components.
And yet, although this blog is built with RSC, it is statically served from a Cloudflare CDN using their free static hosting plan. It costs me exactly zero.
Zero.
How is this possible?
Aren’t these React Server Components?
```
Why is any of that confusing? The very first thing I think of when someone says "React Server Components" is, well, server side rendering of react components. What else could it possibly be? Is anyone who is an established React developer really confused by this?
Because that is what SSR mean. Not to be confused with SSG which is the case for your blog.
Plus, I think Astro wins over Next in terms of documentation and the general developer experience.
Next has the bad vibes, unfortunately because of all Vercel thing. At least for me. I believe if Next would position itself somewhere like Astro, people would be more open to learn and dig it. I don‘t exactly know if it‘s 100% true, but I feel like if I invest my time in Next, I will be locked-in by the Vercel world of things. And no one likes that.
RSC isn’t tied to Next, and Next isn’t tied to Vercel. I hear you about the vibes but thankfully that’s not my problem. I’m just trying to explain the model.
Or a more complicated app: https://exogen.github.io/t2-model-skinner/
Are all of Next.js’ features overkill for such sites? Sure, but the convenience such frameworks provide is worth it. And the reason to prefer it over something like Vite is simply routing, which Vite doesn’t cover out of the box, so as soon as I want to add a second page, I now have another problem to solve.
Next.js’ best feature is simply that you’re up and running with `npm i react react-dom next` and step two is just writing the pages.
this is the biggest effort I'm aware to run Next with a full-ish feature set outside of Vercel: https://opennext.js.org/. Supports AWS, Cloudflare, and Netlify. You can also run Next as a normal node webserver. I've only used the Cloudflare integration and it was a bit janky but worked (and seems to be entering 1.0 soon so may be less janky).
AFAIK this is completely unsupported by the Next team, but would love to be proven wrong!
> Even better, don't pre-render anything until the first time it's requested, then render, serve, and cache it.
This is essentially what Incremental Static Regeneration (ISR) does.
But, mostly you pre-render it, because else, the first user has to wait to long for the page. ISR is also re-rendering for the next user. The current user has the old version and the page is re-rendering in the background for the next user.
The JAMstack architecture is advantageous because it allows for the use of simple servers—essentially S3 buckets that can serve static files. This setup requires less security patching and reduces costs for server hardware. Additionally, the server essentially acts as your cache, allowing you to distribute it widely.
as for "why React", speaking just for myself it's really nice to just have one tool that can do everything (static HTML-only, static with JS, SPA, SSR) and not have to context switch or potentially even have to split my site into two projects just because I want to hop between one or the other approach. and React has the biggest mindshare and ecosystem.
It is telling that the blog of the fw creator ships 500kb of JS/CSS/HTML to display text on a screen.
> it's really nice to just have one tool that can do everything (static HTML-only, static with JS, SPA, SSR)
WebComponents (+lit-html)
That's a crap:content ratio of 256:1
Also I’m not a framework creator.
And you absolutely don't want one tool to do everything. HTML/CSS is native and understanding it is a requirement for React. It also doesn't require Node and a build step.
Really funny how some devs think they know the secrets of engineering simplicity and everyone else is a fool for not knowing what they know (HTML/CSS).
And I'm sure you do it as well as other delusional backend-only coders
It's not necessary and the ROI is poor IMO, especially for CSS. Better to just use React for everything and not worry about the implementation details; yes those details will sometimes help you debug, just like knowing machine code will occasionally help you debug your compiled code, but it's not something to put a lot of your learning budget into.
> It also doesn't require Node and a build step.
The point is assuming you already have node and a build step. You already know React. So just use it for everything. Everyone who thinks they can "just write HTML/CSS" ends up introducing Hugo or Gatsby or whatnot (or, worse, writing their own "simple" Makefiles and shell scripts) and gradually adding more and more features until it's just as complex as React. Just use React.
...what? What are you writing in React if not HTML tags and CSS classes? How can you even write anything in React without that? React doesn't do anything CSS specific either, so I don't understand how you'd even style anything if HTML and CSS were not a "necessity."
UIs made of React components. I try to avoid having to know or care about the underlying implementation details.
If a component doesn't have built-in styling support (i.e. configurable via React properties) then I'll use Tailwind so I can at least ignore all the selectors and cascading nonsense of CSS. (I remain hopeful that the world will eventually see that inline styling is the way to go; with Tailwind I meet them halfway)
And AI really can do a lot of work nowadays. I met a founder who built their entire mvp with v0.dev. 5 pages, multiple flows, modals with photo taking/uploading and working color picker. They only needed to add the api-calling logic.
Must be a case of the midwit meme, or https://cspages.ucalgary.ca/~robin/class/449/Evolution.htm . Intermediate programmers satisfy their ego by writing everything themselves; a real experienced professional knows that custom code or a complex technology stack is a liability, and delivers the functionality the business needs in the way that will impose the smallest maintenance burden.
> it's not accurate to say that HTML and CSS are not "necessary" unless you're doing what seems to be very basic work.
Disagree. You need to be able to lay things out, compose components, and hook up behaviour. But you don't need to use the lowest level languages to do that, any more than you need to write all your programs in machine code. You need to understand the DOM, but that doesn't mean you need to express it in HTML, and similarly for layout.
> Tailwind is still CSS, again, so without knowing what things like flex actually do, you can't use Tailwind either.
You need to understand layout and styling properties, sure. But you can skip the things that make CSS CSS - selectors, cascading, and the like - which the industry is ever so gradually starting to recognise for the failures they are.
> I'm beginning to suspect you may just use AI to build much of your code for you.
LOL. Is this projection, or just reaching for any possible way to smear me? The AI fanboys are happy to mix a dozen technologies in their project because the AI "understands" all of them equally well - mix React and CSS and HTMX and what have you, why not? I'm actually genuinely curious about your thought process here (if you had one), can you talk through what lead you to this bizarre idea?
This feels quite ignorant. I'm not sure, in some ways I understand it, for example, when running software on the JVM, I typically don't think about how it's implemented, so I share some of that ignorance.
At the same time, specializing to just knowing one technology (e.g. React) and not caring about up or down the stack can also be limiting - both for any career moves (Vue? Angular? working with how the resources are packaged and deployed?) as well as just debugging things in more detail (since one can feasibly imagine cases where you need to look at both the output HTML/CSS/JS to understand why certain things are happening, not just a React plugin in DevTools).
You don't have to learn things that are of no value right now, but you probably shouldn't go out of your way to not learn things. Staying curious is generally pretty nice!
JSX compiles to jsx(“div”, props, children) function calls so you need a runtime (which can be small) to render that into strings.
At which point, who cares if you’re using react to do it? It’s a good zero dep implementation of a jsx fn.
Alternatively, you can use Astro with React components, which will render them using React-DOM, but save them as static HTML by default (you can still choose some components to be hydrated, though).
Next.js does usually have the runtime part, but I imagine it’s not too hard to disable (or you can strip all JS from the output). Astro, like I mentioned, strips JS by default (from island components, not from .astro components, though you can usually use those without any client-side JS, too).
It is kinda roundabout way of generating HTML from JSX though.
I have interactive examples on some pages. I’m planning to have more of them and more complex ones. Very little of the infra for this is actually render-blocking — try disabling JS and see that my site loads just fine.
All data and interactive stuff is loaded after the text and doesn’t block the first paint.
If anything, running a webpage test shows that the CSS requests are blocking the first render a bit. Maybe I should inline them or something.
Yes, you don't need this, and you can directly call an API, but, thats bad for the user, because they have to wait for the API request (and UI update) and bad for you, because you have as many API request, you have as page visits.
So, server components bring value with the ttl / revalidate option of the page. A framework like next/vercel brings value if you want to maintain you page over the next 10 years with more then 1 developer.
I'm showing my age, but we used to do this using Wordpress ages ago. Like 15 years ago or more haha.
That came later, but yes we could (we did some wild stuff with v8js in PHP). And I'm convinced that anything in the blog requires either feature, though I get that more complex systems might.
Because you end up with two subsets of supported features in the same technology, even in the linked page: https://nextjs.org/docs/pages/guides/static-exports
Supported Features
The majority of core Next.js features needed to build a static site are supported, including:
Dynamic Routes when using getStaticPaths
Prefetching with next/link
Preloading JavaScript
Dynamic Imports
Any styling options (e.g. CSS Modules, styled-jsx)
Client-side data fetching
getStaticProps
getStaticPaths
Unsupported Features
Features that require a Node.js server, or dynamic logic that cannot be computed during the build process, are not supported:
Internationalized Routing
API Routes
Rewrites
Redirects
Headers
Middleware
Incremental Static Regeneration
Image Optimization with the default loader
Draft Mode
getStaticPaths with fallback: true
getStaticPaths with fallback: 'blocking'
getServerSideProps
To me, this feels about as awkward as React moving from class based components to function and hook based ones, dragging a lot of the large libraries alongside with it, meaning that if you tried using class based ones for a while you'd run into cases where some of your dependencies would only offer documentation for the functional approach.Mixing approaches that differ so much inevitably leads to awkwardness. I'd prefer a SPA library/framework without awkward sharp edges and a separate SSR solution, each specialized at what they do, neither trying to do everything. That way the toolchains remain simpler, there's fewer abstractions at play and fewer things to keep in mind. But if one tool to rule them all works for you, then great!
Dunno, the Next.js hybrid approach seems both trivial to understand the trade-offs of, but also optimal:
You get to use the same tooling, but if you don't use any of the dynamic stuff like the router (stuff you'd obviously need to use a server for), then you get to output static html files.
Or, you can start with an SSG site and then decide that you want server-side logic, and all you do is opt-in to some server-side logic.
This works well because instead of traditional SSGs like Jekyll, Next.js has the nice UX/DX of writing a dynamic server where it has a build step that crawls all your routes to generate static files (the right way to do SSG imo). So when you decide you want to run on a server, you just deploy it on the server instead of using the crawl step.
Framing this into a confusing subset vs superset distinction kinda obscures what's really going on. It's like writing an Express app but opting in to SSG by using a build tool that wget-crawls your local server.
The downside of Next.js is that client-side "rehydration" is inherently complex, not that it can enumerate your routes to generate static files. It's just that when you build a system that can render server html templates to strings and then rehydrate them in the browser, it's trivial to build the tool that saves those server templates into static html files.
And I think you're imagining that you could only do such a thing if you designed for it from the beginning, essentially bending over your abstraction to force that feature, when it's actually a trivial entailment of the system in the first place.
ktpsns•2mo ago