Fasted Web Experience Possible?

bill-cupid1 pts0 comments

Astro 6 + Specific.dev: the stack ano.chat ships on ← All posts<br>Astro 6 + Specific.dev: the stack ano.chat ships on

by Ruben Flam · Co-founder, Ano · posted May 21, 2026 · 7 min read · #engineering · #astro · #specific · #performance · #marketing-site<br>A marketing site is a stack of pages a human reads once. It is<br>not a React app. It has no session. It has no state machine.<br>Nothing on it is realtime.

Every marketing site you have visited in the last five years was<br>built like one anyway. A React tree, a hydration pass, half a<br>megabyte of JavaScript to render text that was already on the<br>wire, deployed through a build farm an ocean away from the<br>person reading the page. They all feel the same: a flash of<br>nothing, a flash of text, the page settles.

We were not going to ship another one.

The site you are reading is three decisions. Specific.dev<br>is where it runs. Astro 6 is what builds the pages.<br>Content collections are how the words become pages.<br>Together they are why this page comes up as fast as it does.

Specific.dev: the deploy is the merge

The thing we use the most on Specific.dev<br>is the thing they do not put on a feature page: the GitHub<br>integration.

git push origin main<br>That is the deploy. Specific.dev watches the branch, builds<br>the Astro app, runs migrations against the env’s Postgres, and<br>flips traffic at the edge when the new version is healthy. No<br>specific deploy, no CI step we own, no waiting in front of a<br>yellow check mark. The merge is the deploy.

Two things fall out of that:

Preview environments are free. Open a branch, push, get<br>a URL with real data. Land it, the preview goes away.

Rollbacks are trivial. A bad commit gets a revert, which<br>is another push, which is another deploy. The same loop.

Specific.dev itself is a cloud platform built for coding agents:<br>one CLI, one config file, every primitive a small product<br>needs (managed Postgres with read replicas, S3-compatible<br>storage, a Redis-compatible cache, secrets, a global CDN with<br>auto-generated TLS) on the same control plane. The marketing<br>site uses a thin slice: frontend hosting, Postgres for signups<br>and admin state, a couple of secrets. The chat product uses<br>more.

Where it bites

The merge-is-the-deploy story is true for the Astro origin and<br>not true for the Cloudflare Workers in front of it. The<br>workers (an edge HTML cache, a dev-domain redirect) live in<br>the same repo but deploy on a separate track: a wrangler deploy from each worker directory, run by a human. The day<br>someone pushes a worker change to main and forgets the<br>wrangler deploy, git and the edge drift and the bug looks<br>like the worker code in the repo behaving differently than<br>the worker code in production. We have done this. It is<br>documented in the repo and we still occasionally redo it.

That is the kind of seam a newer platform has and an older<br>one would have smoothed over. Specific.dev does not own the<br>edge in front of itself the way Cloudflare does. We chose to<br>keep both, and pay the seam.

What we ruled out

Vercel. Excellent frontend platform. Bring your own<br>database. We did not want a second control plane for the<br>Postgres the admin tools need.

Netlify. Same shape, same answer.

Fly / Render / Railway. Good runtimes. Each ships a<br>slice of what Specific.dev gives in one box. Composing them<br>is up to you.

Cloudflare Pages plus D1. Tempting. Postgres is what<br>our team writes against. D1 is not.

Specific.dev gave us Postgres, CDN, secrets, preview envs,<br>and the GitHub auto-deploy in one place. That is the bar.

Astro 6: HTML first, JavaScript on request

The site has a performance budget written into the repo. Mobile<br>Lighthouse at or above 90. LCP under 2.5 seconds. FCP under 1.8<br>seconds. CLS under 0.05. Total payload under 1.5MB on the home<br>page and 1MB elsewhere. Anything that drops the score by more<br>than five points does not merge.

The homepage today is 37KB of gzipped HTML on the wire, 152ms<br>to first byte from the EU edge. The rest of the site sits<br>under that. Holding that line against an SPA framework is a<br>job. Holding it against Astro 6 is the<br>default.

Astro is a content-first web framework. A page is an .astro<br>file: HTML with a TypeScript frontmatter block on top. The<br>build outputs HTML. JavaScript ships on the components you mark<br>with a client:* directive, and only those. The default is<br>zero JS. The opt-in is a single attribute.

import Counter from "../components/Counter.tsx";

h1>Team chat with Claude Code built in.h1>

Counter client:visible /><br>The hero on this page is HTML. A client:visible island<br>hydrates when it scrolls into view, and only then. Nothing<br>else on the page costs the reader a kilobyte of JavaScript.

That is the user-experience argument in four bullets:

First paint feels like final paint. The browser receives<br>HTML that already knows what it is rendering. No hydration<br>flash, no skeleton, no second pass of layout.

Less JavaScript means less time to interactive. On a<br>mid-range phone on 4G the gap between “page visible” and<br>“page...

specific astro page deploy site html

Related Articles