Project Directory Structure
Project Organization Philosophy
Section titled “Project Organization Philosophy”The Astro Performance Starter follows a structured, scalable architecture designed for:
- Developer Experience: Clear, predictable file locations
- Performance First: Optimized build output and asset organization
- Atomic Design: Component hierarchy that scales from simple to complex
- Type Safety: TypeScript-first with generated types from content
- AI-Friendly: Well-documented structure for AI development tools
Complete Directory Structure
Section titled “Complete Directory Structure”astro-performance-starter/├── .github/│ ├── workflows/│ │ ├── ci.yml # Quality gates, budgets, e2e│ │ ├── deploy.yml # GitHub Pages deployment│ │ ├── lighthouse.yml # Lighthouse CI gates (desktop + mobile)│ │ ├── mutation.yml # Stryker mutation testing│ │ └── release.yml # Release automation│ ├── CODEOWNERS│ ├── PULL_REQUEST_TEMPLATE.md│ ├── dependabot.yml│ └── ISSUE_TEMPLATE/│ ├── bug-report.md│ └── feature-request.md│├── docs/│ ├── README.md # Docs overview & navigation│ ├── getting-started/ # Onboarding, FAQ, quick deploy│ ├── development/ # Contributor workflows & conventions│ ├── patterns/ # Pattern guides (islands, MDX, …)│ ├── snippets/ # Reusable doc snippets│ ├── ai-context/ # AI assistant context docs│ ├── assets/ # Doc images and assets│ ├── 2026-06_design_system/ # Design system reference sheets│ ├── logo.svg│ ├── personalization-guide.md│ ├── implementation-guides/ # Development guides│ │ ├── README.md # Implementation roadmap (tier model)│ │ ├── completed/ # Foundation phases (0-4)│ │ │ ├── phase-0-foundation.md│ │ │ ├── phase-1-content-arch.md│ │ │ ├── phase-2-design-system.md│ │ │ ├── phase-3-tooling.md│ │ │ ├── phase-4-skeleton.md│ │ │ └── phase-{1..4}-code-examples.md│ │ ├── active-phases/ # Build & polish phases (5-12)│ │ │ ├── phase-5-components.md│ │ │ ├── phase-6-sections.md│ │ │ ├── phase-7-content.md│ │ │ ├── phase-8-qa.md│ │ │ ├── phase-9-performance.md│ │ │ ├── phase-10-deployment.md│ │ │ ├── phase-11-documentation.md│ │ │ └── phase-12-post-launch.md│ │ ├── guides/ # Topic-specific guides│ │ │ ├── accessibility-guide.md│ │ │ ├── components-guide.md│ │ │ ├── content-model-guide.md│ │ │ ├── image-optimization-guide.md│ │ │ ├── responsive-design-guide.md│ │ │ ├── rollback-strategies-guide.md│ │ │ └── testing-strategy-guide.md│ │ ├── code-examples/ # Implementation examples│ │ │ └── phase-{5..10,12}-code-examples.md│ │ └── reference/ # Technical reference│ │ ├── tech-stack.md│ │ ├── directory-structure.md│ │ ├── budgets-guardrails.md│ │ ├── portfolio-checklist.md│ │ ├── optional-analytics.md│ │ └── table-format-guide.md│ └── adr/ # Numbered ADRs through 062│ ├── README.md│ ├── template.md│ ├── 000-starter-decisions.md│ └── … # 001 … 062│├── src/│ ├── assets/│ │ ├── brand/ # Brand SVGs│ │ ├── fonts/ # Self-hosted woff2 (Astro Fonts API)│ │ ├── icons/ # SVG icon sources│ │ └── logo.svg # Project logo│ ├── components/│ │ ├── atoms/ # Badge, Button, Icon, Image, ThemeToggle, …│ │ ├── molecules/ # Card, ContactForm, Dialog, Head, Tabs, …│ │ ├── structural/ # Container, Section, Grid, Header, Footer, …│ │ ├── islands/ # Preact islands (SignalsCounter, MotionLab)│ │ ├── mdx/ # MDX component set (Callout, Figure, …)│ │ ├── a11y/ # SkipLink│ │ ├── ThemeSetup.astro # Theme initialization│ │ └── CLAUDE.md # Component guidelines│ ├── content.config.ts # Content Layer collection schemas│ ├── content/│ │ ├── bio/ # Bio/profile content│ │ ├── blog/ # Blog posts (four examples)│ │ ├── experience/ # Experience entries│ │ ├── navigation/ # Nav data (header.json, …)│ │ └── projects/ # Portfolio projects│ ├── layouts/│ │ ├── BaseLayout.astro # Complete base layout│ │ ├── BlogLayout.astro│ │ └── ProjectLayout.astro│ ├── pages/│ │ ├── index.astro # Homepage│ │ ├── about.astro, contact.astro, how-it-works.astro, showcase.astro│ │ ├── blog/, projects/, adr/ # Route directories ([slug] + index)│ │ ├── robots.txt.ts # robots.txt generated at build time│ │ ├── rss.xml.ts # RSS feed route│ │ ├── 404.astro│ │ └── 500.astro│ ├── styles/│ │ └── global.css # With token integration│ ├── types/│ │ ├── astro-content.d.ts # Generated types│ │ ├── content.ts # Shared content schemas│ │ ├── icons.ts│ │ └── navigation.ts # Navigation types│ ├── utils/ # blog, formatDate, url-utils, …│ └── config.ts # Site config│├── public/│ ├── _headers # Security headers│ ├── favicon.svg, favicon.ico, apple-touch-icon.png│ ├── og-*.png, og-*.svg # Open Graph images│ ├── logo.svg│ └── site.webmanifest│├── scripts/│ ├── src/ # Script source files│ │ ├── build-tokens.ts # Token builder│ │ ├── validate-contrast.ts # Contrast validator│ │ ├── track-performance-budgets.ts # Budget tracking│ │ └── … # OG builder, gates, remark plugins│ └── tsconfig.json # Scripts TypeScript config│├── tokens/│ ├── base.json # Complete token set│ ├── semantic.json│ └── dist/ # Git-ignored│├── e2e/ # Playwright specs (9 page suites)│├── .devcontainer/ # Dev container config├── .claude/ # AI constitution layers├── .husky/ # pre-commit, commit-msg, pre-push hooks│├── .commitlintrc.cjs # Commit message linting├── .editorconfig # Editor settings├── .env.example # Environment template├── .gitignore # Comprehensive ignore├── .lintstagedignore # Lint staged ignore├── .nvmrc # Node version├── .windsurfrules # Windsurf overlay (thin; see AGENTS.md)├── AGENTS.md # Generated agent instructions├── CLAUDE.md # AI constitution├── CHANGELOG.md # Release notes├── CONTRIBUTING.md # Contribution guide├── README.md # Project overview├── SECURITY.md # Security policy├── LICENSE.txt # MIT license├── astro.config.mjs # Framework config├── biome.json # Complete config├── budget-overrides.json # Example overrides├── budgets.json # Raw-size performance budgets├── ec.config.mjs # Expressive Code config├── lighthouserc.json # Lighthouse CI (desktop)├── lighthouserc.mobile.json # Lighthouse CI (mobile)├── package.json # All deps, no fluff├── playwright.config.ts # E2E config├── pnpm-lock.yaml # Lockfile├── stryker.conf.json # Mutation testing config├── tsconfig.json # Strict mode├── versions.json # Public version manifest (ADR-061)└── vitest.config.ts # Testing configComponent Architecture (Atomic Design)
Section titled “Component Architecture (Atomic Design)”Primary Component Categories
Section titled “Primary Component Categories”src/components/├── atoms/ # Basic UI building blocks│ ├── Button.astro # Interactive elements│ ├── Badge.astro # Status/label badges│ ├── Icon.astro # SVG icons│ ├── Image.astro # Optimized images (astro:assets)│ ├── ThemeToggle.astro # Light/dark switch│ ├── Tooltip.astro│ └── … # SocialLink, ScrollReveal, ReadingProgress, …│├── molecules/ # Simple component combinations│ ├── Card.astro # Content cards│ ├── ContactForm.astro # Complete contact form│ ├── Dialog.astro # Modal dialog│ ├── Head.astro # Document head (meta, fonts, OG)│ ├── Tabs.astro│ ├── PostCard.astro / ProjectCard.astro│ └── … # ScrollSpy, SectionSeparator, TypeSpecimen, …│├── structural/ # Layout and positioning│ ├── Container.astro # Content width constraints│ ├── Section.astro # Semantic page sections│ ├── Grid.astro # Layout grids│ ├── Header.astro # Site header│ ├── Footer.astro # Site footer│ └── ParallaxSection.astro│├── islands/ # Preact islands (client-side state)│ ├── SignalsCounter.tsx│ └── MotionLab.tsx│├── mdx/ # Content-specific components│ ├── Callout.astro # Information boxes│ ├── Figure.astro # Images with captions│ ├── Grid.astro, Blockquote.astro, Link.tsx, CodeFromFile.astro│ └── index.ts # MDX component map│└── a11y/ # Accessibility helpers └── SkipLink.astroThere is no organisms/ directory — complex page sections are composed
in pages from structural/ and molecules/ components.
Component Naming Conventions
Section titled “Component Naming Conventions”// File naming: PascalCaseButton.astroHeroSection.astroNavigationMenu.astro
// Component exports: Match filenameexport default Button;export default HeroSection;export default NavigationMenu;
// Props interface: ComponentPropsinterface ButtonProps { variant?: 'primary' | 'secondary'; size?: 'sm' | 'md' | 'lg';}
interface HeroSectionProps { title: string; subtitle?: string; backgroundImage?: string;}TypeScript Import Aliases
Section titled “TypeScript Import Aliases”Pre-configured path aliases for clean imports:
// Available aliasesimport Button from '@components/atoms/Button.astro';import { formatDate } from '@utils/date-utils';import { siteConfig } from '@/config';import heroImage from '@assets/hero.jpg';import BaseLayout from '@layouts/BaseLayout.astro';import type { NavigationItem } from '@types/navigation';
// tsconfig.json configuration{ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"], "@components/*": ["src/components/*"], "@layouts/*": ["src/layouts/*"], "@utils/*": ["src/utils/*"], "@styles/*": ["src/styles/*"], "@types/*": ["src/types/*"], "@assets/*": ["src/assets/*"], "@content/*": ["src/content/*"] } }}Content Organization
Section titled “Content Organization”Content Collections Structure
Section titled “Content Collections Structure”src/content.config.ts # Collection schemas (Content Layer, at src root)src/content/├── blog/ # Blog posts (directories per post)├── projects/ # Portfolio items├── bio/ # Bio/profile content├── experience/ # Experience entries└── navigation/ # Nav data (header.json, …)
# A sixth collection, `adr`, loads from docs/adr/ (outside src/content/)# via a glob() loader and powers the /adr/ routes.Content Type Patterns
Section titled “Content Type Patterns”// Schema definition pattern (src/content.config.ts — Content Layer)import { defineCollection } from 'astro:content';import { glob } from 'astro/loaders';import { z } from 'astro/zod';
const blog = defineCollection({ loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ title: z.string(), description: z.string(), publishDate: z.date(), author: z.string().optional(), tags: z.array(z.string()).optional(), draft: z.boolean().default(false), }),});
// Usage pattern — entries are keyed by `id`, not `slug`import { getCollection, getEntry } from 'astro:content';
const allPosts = await getCollection('blog');const post = await getEntry('blog', 'example-post');Performance Considerations
Section titled “Performance Considerations”Asset Organization
Section titled “Asset Organization”Performance Strategy: images: location: src/assets/ (processed) | public/ (static) formats: AVIF → WebP → JPEG fallback optimization: Automatic via Astro Image component
fonts: source: Astro Fonts API, fontProviders.local() (woff2 vendored in src/assets/fonts/) format: WOFF2 variable fonts preferred loading: metric-adjusted fallbacks generated by Astro (cuts CLS)
icons: format: SVG inline (< 2KB) or sprite optimization: SVGO processing
scripts: bundling: Vite automatic code splitting islands: Lazy loaded via client directives critical: Inlined via is:inline (sparingly)Build Output Structure
Section titled “Build Output Structure”dist/ # Generated at build time├── _astro/ # Hashed JS/CSS/image assets│ ├── index.abc123.js│ ├── index.def456.css│ └── hero.ghi789.avif├── index.html # Static HTML at route directories├── about/, blog/, projects/, adr/, …├── 404.html├── robots.txt # Emitted by src/pages/robots.txt.ts└── _headers # Deployment headersDevelopment Workflow
Section titled “Development Workflow”File Creation Patterns
Section titled “File Creation Patterns”# New component workflow1. Create component file: src/components/atoms/NewButton.astro2. Add to appropriate category (atoms/molecules/structural/islands)3. Export component with proper TypeScript props4. Document usage per src/components/CLAUDE.md guidelines5. Add to component index if needed
# New content workflow1. Define schema in src/content.config.ts2. Create collection directory: src/content/[collection]/3. Add content files with proper frontmatter4. Test with pnpm run check5. Build and validate outputFolder Naming Conventions
Section titled “Folder Naming Conventions”- Directories:
kebab-case(e.g.,hero-section/) - Components:
PascalCase.astro(e.g.,HeroSection.astro) - Utilities:
camelCase.ts(e.g.,formatDate.ts) - Content:
kebab-case.mdx(e.g.,getting-started.mdx) - Types:
camelCase.tsor descriptive names (e.g.,navigation.ts)
Integration Points
Section titled “Integration Points”Key Configuration Files
Section titled “Key Configuration Files”Critical Files: astro.config.mjs: # Framework configuration - integrations (MDX, Sitemap, Preact) - Tailwind v4 via the @tailwindcss/vite plugin - build settings - deployment config
src/styles/global.css: # Design system integration (Tailwind v4 CSS-first) - imports tokens/dist/tokens.css - maps tokens to utilities via @theme inline - dark mode @variant
tsconfig.json: # TypeScript configuration - strict mode enabled - path aliases - content collections types
biome.json: # Code quality - linting rules - formatting preferences - import organizationArchitecture Decision Records
Section titled “Architecture Decision Records”This directory structure is enforced by ADR-003: Unified Component Structure, which establishes:
- Atomic Design as the mandatory component organization pattern
- Import alias requirements for clean code
- Component placement rules and exceptions
- Migration guidelines for existing projects
Getting Started
Section titled “Getting Started”- Explore components: Start with
src/components/CLAUDE.md - Review patterns: Check common patterns
- Understand content: Read content collections
- Learn islands: Study islands architecture
- Performance focus: Review budgets & guardrails
This structure provides a scalable foundation that grows with your project while maintaining performance, accessibility, and developer experience as core principles.