Technology Stack
Core Stack
Section titled “Core Stack”Framework & Build Tools
Section titled “Framework & Build Tools”Framework: name: Astro version: {{versions.astro}} 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 7.x runtime: Node.js 24.x (>=24 required) package_manager: pnpm 10.13.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) - tailwindcss-themer (optional theme switching)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 - AVIF + WebP output 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 | MVP | Showcase | Tool |
|---|---|---|---|
| Unit | ✅ Mandatory (TDD, ADR-037; runs in quality:ci) | ✅ Mandatory | Vitest |
| Mutation | Optional | ✅ | Stryker (test:mutate) |
| E2E | Manual | ✅ | Playwright |
| A11y | Dev tools | ✅ | axe-core + Playwright |
| Performance | Lighthouse | ✅ | Lighthouse CI |
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: MVP: - Cloudflare Web Analytics - Uptime monitoring - Basic error logging
Showcase: - Real User Monitoring (RUM) - Core Web Vitals tracking - 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.2.2, Tailwind CSS 4.3.3 (via @tailwindcss/vite), Preact 10.29.8, TypeScript 5.9.3, Biome 2.5.8, Vitest 4.1.10, Playwright 1.62.1, plus @astrojs/mdx, @astrojs/sitemap, @astrojs/preact, and Sharp.
Dev tooling includes Husky, lint-staged, Stryker (@stryker-mutator/core 9.6 for mutation testing), Lighthouse CI, 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.2.2: 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 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