Technology Stack
Core Stack
Section titled “Core Stack”Framework & Build Tools
Section titled “Framework & Build Tools”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.3Styling & Design
Section titled “Styling & Design”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 & Data
Section titled “Content & Data”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 automaticallyInteractivity (When Needed)
Section titled “Interactivity (When Needed)”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)Development Tools
Section titled “Development Tools”Code Quality
Section titled “Code Quality”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 hooksTesting Strategy
Section titled “Testing Strategy”| Type | Scope | Tool | Where it runs |
|---|---|---|---|
| Unit | Essential (TDD, ADR-037) | Vitest | quality:ci, pre-push hook |
| E2E | Essential | Playwright (e2e/) | CI |
| A11y | Essential | axe-core + Playwright (test:a11y) | CI |
| Performance | Essential | Lighthouse CI (desktop + mobile) | CI, floors 0.90/0.95/0.95/0.90 |
| Mutation | Recommended | Stryker (test:mutate) | Weekly workflow (ADR-042) |
Documentation & Component Development
Section titled “Documentation & Component Development”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 guidesDeployment & Infrastructure
Section titled “Deployment & Infrastructure”Hosting
Section titled “Hosting”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)Performance & Monitoring
Section titled “Performance & Monitoring”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)Package Versions
Section titled “Package Versions”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 (everyday subset)
Section titled “Scripts (everyday subset)”{ "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).
Technology Decision Rationale
Section titled “Technology Decision Rationale”Why These Choices?
Section titled “Why These Choices?”- Astro 7.4.1: Best-in-class static site generator with minimal JavaScript
- Tailwind v4: Modern utility CSS with the Oxide engine and CSS-first configuration
- Biome: Massive speed improvement over ESLint/Prettier
- Preact: Smaller than React for islands that need state
- GitHub Pages: Zero-config deploys via the bundled
deploy.ymlworkflow
What We Avoid
Section titled “What We Avoid”- ❌ 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)
Migration Notes
Section titled “Migration Notes”When updating from older versions:
- 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) - Astro 5 → 6: Legacy content collections are gone — use the Content Layer (
src/content.config.ts,glob()loaders, entries keyed by.id) - Tailwind 3 → 4: Config moves into CSS (
@import "tailwindcss"+@theme); the@astrojs/tailwindintegration is replaced by@tailwindcss/vite - ESLint → Biome: Run migration command:
pnpm dlx @biomejs/biome migrate - React → Preact: Update imports in island components