Skip to content

Technology Stack

Framework:
name: Astro
version: 7.4.1
features:
- Static Site Generation (SSG) by default
- Server-Side Rendering (SSR) optional
- Zero JavaScript by default
- Content Layer API (content collections)
- ClientRouter (astro:transitions)
- Server Islands
Build:
bundler: Vite 8.2.0
runtime: Node.js 24.21.0 (>=24.15.0 required)
package_manager: pnpm 11.27.1 (required)
typescript: 5.9.3
CSS:
framework: Tailwind CSS v4.3.3 (via @tailwindcss/vite plugin)
approach: Utility-first with design tokens, CSS-first configuration
features:
- CSS Variables for theming
- Container queries support
- Built-in dark mode (class-based @variant)
- Oxide engine (no tailwind.config file — configured in CSS via @theme)
Design_Tokens:
format: JSON → CSS variables (tokens/dist/tokens.css), mapped to utilities via @theme inline
build: pnpm run tokens:build (scripts/src/build-tokens.ts)
tools:
- style-dictionary (optional token generation)
Content:
format: MDX with Astro Content Collections
features:
- Type-safe frontmatter
- Custom components in content
- Automatic image optimization
- Content Layer API for external data
Assets:
images:
- Astro <Image> component
- Sharp for processing
- Single-format output, AVIF by default (ADR-030; the Image atom's `format` prop overrides)
fonts:
- Astro Fonts API with fontProviders.local() (self-hosted woff2 in src/assets/fonts/)
- Variable fonts preferred, metric-adjusted fallbacks generated automatically
Progressive_Enhancement:
1. CSS-only solutions (preferred)
2. ClientRouter from astro:transitions (SPA-like navigation)
3. Preact Islands (client-side state)
ClientRouter_vs_Islands:
ClientRouter: For page-level animations and maintaining state across navigation (e.g., persistent audio player). Manages the "frame" of the app.
Islands: For component-level interactivity that requires client-side JavaScript (e.g., an interactive form). Manages interactive "widgets" on a page.
Island_Directives:
- client:visible (lazy load)
- client:idle (load when idle)
- client:media (responsive loading)
- client:only (skip SSR)
Never: client:load (unless justified in ADR)
Linting_Formatting:
primary: Biome (replaces ESLint + Prettier)
config: biome.json
benefits:
- 20x faster than ESLint
- Single tool for lint + format
- Built-in import sorting
- TypeScript-first
Type_Checking:
- TypeScript strict mode
- @astrojs/check for templates
- Type generation from Content Collections
Git_Hooks:
tool: Husky + lint-staged
pre-commit:
- Format/lint staged code files with Biome (biome check --write)
- Fix staged Markdown with markdownlint-cli2
commit-msg:
- Conventional commits enforced via commitlint
pre-push:
- Unit test suite (pnpm run test:unit)
# Type checking (astro check) runs in quality:ci, not in git hooks
TypeScopeToolWhere it runs
UnitEssential (TDD, ADR-037)Vitestquality:ci, pre-push hook
E2EEssentialPlaywright (e2e/)CI
A11yEssentialaxe-core + Playwright (test:a11y)CI
PerformanceEssentialLighthouse CI (desktop + mobile)CI, floors 0.90/0.95/0.95/0.90
MutationRecommendedStryker (test:mutate)Weekly workflow (ADR-042)
Component_Docs:
approach: TypeScript interfaces + JSDoc on component props
features:
- Props documented at the type level
- Playwright e2e specs covering key pages (no visual-regression snapshots)
- "@a11y-tagged accessibility checks in the e2e suite (pnpm run test:a11y)"
API_Docs:
- TypeScript JSDoc
- Generated from types
- Markdown for guides
Primary: GitHub Pages
notes:
- The starter ships a ready-to-use workflow (.github/workflows/deploy.yml)
- Base path derived automatically from package.json name
- Free for public repos
Alternatives:
- Cloudflare Pages (global CDN, Web Analytics included)
- Vercel (great DX)
- Netlify (mature platform)
Build_Time:
- Image optimization via Sharp
- CSS purging via Tailwind
- Bundle analysis via Vite
- Compression (Brotli/Gzip)
Runtime:
shipped: none — the starter includes no analytics or monitoring provider (see Optional Analytics)
Recommended:
- Uptime monitoring
- Core Web Vitals tracking (RUM)
Advanced:
- Error tracking with source maps
- Session replay (privacy-safe)

The starter’s package.json and versions.json are the single source of truth for exact versions — a hardcoded list here would drift. The headline pins: Astro 7.4.1, Tailwind CSS 4.3.3 (via @tailwindcss/vite), Preact 10.29.8, TypeScript 5.9.3, Biome 2.5.15, Vitest 4.1.11, Playwright 1.64.1, plus @astrojs/mdx, @astrojs/sitemap, @astrojs/preact, and Sharp.

Dev tooling includes Husky, lint-staged, Stryker (@stryker-mutator/core for mutation testing), Lighthouse CI 0.15.1, and tsx. Semgrep (SAST) and gitleaks (secret scanning) run in CI via their official containers rather than as devDependencies. Engines require Node >=24.15.0 and pnpm >=10.

{
"scripts": {
"dev": "astro dev",
"build": "pnpm run env:validate && pnpm run tokens:build && astro build",
"preview": "astro preview",
"check": "SITE_URL=${SITE_URL:-http://localhost:4321} astro check",
"format": "biome format . --write",
"lint": "biome check .",
"quality:ci": "pnpm run format:check && pnpm run lint && pnpm run lint:md && pnpm run check && pnpm run test:unit && pnpm run agents:check && pnpm run version:check && pnpm run og:check && pnpm run docs:count",
"tokens:build": "tsx scripts/src/build-tokens.ts",
"design:validate": "tsx scripts/src/validate-contrast.ts",
"perf:baseline": "tsx scripts/src/baseline-performance.ts",
"prepare": "husky"
}
}

See the starter’s package.json for the full script catalogue (testing, performance gates, maintainer tooling).

  1. Astro 7.4.1: Best-in-class static site generator with minimal JavaScript
  2. Tailwind v4: Modern utility CSS with the Oxide engine and CSS-first configuration
  3. Biome: Massive speed improvement over ESLint/Prettier
  4. Preact: Smaller than React for islands that need state
  5. GitHub Pages: Zero-config deploys via the bundled deploy.yml workflow
  • ❌ Multiple build tools (webpack, rollup, etc.)
  • ❌ Heavy component frameworks for simple sites
  • ❌ Overlapping linters and formatters
  • ❌ Client-side routing libraries
  • ❌ Large JavaScript frameworks for minimal interactivity
  • ❌ External image CDNs (use Astro’s built-in optimization)

When updating from older versions:

  1. Astro 6 → 7: The unified/remark processor is retained for snippet includes (ADR-062); the agent-facing background dev server arrives with dev:agent (ADR-063)
  2. Astro 5 → 6: Legacy content collections are gone — use the Content Layer (src/content.config.ts, glob() loaders, entries keyed by .id)
  3. Tailwind 3 → 4: Config moves into CSS (@import "tailwindcss" + @theme); the @astrojs/tailwind integration is replaced by @tailwindcss/vite
  4. ESLint → Biome: Run migration command: pnpm dlx @biomejs/biome migrate
  5. React → Preact: Update imports in island components