In the web series you shipped a Worker that returns HTML strings. Five pages was great. Ten was fine. At thirty pages — with a shared header, a footer, a paywall snippet, dark mode, MDX articles, sitemaps, Open Graph tags, and per-page metadata — the "return a giant template literal" approach starts to bend. Then you hit a real choice:
Use a framework — a tool that handles routing, components, MDX, and deployment so you can focus on content and logic.
The two frameworks every JS developer asks about are Astro and Next.js. They solve the same problem from opposite ends. This chapter is the decision: what each gives you, which to pick for what kind of site, and what either one costs on Cloudflare.
What a Framework Actually Adds
If you've never used one, the marketing is vague. The five concrete things you get:
| Thing | What it means in practice |
|---|---|
| File-based routing | A file at pages/about.astro or app/about/page.tsx becomes the URL /about. No router config. (Ch 2 unpacks this.) |
| Component reuse | One <Header /> file, imported everywhere. Update the header → updates 200 pages. |
| Asset optimization | JS gets bundled and minified, CSS gets scoped, images get resized/served as WebP. None of this is your code. |
| MDX support | Markdown with embedded JSX components. Write articles in .mdx, drop a <VideoPlayer /> mid-paragraph. Every chapter on this site is MDX. |
| Dev mode | npm run dev = hot-reload on save, type-check on save, instant feedback. Way better than re-deploying a Worker every time. |
Each of those is "doable by hand," but doing all five well is a year of tooling work. A framework gives you all five out of the box.
The Two Real Options
There are dozens of frameworks. In practice, in 2026, for a new project on Cloudflare or anywhere static-leaning, two are the realistic choices:
Figure 1 — The headline difference: Astro ships zero JavaScript to the browser by default, Next.js ships React. That single trade-off explains 80% of the rest of this chapter.
Astro — "Build a content site, not an app"
Astro is a static-site-leaning framework with a unique trick: by default, none of your component code ships as JavaScript. The page is fully server-rendered to HTML; the browser gets just HTML and CSS. If you need interactivity, you opt-in component by component (an "island" — <Counter client:load />). The rest of the page stays HTML-only.
What that buys you:
- Fastest page loads — there's literally no JS bundle until you ask for one.
- Best Core Web Vitals — Lighthouse scores in the 95–100 range are routine.
- Plain
.astrofiles that look like HTML with a---front-matter for server logic. - First-class MDX, content collections, sitemap, RSS, OG-image generation.
Astro 5 (late 2024) added Server Islands (per-island server rendering at request time) and a Content Layer API for loading content from any source. The model is mature.
---
// src/pages/about.astro
const title = "About";
---
<html>
<head><title>{title}</title></head>
<body>
<h1>{title}</h1>
<p>Plain HTML in the browser. Zero KB of JS.</p>
</body>
</html>That whole page is ~200 bytes over the wire after compression. The same shape in Next.js, by default, is ~80 KB of React runtime.
Next.js — "Build an app, on React"
Next.js is React with everything-else included — routing, server rendering, server actions, streaming, suspense, image optimization, middleware. As of Next.js 13+ the App Router is the recommended model:
- React Server Components (RSC) by default. Most components render on the server, send HTML, never ship JS.
"use client"to opt a component into client-side rendering when you need interactivity.- Server Actions — write a function on the server, call it from a form, no API route needed.
- Streaming — flush HTML chunks as they're ready, with Suspense boundaries for slow data.
// app/about/page.tsx
export const metadata = { title: "About" };
export default function Page() {
return (
<main>
<h1>About</h1>
<p>React Server Component. Renders on the server; ships minimal JS.</p>
</main>
);
}The base bundle is heavier than Astro's (React + hydration), but when your app is genuinely an app — user state, forms, real-time, dashboards, anything where parts of the UI re-render in response to user input — RSC + Server Actions is dramatically more productive than wiring Astro islands.
Decision Table — Pick by Site Shape
| Site shape | Pick | Why |
|---|---|---|
| Blog / personal site | Astro | Pure content; zero JS = perfect performance + SEO. |
| Documentation | Astro (or Astro's Starlight theme) | Content-heavy, mostly static, rare interactivity. |
| Marketing site | Astro | Few pages, Core Web Vitals matter, no app state. |
| Course platform (this site) | Next.js | Subscribers, video players, paywalls, account UI — genuine app state. |
| SaaS dashboard | Next.js | Forms + auth + interactive charts + server actions — RSC's home turf. |
| E-commerce | Next.js | Cart state, checkout, dynamic product pages. |
| Static landing page | Astro | Anything you want to load in < 1 second on 3G. |
| You already know React deeply | Next.js | Reuse your muscle memory; Astro can use React components too if you want. |
The two are complementary, not enemies. Big organisations use Astro for marketing + docs (example.com, docs.example.com) and Next.js for the app itself (app.example.com).
The Bill on Cloudflare
Both frameworks deploy to Cloudflare Workers via their respective adapters:
| Astro | Next.js | |
|---|---|---|
| Adapter | @astrojs/cloudflare | @opennextjs/cloudflare (OpenNext) |
| Build output | Static HTML + small server Worker | OpenNext-bundled Worker (heavier) |
| Cold start | ~0 ms (mostly static) | ~5 ms (Worker isolate) |
| Free tier covers | Comfortably to ~100k visits/day | Comfortably to ~100k visits/day |
| Paid plan kicks in at | $5/mo for > 100k req/day | $5/mo for > 100k req/day |
| This site | — | Next.js 16 on OpenNext (you're reading it) |
For the full Cloudflare-stack-and-bill story see Cloudflare Course Platform Ch 1. The headline is the same for both frameworks: $0–$5/month until you have real traffic.
Mental Model — Three Sentences
- A framework adds five things — file-based routing, component reuse, asset optimization, MDX, and dev-mode hot-reload — which are doable by hand but a year of tooling work to do well.
- Astro vs Next.js is a single trade-off: Astro ships zero JS by default and is the right pick for content sites (blogs, docs, marketing); Next.js ships React everywhere and is the right pick for app-like sites (dashboards, SaaS, e-commerce, this site).
- Both deploy to Cloudflare Workers for $0–$5/month at indie scale — Astro via
@astrojs/cloudflare, Next.js via@opennextjs/cloudflare— so the framework choice is about productivity and shape, not infrastructure.
Try It Yourself (15 Minutes)
npm create astro@latest my-astroand pick the minimal template. Runnpm run dev. Opensrc/pages/index.astroand edit the<h1>; watch it hot-reload. Build withnpm run buildand observe the output is HTML + minimal CSS, with no JS bundle in the network tab.npx create-next-app@latest my-nextand accept defaults. Runnpm run dev. Editapp/page.tsx's<h1>. Build withnpm run buildand observe the output includes the React runtime + your code.- Compare the two
dist/(Astro) and.next/(Next.js) directories. Notice the size difference — Astro's is bytes; Next.js's is hundreds of KB. - Add the Cloudflare adapter to each (
@astrojs/cloudflare/@opennextjs/cloudflare). Deploy both — you now have two sites on Cloudflare Workers for $0. - Open the Cloudflare dashboard → Workers Analytics for each. Note that requests per day count against the same free tier regardless of framework.
Where This Lands in the Series
You've picked a framework (or know you'll defer that decision to the kind of project). The next chapter is the question every reader asks at some point — and the one that's most often answered badly:
Next chapter: File-Based Routing + What [slug] Means — how files become URLs in both frameworks, what the [slug] square-bracket syntax actually does, static vs dynamic vs catch-all routes, route params at runtime, and the exact rules for both Astro's src/pages/ and Next.js's app/ directory.
Ship your apps faster
When you're ready to publish your Swift app to the App Store, Simple App Shipper handles metadata, screenshots, TestFlight, and submissions — all in one place.
Try Simple App Shipper