My personal portfolio, built as a static Astro site. I deliberately keep it small: Astro renders the page, Vite builds the assets, and a short browser script handles the theme and project index.
- Astro 7
- Vite 8 through Astro
- TypeScript with Astro's strict configuration
- Plain CSS
- Bun 1.4 for dependency management and scripts
- GitHub Actions and GitHub Pages
There is no database, server runtime, UI framework, résumé download, or content management
system. Portfolio content lives in src/data/portfolio.ts and the deployed result is static
HTML, CSS, and JavaScript. Longer writing lives as Markdown in src/content/writing/.
The reusable AlanD20 brand assets live in public/brand/; the flat SVG mark is used by the site,
the high-resolution transparent PNG can be used as an avatar, and the 1200×630 social image is
used for link previews.
Install the exact locked dependencies:
bun ciStart the local development server:
bun run devRun every local quality gate used by CI:
bun run verifyOther useful commands:
bun run check # Astro and TypeScript diagnostics
bun run build # production build in dist/
bun run preview # preview the production build
bun run format # format the repository
bun run format:checkThe portfolio is driven by src/data/portfolio.ts:
compactProjectsalways links to a repository and can optionally add afeaturedLink. Its label and badge can describe an official website, documentation, package, live demo, or another useful destination.workHistoryandeducationHistorypopulate background sections before technical experience.buildingEntriesmodels a public organization separately from its optional products. If the organization is also the product, leave itsproductslist out. Each product accepts multiple labelled links for destinations such as its website, repository, documentation, or demo.research,experiments,contributions, andtalkspopulate output sections after the main project index.- Adding the first entry to an optional data section makes its section and navigation link appear automatically. Empty sections render no markup.
experienceAreasis an inventory of technologies used over time, not a proficiency ranking.
Writing uses Astro's local content collection. Copy src/content/writing/_draft-template.md,
rename it to the URL slug you want, and update its frontmatter:
---
title: Article title
description: One concise summary.
publishedAt: 2026-08-24
updatedAt: 2026-09-01 # optional
tags: [Linux, Infrastructure]
draft: false
externalUrl: https://example.com/original # optional
---Published local entries receive /writing/<slug>/ pages. An externalUrl links the writing list
to the original destination instead. Drafts and future-dated entries generate no section item,
navigation link, page, or sitemap entry. When no writing is published, /writing/ is not built.
.github/workflows/deploy.yml verifies and builds every pull request. A push to main also
uploads the static build and deploys it to GitHub Pages. The workflow pins Bun 1.4 and uses the
official Astro and GitHub Pages actions.
The Astro site value and public/CNAME target https://aland20.com. In the repository's
Settings → Pages, select GitHub Actions as the publishing source and configure the same
custom domain.
The previous portfolio iterations remain available through archive/* tags. These tags are
historical pinpoints rather than release lines; v3 replaces the former Next.js application on
main.