The source of my personal site. Cinematic-dark, animated, and led by IT work rather than by a projects grid.
Stack: Astro 5 · TypeScript · Vitest
A rebuild of a v1 Express/EJS site, moved to Astro for static output with islands only where interactivity is genuinely needed — so most pages ship no JavaScript at all.
Two pieces have real logic behind them and are unit-tested: the contact form handling and a live status section. The résumé PDF is generated from source by a build script rather than being a binary someone has to remember to re-upload, so the site and the PDF can't drift apart.
npm install npm run dev # localhost:4321 npm test npm run build
Live at mitchelltrout.com.
| Command | Action |
|---|---|
npm run dev |
Dev server at http://localhost:4321 |
npm test |
Vitest (contact + status logic) |
npm run build |
Production build to dist/ |
npm run preview |
Serve the production build locally |
node dist/server/entry.mjs |
Run the standalone production server |
./scripts/build-resume.sh |
Regenerate public/Mitchell-Trout-Resume.pdf |
- Create
src/content/projects/<slug>.md(copy an existing file for the frontmatter shape). - Drop screenshots in
src/assets/screenshots/and list them in the frontmatter with alt text. npm run build— the schema validates everything.
- Pull,
npm install,npm run build - Copy
.env.example→.env, fill in Brevo credentials - Run
deploy/start.bat(serves on PORT, default 3005) - Caddy: existing
mitchelltrout.comblock already points at 3005 — one CSP addition, seedeploy/caddy-changes.md - Rollback: stop this, start the old
portfolioapp again