Building two sites with Astro, and refusing to start from a template

June 16, 2026 · 9 min read

Astro

I built two sites this year with Astro: the one you're reading now, and the marketing site for RoleReady, the job-application tracker I work on. Same framework, very different jobs — a personal portfolio that should feel quiet and fast, and a product site that has to sell. The thing they have in common is that I wrote essentially every component myself instead of starting from a theme. This is a note on why, and on the one piece I'm most pleased with.

Why Astro for both

The pitch that actually held up in practice is that Astro ships zero JavaScript by default. Both of these sites are content-first — prose, layout, the occasional bit of motion — and almost none of that needs a client runtime. Astro renders to static HTML at build time, and the only JavaScript on the page is the handful of islands I explicitly asked for. The portfolio's payload is mostly HTML and CSS, and it shows in the load time.

The component model is the other reason. Astro components are close enough to plain HTML that there's no ceremony tax for writing your own, but they have real props, scoped styles, and slots when you need them. So the marginal cost of "build this myself" instead of "pull in a library" stays low. That changes what's reasonable to do by hand.

Why not a template

Templates are a great way to get a site that looks like every other site built from that template. You can usually spot them — the same hero, the same three-up feature grid, the same pricing table — because the design decisions were made by someone solving for "generic," and generic is the one thing a personal site or a young product can't afford to be.

So I gave myself a rule: design the whole thing, every section and every component, to my own vision, and only reach for someone else's code when building it myself would be genuinely foolish. That line gets crossed for things like the framework itself, or a date library — not for a card, a nav, a marquee, or a layout. The cost of that rule is real hours. The payoff is that nothing on either site looks borrowed, and every piece does exactly what I wanted instead of approximately what a theme allowed.

It's also just a better way to learn. When you own the markup and the CSS end to end, you understand why the layout behaves the way it does, and fixing it is editing your own code rather than fighting an abstraction.

The floating job-card background

The piece I'm proudest of is the background of RoleReady's feature section. Behind the scrolling feature scenes, realistic job cards drift slowly across the screen in stacked rows — a "Senior Product Manager" at Brex with an offer, an "iOS Developer" at Neon mid-interview, each with a real company favicon, a salary band, a location, and a status pill. They're the actual product's cards, used as ambient motion. The effect is that the page quietly demonstrates what the app is full of, without a single screenshot.

Mechanically it's a marquee, but the details are where the hours went. Each row renders its set of cards twice and translates by exactly half its width, so the loop is seamless with no visible seam or jump. Rows run at different speeds, alternate direction, and start at staggered horizontal offsets, so the field never falls into an obvious grid — it reads as drift, not as a conveyor belt. A horizontal gradient mask fades the cards out at both edges so they dissolve into the page rather than clipping against it.

The whole thing is CSS transforms on a track, which means it's cheap: it animates on the compositor, it doesn't touch layout, and it ships no JavaScript to run the motion. The job card itself is one component with a typed props interface, reused both as the foreground product UI and as this background texture. Building it from scratch is what made that reuse possible — a template's hero background would never have known what a job card was.

Sharing nothing, deliberately

The two sites don't share a component library, and that was a choice rather than an oversight. They have different voices — the portfolio is restrained and typographic, the product site is louder and more animated — and forcing them through a shared design system would have flattened both. Astro made it cheap enough to keep two distinct vocabularies that I never felt the pull to consolidate them prematurely.

What I'd tell someone starting

Reach for Astro if your site is mostly content and you want it to be fast without thinking about it. Then, before you install a theme, try building the first few components yourself — you'll likely find it's faster than evaluating themes, and the result is yours. The job-card marquee took an afternoon I'll never regret, and it's the kind of detail no template would have handed me.