#Astro
11 posts
Putting a Three.js island inside a static site
The isle page downloads only its own script. The scene is computed at runtime, Three.js stays in that page's chunk, and the first HTML response carries an empty stage.
The loading budget for 3D: split the chunk, load on visibility, know when to stop
A 3D page pays three costs — download, first-frame compilation, per-frame drawing. Each needs its own budget, and any one of them can turn good-looking into janky.
Islands are not Web Components: two different kinds of on-demand loading
Islands decide at build time where JavaScript is needed and when it hydrates. Web Components give the browser a self-contained element at runtime. Confusing them picks the wrong tool.
1059 assertions, no test framework: why pure logic must import nothing
My test suite is `node scripts/selftest.ts` — no framework, no dependencies. The price is that every module it touches must have zero relative imports, and that price bought a codebase shape.
Pushing first-load JS to zero with Astro islands
From "async import" to "hydrate on demand" — what each of the three lazy-loading layers actually solves, with the code that runs on this site.
Pagination at build time: why a static site should not page with a query string
The post list is sliced into static pages during the build, so page N is a real route. No client-side paging logic, no query string, just links.
The @/ alias lives in three configs, and all three are required
Deep relative imports are banned project-wide, and the price is configuring the alias in three places. Miss one and you get editor errors, a broken build, or silently dropped styles.
zod as a frontmatter contract: bad articles fail the build
The Content Collections schema is the single source of truth. A title over 120 characters, a mangled date or a string where an array belongs fails immediately instead of silently dropping a page.
Why I built yet another personal site
Not because there was nowhere to write, but because there was nowhere to put writing, small games and tools side by side.
A zero-config registry: adding a game means adding a directory
App lists, detail routes, the home page picks and the sitemap are all discovered by import.meta.glob. The price is Vite's hard rule: literal relative paths only.
Views hold no logic: all data assembly lives in src/server
A page here exports a route, imports two components and passes props. Everything else — fetching, paths, dates — happens in src/server. Here is what that buys, and the type constraint it forces.
