A proposal comes back with words like “static site,” “server-rendered,” or “islands architecture,” and none of them mean much until someone explains what you’re buying. This is the plain version, grounded in two things we’ve built: this site, and a client’s SaaS product.
Static: one file, every visitor
The simplest model is the one search engines and CDNs like best. The site is built once, ahead of time, into a folder of HTML files, and every visitor gets the same file for the same URL. Nothing runs on a server when someone loads the page, because there’s nothing left to compute. Astro describes its own default this way: pages are pre-rendered at build time into static pages unless you tell it otherwise.
What that buys you: hosting is cheap because you’re serving files, not running a program. Pages load fast because there’s no computation between the request and the response. Search engines and AI crawlers get a complete page with no JavaScript required to see it.
What it costs you: the page can’t know who’s looking at it. A logged-in dashboard, a shopping cart with your items in it, a page that changes based on a user’s role, none of that fits, because “static” means the file is identical for everyone until the next build.
This is the right fit for a brochure site, a marketing page, a blog, a documentation site, anything where the words on the page are the same regardless of who’s reading them.
Server-rendered: FurnitureAxis
The opposite model computes the page fresh on every request. FurnitureAxis, the multi-tenant SaaS we built for furniture retailers, runs this way. It’s built on Next.js 15 with React 19, Prisma, and PostgreSQL, and almost every screen sits behind a login and is scoped to one retailer’s data. A warehouse manager and a sales rep hitting the same URL need to see different numbers, so the server has to check who’s asking before it can answer.
Next.js’s docs describe this as Server Components rendering on the server into a payload, then the browser gets HTML for the first paint and JavaScript to make the interactive parts of the page respond to clicks and keystrokes after that. That second part, the JavaScript that ships to the browser, is the real cost difference from static. A static marketing page can skip shipping a UI framework entirely. An app with forms, tables that filter without a reload, and per-user state can’t.
What that buys you: personalization, live data, and mutations that happen through server code rather than a database call from the browser. What it costs you: an actual running server rather than a folder of files on a CDN, and more JavaScript in the browser to keep the page interactive after it loads.
Islands: dawloom.com
There’s a middle option that starts from static and adds interactivity only where it’s needed. This site runs on Astro 7 with Svelte 5, built as static output and served on Cloudflare Workers. Astro’s islands architecture renders the page to static HTML by default and only ships JavaScript for the specific components you mark as interactive. On this site that’s a single Svelte component, the mascot in the corner, and it loads after the rest of the page has already gone idle. Everything else, including the FAQ accordions, is plain HTML with no framework attached.
What that buys you: most of static’s speed and hosting simplicity, with room for the handful of interactive pieces a marketing site needs, like a form or a widget, without paying for a full app framework’s JavaScript on every page.
What it costs you: this only works cleanly when most of the page really is the same for every visitor. A site that’s mostly interactive, logged-in, and per-user starts to look like the server-rendered model with extra steps.
What the code looks like
The difference between static and server-rendered in Astro comes down to one export. A page is static unless you say otherwise:
---
export const prerender = false
---
<h1>This page now runs on every request.</h1>
That single line is the difference between a page a CDN can hand out from cache and a page that needs a server running behind it to compute an answer per visitor. It’s a small piece of code with a real infrastructure consequence: the moment a page needs prerender = false, you need somewhere for that code to run on every request, not just a place to host files.
The question that matters
None of these three is better in the abstract. The question worth asking, whether you’re reading a proposal or writing one, is whether the page needs to know who’s asking before it can respond. If every visitor sees the same content, static or islands covers it, and islands is the version to reach for once you need even a little interactivity. If the page holds a login, per-user data, or state that changes on click, you need something computing per request, which is what a server-rendered app is for.
A vendor who leads with the framework name before asking that question is optimizing for what they like building, not for what your product needs. Tell us what you’re building, and we’ll tell you honestly which of these three fits, including the one we’d rather not build if it’s not the right one. That’s how we work through web development projects, whether the answer turns out to be a static page, a full server-rendered app, or something in between.