Personal site built with Astro, Tailwind CSS, and a small Svelte island (live clock).
Requires Bun and Node 24.x (see engines in package.json and .node-version).
bun installbun devbun run build
bun run preview| Tool | Role |
|---|---|
| Oxlint | bun run lint / lint:fix — fast JS/TS lint (.oxlintrc.json) |
| Oxfmt | bun run fmt / fmt:check — formatter (.oxfmtrc.json) |
| unplugin-fonts | Geist via Fontsource + preload <link>s (unfonts.css, <Unfont /> in Base.astro) |
| astro-icon | Icon + Iconify; only simple-icons github & linkedin are bundled (astro.config.mjs include) |
| @astrojs/sitemap | sitemap-index.xml at build; <link rel="sitemap"> in Base.astro and Sitemap: in public/robots.txt |
Deploys to Vercel via @astrojs/vercel (static output). vercel.json uses Bun for install/build; bun.lock is the lockfile. There is no packageManager field: Corepack only supports npm/Yarn/pnpm, so npm@… conflicts with Bun detection, and bun@… can break Corepack. If builds log Corepack noise, set ENABLE_EXPERIMENTAL_COREPACK=0 in the Vercel project’s Environment Variables.
Social og:image / twitter:image use /open-graph/site.png, built from astro-og-canvas plus a CTA pill composited with sharp (src/lib/og-site-image.ts, route in src/pages/open-graph/[...route].ts). Copy lives in SITE (ogImageBody, ogImageCta). The build must reach Fontsource for Noto Sans TTFs.
This is separate from astro-embed Link Preview, which only reads external URLs for optional work cards.
Notable work entries in src/lib/notable-works.ts can include previewUrl. That renders @astro-community/astro-embed-link-preview (Open Graph at build time; Vercel needs network access during astro build).