benchmark
This is the Astro web framework monorepo — a content-focused static site generator and full-stack web framework that compiles .astro components into optimized HTML with minimal client-side JavaScript. It includes the core framework, a CLI, an image optimization pipeline, content collections system, SSR runtime, and official integrations for React, Svelte, Solid, Preact, Lit, Alpine.js, MDX, Markdoc, and more.
Tech Stack
Key Features
- .astro Component Compilation
- Partial Hydration (Islands Architecture)
- Multi-Framework Integrations
- Content Collections
- Image Optimization Pipeline
- SSR Application Runtime
- File-Based Routing
- Middleware Pipeline
- View Transitions
- Internationalization (i18n)
- Dev Toolbar
- Link Prefetching
- Markdown & MDX Processing
- CLI Toolchain
Entry Points
Start here when working with this codebase
packages/astro/src/cli/index.tsMain CLI entry point that dispatches subcommands (dev, build, add, check, sync, preview). Parses arguments and routes to the appropriate command handler.
Start here when adding a new CLI command, modifying CLI argument parsing, or understanding how Astro boots up.
packages/astro/src/core/config/index.tsResolves and validates the Astro configuration object from astro.config.mjs files. Merges defaults, user config, and CLI flags.
Start here when adding a new configuration option or changing how config is resolved.
packages/astro/src/@types/astro.tsCentral TypeScript type definitions for the entire Astro framework including AstroConfig, AstroIntegration, SSRResult, and all public API types.
Start here when adding new types, extending existing interfaces, or understanding the shape of any Astro data structure.
packages/astro/src/vite-plugin-astro/index.tsThe primary Vite plugin that handles .astro file compilation, HMR, and module transformation. Bridges Astro's compiler output into Vite's module system.
Start here when modifying how .astro files are compiled, changing HMR behavior, or adding new file transform capabilities.
packages/astro/src/vite-plugin-astro-server/index.tsVite plugin that powers the Astro dev server: handles request routing, SSR rendering in dev mode, error overlay, and HMR coordination.
Start here when modifying dev server request handling, adding dev-only middleware, or changing how errors display in development.
packages/astro/src/core/build/index.tsOrchestrates the full production build: static generation, SSR bundling, asset optimization, and output writing.
Start here when modifying the build process, adding build steps, or debugging production output issues.
packages/astro/src/core/app/index.tsThe SSR application runtime used by deployed adapters. Handles incoming requests, matches routes, and renders pages in production SSR mode.
Start here when modifying how SSR adapters handle requests, changing response generation, or adding SSR-specific features.
packages/astro/src/core/routing/index.tsCreates the route manifest from the file system, handles route matching, parameter extraction, and route validation.
Start here when adding new routing features, modifying route matching logic, or changing how file-based routing works.
packages/astro/src/content/index.tsEntry point for content collections: schema validation, type generation, and the Vite plugin that powers content queries.
Start here when modifying content collections behavior, adding new collection types, or changing content schema validation.
packages/astro/src/assets/index.tsImage optimization pipeline entry point: defines image services, handles remote patterns, and coordinates sharp/squoosh transforms.
Start here when adding image format support, modifying optimization settings, or extending the asset pipeline.
packages/astro/src/core/errors/errors-data.tsDefines all Astro error codes, messages, and hints. Each error has a unique code, a message template, and optional hint text.
Start here when adding a new error type or modifying existing error messages.
packages/astro/src/core/middleware/index.tsLoads, sequences, and executes middleware functions in the request pipeline.
Start here when modifying middleware execution order, adding middleware hooks, or changing how middleware is loaded.
packages/astro/src/i18n/index.tsInternationalization routing: locale detection, URL rewriting for locales, and i18n-specific middleware.
Start here when adding i18n features, modifying locale detection, or changing internationalized routing behavior.
packages/astro/src/runtime/server/index.tsServer-side HTML rendering utilities: component rendering, slot handling, hydration script injection, and the JSX runtime.
Start here when modifying how components render to HTML, changing hydration behavior, or adding new rendering primitives.
packages/astro/src/transitions/router.tsClient-side View Transitions API router: intercepts navigation, manages page swaps, and coordinates transition animations.
Start here when modifying client-side navigation, adding transition events, or changing how page swaps work.
packages/astro/src/prefetch/index.tsLink prefetching strategies: hover, viewport intersection, and eager load prefetching of linked pages.
Start here when adding prefetch strategies or modifying when/how links are prefetched.
How to Make Changes
Common modification patterns for this codebase
Add a new Astro configuration option
packages/astro/src/@types/astro.tsAdd the new property to the AstroUserConfig interface. Include JSDoc documentation with @docs annotation following the existing pattern for properties like `prefetch` or `image`.
Pattern: See how the `prefetch` property is defined in AstroUserConfig with its JSDoc @docs block including name, type, default, version, and description fields.
packages/astro/src/core/config/schema.tsAdd Zod validation for the new option in the AstroConfigSchema. Define the type, default value, and any transforms.
Pattern: See how `prefetch` is validated with z.object().optional() and given a default value via .transform() in the same schema file.
packages/astro/src/core/config/index.tsIf the option requires special resolution logic beyond Zod defaults, add resolution logic here. Most simple options only need the schema change.
Pattern: See how image config or output config is resolved with special handling after Zod parsing.
packages/astro/src/core/errors/errors-data.tsIf the new option can produce user-facing errors, add a new error definition with a unique code, message template, and hint.
Pattern: See how ConfigNotFound or ConfigLegacyKey errors are defined with title, code, message function, and hint.
Conventions to follow:
Add a new CLI command
packages/astro/src/cli/index.tsAdd a new case to the command dispatcher switch statement that routes to your new command handler.
Pattern: See how the 'dev', 'build', 'preview', 'sync', 'check', and 'add' commands are dispatched in the switch statement, each calling a dedicated function.
packages/astro/src/cli/index.tsCreate the command handler function in the same file or a new dedicated file under packages/astro/src/cli/. The handler should accept parsed flags and the resolved config.
Pattern: See how the 'check' command is implemented: it has its own handler function that receives telemetry, flags, and resolves config before executing.
packages/astro/src/@types/astro.tsIf the command needs new types (e.g., new flags or options), add them to the appropriate interface in the types file.
Pattern: See how CLIFlags interface is defined with properties for each CLI flag.
packages/astro/src/core/errors/errors-data.tsAdd any command-specific error definitions if the command can fail in user-facing ways.
Pattern: See how existing errors like UnknownCLIError are defined with code, title, and message.
Conventions to follow:
Add a new Vite plugin to the build pipeline
packages/astro/src/vite-plugin-astro/index.tsStudy the existing main Vite plugin structure to understand how plugins export a function returning a Vite Plugin object with name, transform, resolveId, load, and configureServer hooks.
Pattern: See how packages/astro/src/vite-plugin-astro/index.ts exports a default function that returns a Vite plugin object with hooks like transform(), resolveId(), and handleHotUpdate().
packages/astro/src/vite-plugin-{your-plugin-name}/index.tsCreate a new directory and index.ts file following the naming convention packages/astro/src/vite-plugin-{name}/index.ts. Export a function that accepts AstroSettings and returns a Vite Plugin object.
Pattern: See how packages/astro/src/vite-plugin-astro-server/index.ts exports a function taking (settings, logging) and returns { name: 'astro:server', configureServer() {...} }.
packages/astro/src/core/create-vite.tsRegister your new plugin in the createVite() function by adding it to the plugins array. This is where all Astro Vite plugins are assembled.
Pattern: See how existing plugins like astroScriptsPlugin(), astroPostprocessVitePlugin(), and astroContentVirtualModPlugin() are added to the plugins array in createVite().
packages/astro/src/@types/astro.tsIf your plugin needs configuration options, add them to AstroUserConfig and any relevant internal types.
Pattern: See how image-related types are defined for the image optimization Vite plugin.
Conventions to follow:
Add a new error type
packages/astro/src/core/errors/errors-data.tsAdd a new error definition object to the appropriate section (Astro, CSS, Markdown, Content, etc.). Each error needs a unique numeric code, a title string, a message function that accepts context parameters, and an optional hint.
Pattern: See how UnknownCompilerError is defined: { code: 1000, title: 'Unknown compiler error.', message: 'Unknown compiler error.', hint: 'This is almost always a problem with the Astro compiler...' }. For dynamic messages, see InvalidGetStaticPathParam which uses message: (paramType) => `...${paramType}...`.
packages/astro/src/core/errors/errors.tsIf you need a new error class (not just a new error code), extend AstroError or AstroUserError. Most new errors only need a new entry in errors-data.ts and can use the existing AstroError class.
Pattern: See how AstroError extends Error with properties for code, title, hint, and frame. See how CompilerError extends AstroError for compiler-specific errors.
packages/astro/src/core/errors/index.tsEnsure your new error is exported from the errors barrel file so it can be imported elsewhere.
Pattern: See how this file re-exports from errors-data.ts, errors.ts, and utils.ts.
packages/astro/src/core/errors/dev/utils.tsIf the error needs special formatting in the dev overlay (e.g., code frames, custom rendering), add handling here.
Pattern: See how getErrorDataByCode() maps error codes to their data and how errors are formatted for the dev overlay.
Conventions to follow:
Add a new integration
packages/astro/src/@types/astro.tsReview the AstroIntegration interface to understand the hooks available: 'astro:config:setup', 'astro:config:done', 'astro:server:setup', 'astro:server:start', 'astro:build:start', 'astro:build:setup', 'astro:build:generated', 'astro:build:ssr', 'astro:build:done'.
Pattern: See the AstroIntegration interface definition which specifies the name property and hooks object with typed parameters for each hook.
packages/integrations/Create a new package directory under packages/integrations/ (or packages/ for major integrations). Create package.json, tsconfig.json, and src/index.ts. The index.ts should export a default function that returns an AstroIntegration object.
Pattern: See how packages/astro/src/assets/index.ts or any existing integration package exports a function returning { name: 'astro:assets', hooks: { 'astro:config:setup': ({updateConfig}) => {...} } }.
packages/astro/src/core/config/schema.tsIf the integration needs to be a built-in (like assets), register it in the config schema's integrations handling. For external integrations, users add them to their astro.config.mjs.
Pattern: See how built-in integrations are injected in the config resolution pipeline.
examples/basics/astro.config.mjsAdd an example usage of the integration to demonstrate proper configuration.
Pattern: See how examples/framework-react/astro.config.mjs imports and uses the React integration: import react from '@astrojs/react'; export default defineConfig({ integrations: [react()] }).
Conventions to follow:
Add a new client-side hydration directive
packages/astro/src/runtime/client/idle.tsStudy an existing hydration directive to understand the pattern. Each directive exports a default function that receives an element callback and options, and decides WHEN to call the callback to hydrate the component.
Pattern: See how packages/astro/src/runtime/client/idle.ts uses requestIdleCallback to defer hydration, or how packages/astro/src/runtime/client/visible.ts uses IntersectionObserver.
packages/astro/src/runtime/client/{your-directive}.tsCreate a new file that exports a default async function matching the hydration directive signature: (cb: () => Promise<void>, opts: Record<string, string>, el: HTMLElement) => void. The function should call cb() when the hydration condition is met.
Pattern: See packages/astro/src/runtime/client/media.ts which calls cb() when a media query matches: window.matchMedia(opts.value).addEventListener('change', cb, {once: true}).
packages/astro/src/runtime/server/hydration.tsRegister the new directive in the server-side hydration logic so the correct client script is injected when the directive is used on a component.
Pattern: See how existing directives like 'idle', 'load', 'visible', 'media', 'only' are mapped to their client-side script paths in the hydration module.
packages/astro/src/@types/astro.tsAdd the new directive to the relevant type definitions so TypeScript recognizes client:{your-directive} as valid syntax.
Pattern: See how client:idle, client:load, client:visible, client:media, and client:only are typed in the component props interfaces.
packages/astro/src/core/errors/errors-data.tsUpdate the list of known directives in any error messages that enumerate valid directives (e.g., InvalidComponentArgs).
Pattern: See error messages that list valid client: directives to ensure your new one is included.
Conventions to follow:
Coding Conventions
Standards and patterns used in this codebase
Monorepo structure: apps/ contains deployable applications, packages/ contains shared libraries
Packages: packages/astro, packages/create-astro, packages/upgradeFile naming uses: kebab-case
prettier.config.js, index.js, index.js, render.js, astro.config.mjsMiddleware is used for cross-cutting concerns (auth, logging, validation)
Middleware files: examples/middleware/astro.config.mjsConfiguration is centralized in config files
Config files: prettier.config.js, examples/basics/astro.config.mjsTypes are defined in dedicated type files
Type files: packages/astro/astro-jsx.d.ts, packages/astro/client.d.ts