[HN Gopher] Static as a Server
       ___________________________________________________________________
        
       Static as a Server
        
       Author : danabramov
       Score  : 63 points
       Date   : 2025-05-08 17:49 UTC (5 hours ago)
        
 (HTM) web link (overreacted.io)
 (TXT) w3m dump (overreacted.io)
        
       | ktpsns wrote:
       | This got popular in JS toolkits a few years ago, at least. For
       | instance, Svelte(kit) also has a static output variant.
        
       | switz wrote:
       | It's unfortunate that there is so much misinformation about what
       | react server components really are, but it's not necessarily the
       | fault of either party. The name is confusing (names are hard),
       | the architecture is new (people don't want to learn it), and it
       | lends itself to conspiracy theories (that aren't true).
       | 
       | 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.
        
         | danabramov wrote:
         | I think it's fair to say that a lot of the negative reception
         | was also due to
         | 
         | 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.
        
           | mikesurowiec wrote:
           | Thanks for pointing out Parcel RSC. I just read through the
           | docs and they do a great job of explaining RSCs from a place
           | I can understand. In contrast to NextJS where it's unclear
           | where the framework stops
           | 
           | https://parceljs.org/recipes/rsc/
        
             | steve_adams_86 wrote:
             | "unclear where the framework stops" is a great way to
             | phrase that issue. It's something I've run into with NextJS
             | in a few contexts.
             | 
             | I really appreciate when frameworks leverage standards
             | and/or indicate the boundaries of the framework as much as
             | possible.
        
         | nicce wrote:
         | I think this was pretty good at explaining the impact:
         | 
         | https://www.youtube.com/watch?v=zqhE-CepH2g
         | 
         | Convinced me to start new project with React just because of
         | the RSCs.
        
           | danabramov wrote:
           | Thanks for reminding, that's a great talk!
        
         | Vinnl wrote:
         | > 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).
         | 
         | 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.
        
           | skydhash wrote:
           | I remember meteor.js!
        
         | owebmaster wrote:
         | > I do think over time the concepts behind RSCs will filter out
         | into most web frameworks because they are so powerful
         | 
         | 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.
        
       | atoko wrote:
       | I wonder if the omission of React Context in this example is
       | intentional. Do you think Context is compatible with suspense? In
       | the sense that posts is being passed to components as props three
       | times over.
       | 
       | Is it because each component is expected to abstract over async,
       | relying on the promise state?
        
         | danabramov wrote:
         | Not sure what you mean -- we're just reading some files from
         | the disk and passing that down. It doesn't need Suspense
         | because everything is static (so no loading indicators are
         | needed). If this was dynamic then I'd probably still not add a
         | loading indicator because you expect a blog index to "pop in"
         | with the rest of the page rather than behind a spinner.
        
           | atoko wrote:
           | Thanks!
           | 
           | 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?
        
             | danabramov wrote:
             | This depends on how you need to use this object.
             | 
             | 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.
        
       | revskill wrote:
       | If you put a cache around all GET API handler, you're faster than
       | static.
        
         | NewEntryHN wrote:
         | Most servers will natively use caching policies for serving
         | static content as well.
        
         | danabramov wrote:
         | Point taken, but I more or less consider this "static". The
         | distinction is artificial (of course there's always a server
         | behind the scenes), the question is just which server you're
         | programming _against_ in the abstraction stack of the majority
         | of your program. Hybrid approach often includes "incremental
         | regeneration", i.e. partial builds on-demand with caching. So
         | that fits very well there. But it's an implementation detail.
         | The programming model you're writing against can just use an
         | "invalidate" function without concerning itself with the outer
         | "actual server" layer.
        
       | raddan wrote:
       | I understand that somebody might want to generate static pages
       | from code that generates it dynamically, but I fail to appreciate
       | _why_. Are people using this for a handful of pages they want to
       | load quickly and whose contents rarely change, or are people
       | building entire static sites using things like React? If it's the
       | latter... uh... why? It's been awhile since I was a web
       | developer, so maybe my pain threshold is inappropriately low. I
       | think Jekyll is fine and use it pretty regularly.
        
         | switz wrote:
         | It's because inevitably there comes a time where you want some
         | pages (or even sub-pages) to be static, and other pages (or
         | parts) of your application to be dynamic. If the question is
         | "why" the inverse is "why not"?
         | 
         | 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.
        
           | danabramov wrote:
           | To give a concrete example, I'll probably add some dynamic
           | stuff at some point in the future, like commenting with
           | Bluesky or such. It's nice not to switch tools for that.
        
           | dakiol wrote:
           | I think the reason to split the marketing page from the
           | dashboard one is that you can deploy one without the other. I
           | would actually prefer to have all the marketing stuff in its
           | own repo away from any dashboard code.
        
         | danabramov wrote:
         | Nowadays it's common for things to not be _entirely_ static but
         | kind of a mix. Some interactive client stuff, some dynamic
         | server stuff. It's nice to stay within the same programming
         | model for these.
         | 
         | 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...
        
         | manofmanysmiles wrote:
         | Although I don't usually use react, for me, there is a certain
         | joy and also efficiency that comes from using some of the
         | abstractions that you got from the larger JavaScript/web
         | ecosystem while also having the ability render all that magic
         | to a folder with a couple of HTML, CSS and JavaScript files.
         | 
         | 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.
        
         | RadiozRadioz wrote:
         | Mainly because they all discovered that fully dynamic client-
         | side SPAs written in 100% JS are extremely slow, and wanted a
         | way to speed them up whilst keeping most of the developer
         | experience of an SPA.
         | 
         | 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.
        
         | dschuessler wrote:
         | As someone who uses Astro a lot for (mostly) static pages, the
         | two standout features of this approach that come to my mind are
         | code sharing and the ease of integrating SSR/CSR where needed.
         | 
         | 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.
        
         | floodle wrote:
         | Because it's an easy and widely used framework to write
         | JavaScript components that react to changes in state
        
         | ricardobeat wrote:
         | Because most mainstream frameworks are too bloated to handle
         | more than a few hundred rps on a normal server, and caching has
         | gone out of fashion (?), so it's the best way to save money.
         | 
         | 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).
        
           | danabramov wrote:
           | I'm actually quite excited for caching to make a comeback:
           | https://overreacted.io/functional-html/#caching
        
         | ahuth wrote:
         | Jekyll is fine. So is React. And Astro. Some folks like
         | different things than others.
        
       | throwaway314155 wrote:
       | I am having trouble understanding this article's premise:
       | 
       | ```
       | 
       | 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?
        
         | roywiggins wrote:
         | this post describes not really running RSC on the server, but
         | instead running it on the developer's laptop, taking the
         | resulting HTML, and pushing that to a server. the more common
         | use case of RSC is where it is actually being run server-side
         | as requests come in, perhaps behind a cache, not baking
         | everything down into a static bundle once
        
         | danabramov wrote:
         | If you think of "server side rendering", you might be assuming
         | that it requires runtime Node.js hosting (which is usually
         | paid). But that's not the case -- my blog is _statically_
         | generated during deployment. Like Jekyll. So the point of the
         | post is to show why it's not a contradiction. In modern tools,
         | "static" is often an _output mode_ of "server" frameworks
         | rather than a separate category of tools.
        
           | owebmaster wrote:
           | > If you think of "server side rendering", you might be
           | assuming that it requires runtime Node.js hosting (which is
           | usually paid)
           | 
           | Because that is what SSR mean. Not to be confused with SSG
           | which is the case for your blog.
        
             | danabramov wrote:
             | Sure. I'm just trying to answer the parent's question? I
             | wasn't the one to bring "SSR" into the conversation.
        
       | ricardobeat wrote:
       | Varnish and PHP say hello from the distant past of 2008.
        
       | rco8786 wrote:
       | One more reason to be confused about nextjs
        
         | danabramov wrote:
         | Are you confused about Astro? It follows the same model.
        
       | exogen wrote:
       | This is also how I build most of my static sites, usually
       | deployed to GitHub Pages. For example, here's the demo page for a
       | library I recently developed: https://exogen.github.io/turbo-
       | colormap/
       | 
       | 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.
        
       | _benton wrote:
       | I'm curious if Next has full support for Cloudflare or if this is
       | the only way to run Next w/RSC off of Vercel.
        
       ___________________________________________________________________
       (page generated 2025-05-08 23:00 UTC)