Want astro-community/astro knowledge in your AI?

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

ReactVue.jsJestExpress.jsTailwind CSSTypeScriptVitestZod

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

CLI Entry Point
packages/astro/src/cli/index.ts

Main 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.

Astro Core Config
packages/astro/src/core/config/index.ts

Resolves 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.

Astro Type Definitions
packages/astro/src/@types/astro.ts

Central 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.

Vite Plugin Astro (Main)
packages/astro/src/vite-plugin-astro/index.ts

The 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.

Dev Server Vite Plugin
packages/astro/src/vite-plugin-astro-server/index.ts

Vite 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.

Core Build Pipeline
packages/astro/src/core/build/index.ts

Orchestrates 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.

SSR App Runtime
packages/astro/src/core/app/index.ts

The 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.

Routing Manifest
packages/astro/src/core/routing/index.ts

Creates 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.

Content Collections Entry
packages/astro/src/content/index.ts

Entry 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.

Assets / Image Pipeline
packages/astro/src/assets/index.ts

Image 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.

Error Definitions
packages/astro/src/core/errors/errors-data.ts

Defines 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.

Middleware Pipeline
packages/astro/src/core/middleware/index.ts

Loads, 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.

i18n Module
packages/astro/src/i18n/index.ts

Internationalization 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.

Server Runtime Rendering
packages/astro/src/runtime/server/index.ts

Server-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.

View Transitions Client Router
packages/astro/src/transitions/router.ts

Client-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.

Prefetch Module
packages/astro/src/prefetch/index.ts

Link 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

1
packages/astro/src/@types/astro.ts

Add 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.

2
packages/astro/src/core/config/schema.ts

Add 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.

3
packages/astro/src/core/config/index.ts

If 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.

4
packages/astro/src/core/errors/errors-data.ts

If 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:

All config options must have Zod validation in schema.ts AND TypeScript types in astro.tsJSDoc on AstroUserConfig properties uses @docs annotations that auto-generate documentationDefault values are set in the Zod schema, not in runtime codeConfig option names use camelCase in TypeScript and the user-facing config file

Add a new CLI command

1
packages/astro/src/cli/index.ts

Add 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.

2
packages/astro/src/cli/index.ts

Create 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.

3
packages/astro/src/@types/astro.ts

If 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.

4
packages/astro/src/core/errors/errors-data.ts

Add 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:

CLI commands are dispatched from the main switch in packages/astro/src/cli/index.tsEach command resolves config via the shared config resolution pipeline before executingCommands should handle telemetry events for usage trackingError handling should use AstroError from the errors module, not raw throws

Add a new Vite plugin to the build pipeline

1
packages/astro/src/vite-plugin-astro/index.ts

Study 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().

2
packages/astro/src/vite-plugin-{your-plugin-name}/index.ts

Create 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() {...} }.

3
packages/astro/src/core/create-vite.ts

Register 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().

4
packages/astro/src/@types/astro.ts

If 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:

Vite plugin names use the 'astro:' prefix (e.g., 'astro:scripts', 'astro:server')Plugin directories follow the naming pattern packages/astro/src/vite-plugin-{name}/All plugins are registered centrally in packages/astro/src/core/create-vite.tsPlugins receive AstroSettings (resolved config + metadata) not raw AstroConfigUse the enforce: 'pre' or 'post' Vite plugin option to control execution order when needed

Add a new error type

1
packages/astro/src/core/errors/errors-data.ts

Add 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}...`.

2
packages/astro/src/core/errors/errors.ts

If 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.

3
packages/astro/src/core/errors/index.ts

Ensure 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.

4
packages/astro/src/core/errors/dev/utils.ts

If 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:

Error codes are grouped by category: 1000-1999 for Astro core, 2000-2999 for CSS, 3000-3999 for Markdown, etc.Error codes must be unique and sequential within their categoryThe message property can be a string or a function that returns a string for dynamic messagesAlways include a hint when possible to help users fix the issueThrow errors using: throw new AstroError(AstroErrorData.YourNewError)

Add a new integration

1
packages/astro/src/@types/astro.ts

Review 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.

2
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}) => {...} } }.

3
packages/astro/src/core/config/schema.ts

If 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.

4
examples/basics/astro.config.mjs

Add 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:

Integration names use the format '@astrojs/{name}' for official integrations or 'astro-{name}' for communityThe default export is a factory function that accepts options and returns an AstroIntegration objectUse the 'astro:config:setup' hook to inject Vite plugins, add renderers, or modify configUse the 'astro:build:done' hook for post-build processing like generating sitemaps or manifestsIntegration hooks receive typed parameters - always destructure what you need from the hook argument

Add a new client-side hydration directive

1
packages/astro/src/runtime/client/idle.ts

Study 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.

2
packages/astro/src/runtime/client/{your-directive}.ts

Create 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}).

3
packages/astro/src/runtime/server/hydration.ts

Register 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.

4
packages/astro/src/@types/astro.ts

Add 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.

5
packages/astro/src/core/errors/errors-data.ts

Update 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:

Hydration directive files live in packages/astro/src/runtime/client/Each directive exports a single default async function with signature (cb, opts, el)The cb() callback triggers the actual component hydration - call it when your condition is metDirectives should be progressive enhancement friendly - if the API isn't available, fall back to immediate hydrationThe opts parameter contains the directive value (e.g., client:media='(max-width: 600px)' passes opts.value = '(max-width: 600px)')

Coding Conventions

Standards and patterns used in this codebase

file-organization

Monorepo structure: apps/ contains deployable applications, packages/ contains shared libraries

Packages: packages/astro, packages/create-astro, packages/upgrade
packages/astropackages/create-astro
naming

File naming uses: kebab-case

prettier.config.js, index.js, index.js, render.js, astro.config.mjs
prettier.config.jsbenchmark/index.jsscripts/index.js
middleware

Middleware is used for cross-cutting concerns (auth, logging, validation)

Middleware files: examples/middleware/astro.config.mjs
examples/middleware/astro.config.mjs
configuration

Configuration is centralized in config files

Config files: prettier.config.js, examples/basics/astro.config.mjs
prettier.config.jsexamples/basics/astro.config.mjsexamples/blog/astro.config.mjs
typescript

Types are defined in dedicated type files

Type files: packages/astro/astro-jsx.d.ts, packages/astro/client.d.ts
packages/astro/astro-jsx.d.tspackages/astro/client.d.tspackages/astro/config.d.ts