# Astro — Administrator & Developer Guide

Astro is a modern web framework purpose-built for content-driven websites. Its defining characteristic is zero JavaScript shipped to the client by default — a philosophy enforced by its **Islands Architecture**, where interactive components are explicitly opted into client-side hydration. The framework is distributed as a TypeScript monorepo with over 6,100 files, maintained by the `withastro` organization and built around a core package (`packages/astro/`) surrounded by official integrations, language tooling, and shared utilities.

This guide covers architecture, configuration, deployment, security, and internals for administrators, platform engineers, and contributors working at the framework level.

---

## 1. Architecture Overview

### 1.1 High-Level Request Pipeline

Astro's runtime is structured as a layered pipeline that handles both development and production requests through a common abstract base, then specializes at the edges.

```
CLI (yargs-parser)
    │
    ▼
Config Resolution (Zod v4 validation)
    │
    ▼
Vite Dev Server  ─────────────────────────  Build (AppPipeline)
    │                                              │
    ▼                                              ▼
DevPipeline                               AppPipeline
    │                                              │
    └──────────────┬────────────────────────────── ┘
                   ▼
           RenderContext (per-request)
           ├── Middleware chain (sequence())
           ├── Actions (defineAction)
           ├── Sessions (driver-based)
           ├── Cache (provider-based)
           └── Routing (file-based + redirects)
```

The `Pipeline` abstract class in `packages/astro/src/core/base-pipeline.ts` defines this contract. `AppPipeline` in `packages/astro/src/core/app/pipeline.ts` is the production implementation. During development, an equivalent dev pipeline is used; they share the same `RenderContext` instantiation and middleware sequencing logic.

> [!IMPORTANT]
> The `output: "hybrid"` mode was removed in a prior major release. The only valid values for `output` are `"static"` (default) and `"server"`. Any configuration referencing `"hybrid"` must be migrated before upgrading.

### 1.2 Class Hierarchy

```
Pipeline (abstract)
└── AppPipeline

BaseApp
└── App
    └── NodeApp

AstroError (extends Error)
├── CompilerError
├── CSSError
├── MarkdownError
├── InternalError
└── AggregateError

AstroUserError (extends Error — separate hierarchy)
MarkdocError (extends Error)
BodySizeLimitError (extends Error)

AstroTelemetry
GlobalConfig
AstroCheck
RouteCache
NodePool
HTMLStringCache
RenderContext
```

`NodeApp` in `packages/astro/src/core/app/node.ts` extends `App` with Node.js-specific adapter helpers, including `BodySizeLimitError` handling for oversized request bodies.

### 1.3 Vite Environment Model

Astro uses Vite as its build and dev-server foundation, and defines four named Vite environments:

| Environment | When Used | Purpose |
|-------------|-----------|---------|
| `ssr` | Build and dev | Server-side rendering of pages and endpoints |
| `client` | Build | Client-side JavaScript bundles shipped to browsers |
| `astro` | Dev only | Runnable environment for the Astro dev process itself |
| `prerender` | Build | Static page rendering during the production build |

These are defined in `packages/astro/src/core/constants.ts` alongside `ASTRO_VERSION`, redirect status codes, middleware symbols, and Vite environment name constants.

> [!NOTE]
> The `astro` Vite environment is a development-only concept. Production builds only use `ssr`, `client`, and `prerender`. Tooling that introspects Vite environments should handle the absence of the `astro` environment in production builds gracefully.

### 1.4 Monorepo Structure

The repository is a pnpm workspace managed by Turborepo:

```
withastro/astro/
├── packages/
│   ├── astro/                  # Core framework
│   │   ├── src/
│   │   │   ├── cli/            # CLI commands (yargs-parser dispatch)
│   │   │   ├── core/           # Pipeline, config, errors, routing
│   │   │   ├── actions/        # Server actions runtime (defineAction)
│   │   │   ├── assets/         # Image optimization, fonts, SVG (50K+ chars)
│   │   │   ├── config/         # Config loading and resolution
│   │   │   ├── env/            # astro:env module
│   │   │   ├── i18n/           # Internationalization
│   │   │   ├── runtime/        # Client/server runtime, dev toolbar
│   │   │   └── types/          # Public TypeScript types
│   │   ├── components/         # Built-in components (Code, Debug)
│   │   └── test/               # Test fixtures (hundreds)
│   ├── integrations/           # Official integrations (node, vercel, cloudflare, etc.)
│   ├── language-tools/         # VS Code extension, LSP, TS plugin, astro-check
│   ├── create-astro/           # Project scaffolding CLI
│   ├── astro-rss/              # RSS feed generation
│   ├── astro-prism/            # Prism syntax highlighting
│   ├── markdown/               # Markdown processing
│   ├── telemetry/              # Anonymous usage tracking
│   ├── internal-helpers/       # Shared utilities (fs, path, etc.)
│   ├── underscore-redirects/   # _redirects file generation for Netlify/Cloudflare
│   ├── upgrade/                # Version upgrade CLI
│   └── db/                     # Astro DB (CLI + core)
├── examples/                   # Starter templates
├── benchmark/                  # Performance benchmarks
├── scripts/                    # Build/test scripts
└── .changeset/                 # Changeset versioning
```

### 1.5 Key Source Modules Reference

| Module | Path | Purpose |
|--------|------|---------|
| CLI Entry | `packages/astro/src/cli/index.ts` | Command dispatch (yargs-parser), lazy imports |
| Config Schema | `packages/astro/src/core/config/schemas/base.ts` | Zod v4 schema, `ASTRO_CONFIG_DEFAULTS` |
| Base Pipeline | `packages/astro/src/core/base-pipeline.ts` | Abstract `Pipeline` class — middleware, actions, sessions, cache, server islands, routing |
| App Pipeline | `packages/astro/src/core/app/pipeline.ts` | Production pipeline (`AppPipeline extends Pipeline`) |
| App | `packages/astro/src/core/app/app.ts` | `App extends BaseApp` — production request handler |
| NodeApp | `packages/astro/src/core/app/node.ts` | `NodeApp extends App` — Node.js adapter helpers |
| RenderContext | `packages/astro/src/core/render-context.ts` | Per-request rendering context |
| Middleware | `packages/astro/src/core/middleware/` | `sequence()`, noop middleware, handler types |
| Errors | `packages/astro/src/core/errors/` | All error classes |
| Error Overlay | `packages/astro/src/core/errors/overlay.ts` | Dev error overlay (shadow DOM, dark/light theme) |
| Constants | `packages/astro/src/core/constants.ts` | `ASTRO_VERSION`, redirect codes, middleware symbols |
| Vite Setup | `packages/astro/src/core/create-vite.ts` | Vite config creation |
| Actions Runtime | `packages/astro/src/actions/runtime/server.ts` | `defineAction()`, `ActionError`, `ActionInputError` |
| Image Utils | `packages/astro/src/assets/utils/` | 17 files — SVG handling, image transforms, responsive images |
| Font System | `packages/astro/src/assets/fonts/` | Font optimization, format detection, CSS generation |
| Events/Telemetry | `packages/astro/src/events/` | Telemetry event tracking |
| Telemetry | `packages/telemetry/src/` | `AstroTelemetry` class, `GlobalConfig` for persistent settings |
| Language Server | `packages/language-tools/language-server/src/` | LSP for `.astro` files |
| Astro Check | `packages/language-tools/astro-check/src/` | CLI diagnostics tool |
| TS Plugin | `packages/language-tools/ts-plugin/src/` | TypeScript language service plugin |
| VS Code Extension | `packages/language-tools/vscode/src/` | VS Code extension entry |
| RSS | `packages/astro-rss/src/` | RSS feed generation |
| Prism | `packages/astro-prism/src/` | Prism syntax highlighting |
| Underscore Redirects | `packages/underscore-redirects/src/` | `_redirects` file generation for Netlify/Cloudflare |
| Internal Helpers | `packages/internal-helpers/src/` | 6 files — shared utilities (fs, path, etc.) |
| Create Astro | `packages/create-astro/src/` | Project scaffolding wizard |

### 1.6 Islands Architecture

The Islands Architecture is the conceptual core of Astro. Each page renders as static HTML by default; interactive UI components are explicit "islands" that get hydrated on the client. Hydration is controlled via `client:*` directives (`client:load`, `client:idle`, `client:visible`, `client:media`, `client:only`). This model means:

- The baseline is zero JavaScript delivered to the browser
- Each island is independently hydrated
- Server-rendered HTML is complete before any JS loads
- Multiple UI framework renderers can coexist on a single page

> [!TIP]
> Islands Architecture is most impactful on content-heavy sites. For highly interactive applications, the zero-JS-by-default model still applies, but islands may cover most of the page. Evaluate whether Astro's model fits the application's interactivity profile before committing.

### 1.7 Middleware and Actions Architecture

Middleware in Astro is composed via the `sequence()` utility, which chains middleware functions in order. Each middleware receives the request context and a `next` function. The middleware chain is resolved by `RenderContext` per request.

Server Actions, defined with `defineAction()` in `packages/astro/src/actions/runtime/server.ts`, provide a type-safe RPC layer callable from client components. Actions can throw `ActionError` (general) or `ActionInputError` (validation failure). The action body size is limited by `security.actionBodySizeLimit` (default 1MB).

---

## 2. System Requirements

### 2.1 Runtime Requirements

| Component | Minimum Version | Notes |
|-----------|----------------|-------|
| Node.js | 22.12.0 | Enforced at runtime; earlier versions are unsupported |
| pnpm | 10.30.3 | Required for monorepo development; enforced via `preinstall` hook and `only-allow` |
| TypeScript | ~5.9.3 | Bundled; projects may use any compatible version |

> [!WARNING]
> The Node.js minimum is 22.12.0. This is enforced in the monorepo build tooling. Adapter-deployed serverless environments must also meet this requirement — Vercel, Netlify, and Cloudflare Workers all support Node.js 22, but verify the specific runtime version in your platform's settings before deploying.

### 2.2 Development Tooling

| Tool | Purpose |
|------|---------|
| Turborepo (`turbo`) | Monorepo task orchestration and caching |
| Vitest | Unit and integration testing |
| Playwright | End-to-end testing (Firefox) |
| Biome | Linting and formatting (primary) |
| ESLint | Secondary linting |
| Prettier | Secondary formatting |
| Changesets | Versioning and changelog management |
| esbuild | Package bundling |
| `astro-scripts` | Internal build scripts |
| `knip` | Dead code detection |

### 2.3 Optional Runtime Dependencies

| Feature | Dependency | Notes |
|---------|-----------|-------|
| Image optimization | `sharp` | Default image service; required for `<Image>` transforms in SSR/SSG |
| MDX support | `@astrojs/mdx` | Official integration |
| Markdoc support | `@astrojs/markdoc` | Official integration |
| SVGO optimization | Configured via `experimental.svgo` | Only when flag enabled |

---

## 3. Configuration Reference

### 3.1 Configuration File

Astro loads configuration from `astro.config.mjs` (or `.ts`, `.js`, `.cjs`) at the project root. The schema is defined as a Zod v4 schema in `packages/astro/src/core/config/schemas/base.ts` with explicit defaults tracked in `ASTRO_CONFIG_DEFAULTS`.

A minimal configuration:

```javascript
// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  site: 'https://example.com',
  output: 'static',
});
```

A server-rendered configuration with adapter:

```javascript
// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});
```

### 3.2 Top-Level Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `root` | `string` | `'.'` | Project root directory |
| `srcDir` | `string` | `'./src'` | Source directory |
| `publicDir` | `string` | `'./public'` | Static assets directory |
| `outDir` | `string` | `'./dist'` | Build output directory |
| `cacheDir` | `string` | `'./node_modules/.astro'` | Cache directory |
| `site` | `string` (URL) | — | Fully-qualified deployed site URL; used for canonical URLs and sitemaps |
| `base` | `string` | `'/'` | Base path when deploying to a subdirectory |
| `trailingSlash` | `'always' \| 'never' \| 'ignore'` | `'ignore'` | Trailing slash enforcement on routes |
| `output` | `'static' \| 'server'` | `'static'` | Output mode; `'hybrid'` was removed |
| `compressHTML` | `boolean` | `true` | Minify HTML output during build |
| `scopedStyleStrategy` | `'where' \| 'class' \| 'attribute'` | `'attribute'` | Strategy for scoping component styles |
| `adapter` | `object` | — | SSR adapter (required when `output: 'server'`) |
| `integrations` | `array` | `[]` | Integration list |
| `vite` | `object` | `{}` | Vite configuration overrides |
| `redirects` | `Record<string, string \| {status, destination}>` | `{}` | URL redirect rules |
| `prerenderConflictBehavior` | `'error' \| 'warn' \| 'ignore'` | `'warn'` | Behavior when prerendering conflicts are detected |

### 3.3 Build Options (`build.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `build.format` | `'file' \| 'directory' \| 'preserve'` | `'directory'` | Output file organization format |
| `build.client` | `string` | `'./client/'` | Client-side assets output directory |
| `build.server` | `string` | `'./server/'` | Server-side output directory |
| `build.assets` | `string` | `'_astro'` | Sub-directory for generated asset files |
| `build.assetsPrefix` | `string \| {fallback: string, ...}` | — | CDN prefix for asset URLs |
| `build.serverEntry` | `string` | `'entry.mjs'` | Server entry point filename |
| `build.redirects` | `boolean` | `true` | Generate redirect files during build |
| `build.inlineStylesheets` | `'always' \| 'auto' \| 'never'` | `'auto'` | Control stylesheet inlining |
| `build.concurrency` | `number (≥1)` | `1` | Number of pages to build concurrently |

> [!TIP]
> Increasing `build.concurrency` can significantly reduce build time for large sites. Start with `4` and adjust based on available CPU cores. High values may cause memory pressure on resource-constrained build machines.

### 3.4 Server Options (`server.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `server.host` | `string \| boolean` | `false` | Dev server host binding; `true` binds to `0.0.0.0` |
| `server.port` | `number` | `4321` | Dev server port |
| `server.open` | `string \| boolean` | `false` | Open browser on dev server start |
| `server.headers` | `OutgoingHttpHeaders` | — | Custom HTTP headers served by dev server |
| `server.allowedHosts` | `string[] \| true` | `[]` | Hostnames allowed to access the dev server |

### 3.5 Image Options (`image.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `image.service.entrypoint` | `string` | `'astro/assets/services/sharp'` | Image optimization service module |
| `image.service.config` | `Record` | `{}` | Image service configuration |
| `image.endpoint.route` | `string` | `'/_image'` | Route for the image optimization endpoint |
| `image.endpoint.entrypoint` | `string` | — | Custom image endpoint module |
| `image.domains` | `string[]` | `[]` | Allowed external image domains |
| `image.remotePatterns` | `array` | `[]` | Allowed remote image URL patterns |
| `image.layout` | `'constrained' \| 'fixed' \| 'full-width' \| 'none'` | — | Default image layout |
| `image.objectFit` | `string` | — | Default CSS object-fit for images |
| `image.objectPosition` | `string` | — | Default CSS object-position for images |
| `image.breakpoints` | `number[]` | — | Responsive image breakpoints |
| `image.responsiveStyles` | `boolean` | `false` | Auto-inject responsive CSS styles |

Remote image patterns support these fields:

```javascript
// astro.config.mjs
export default defineConfig({
  image: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
        port: '',
        pathname: '/images/**',
      },
    ],
  },
});
```

> [!CAUTION]
> Allowing overly broad remote patterns (e.g., `hostname: '**'`) effectively disables remote image restrictions. Always scope `remotePatterns` to the domains you control or trust. Unrestricted patterns allow arbitrary third-party images to be proxied and processed by your image service.

### 3.6 Markdown Options (`markdown.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `markdown.syntaxHighlight` | `{type: 'shiki'\|'prism', excludeLangs?} \| false` | `{type: 'shiki'}` | Syntax highlighting engine |
| `markdown.shikiConfig.theme` | `string` | (bundled default) | Shiki theme name |
| `markdown.shikiConfig.themes` | `Record` | `{}` | Multiple themes (light/dark) |
| `markdown.shikiConfig.langs` | `array` | `[]` | Additional Shiki language grammars |
| `markdown.shikiConfig.langAlias` | `Record` | `{}` | Language name aliases |
| `markdown.shikiConfig.wrap` | `boolean \| null` | — | Code block line wrapping |
| `markdown.shikiConfig.transformers` | `array` | `[]` | Shiki transformer plugins |
| `markdown.shikiConfig.defaultColor` | `'light' \| 'dark' \| string \| false` | — | Default color scheme for dual-theme mode |
| `markdown.remarkPlugins` | `array` | `[]` | Remark plugin list |
| `markdown.rehypePlugins` | `array` | `[]` | Rehype plugin list |
| `markdown.remarkRehype` | `object` | (defaults) | Options passed to remark-rehype |
| `markdown.gfm` | `boolean` | `true` | GitHub Flavored Markdown support |
| `markdown.smartypants` | `boolean \| object` | (defaults) | Smart typography (quotes, dashes) |

### 3.7 Security Options (`security.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `security.checkOrigin` | `boolean` | `true` | Validate `Origin` header on form submissions and actions (CSRF protection) |
| `security.allowedDomains` | `array of {hostname?, protocol?, port?}` | `[]` | Domains permitted beyond same-origin |
| `security.actionBodySizeLimit` | `number` | `1048576` (1MB) | Maximum request body size for server actions |
| `security.serverIslandBodySizeLimit` | `number` | `1048576` (1MB) | Maximum request body size for server islands |
| `security.csp` | `boolean \| {algorithm, directives?, styleDirective?, scriptDirective?}` | `false` | Content Security Policy configuration |

### 3.8 Internationalization Options (`i18n`)

The `i18n` block is optional. When present, `defaultLocale` and `locales` are required.

| Option | Type | Description |
|--------|------|-------------|
| `i18n.defaultLocale` | `string` | Default locale code (e.g., `'en'`) |
| `i18n.locales` | `array of string \| {path, codes}` | Supported locales |
| `i18n.domains` | `Record<string, URL>` | Per-locale domain mapping |
| `i18n.fallback` | `Record<string, string>` | Fallback locale chain |
| `i18n.routing` | `'manual' \| {prefixDefaultLocale?, redirectToDefaultLocale?, fallbackType?}` | Routing strategy |

```javascript
// astro.config.mjs — multilingual site example
export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr', { path: 'pt', codes: ['pt', 'pt-BR'] }],
    routing: {
      prefixDefaultLocale: false,
      redirectToDefaultLocale: true,
    },
    fallback: {
      fr: 'en',
    },
  },
});
```

### 3.9 Environment Variable Schema (`env.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `env.schema` | `object` | `{}` | Type-safe environment variable declarations |
| `env.validateSecrets` | `boolean` | `false` | Validate secret env vars at build time |

### 3.10 Prefetch Options (`prefetch`)

| Option | Type | Description |
|--------|------|-------------|
| `prefetch` | `boolean \| {prefetchAll?, defaultStrategy?}` | Enable prefetching; `true` enables with defaults |
| `prefetch.defaultStrategy` | `'tap' \| 'hover' \| 'viewport' \| 'load'` | When to prefetch links |

### 3.11 Dev Toolbar Options (`devToolbar.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `devToolbar.enabled` | `boolean` | `true` | Show the dev toolbar during development |
| `devToolbar.placement` | `'bottom-left' \| 'bottom-center' \| 'bottom-right'` | — | Toolbar screen position |

### 3.12 Font Options (`fonts`)

The `fonts` option accepts an array of `FontFamilySchema` objects for built-in font optimization. This connects to the font system in `packages/astro/src/assets/fonts/`, which handles format detection, CSS generation, and serving optimized font files.

### 3.13 Session Options (`session`)

The optional `session` block configures server-side session storage using a driver-based architecture. When using the Node.js adapter with no driver configured, filesystem sessions are auto-enabled.

### 3.14 Legacy Options (`legacy.*`)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `legacy.collectionsBackwardsCompat` | `boolean` | `false` | Enable backwards-compatible content collections behavior |

### 3.15 Experimental Options (`experimental.*`)

These flags are subject to change or removal. Do not rely on them in production without evaluating stability.

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `experimental.clientPrerender` | `boolean` | `false` | Enable Speculation Rules API for client-side prerendering |
| `experimental.contentIntellisense` | `boolean` | `false` | Enhanced content collection IntelliSense in VS Code |
| `experimental.chromeDevtoolsWorkspace` | `boolean` | `false` | Chrome DevTools workspace integration |
| `experimental.svgo` | `boolean \| SvgoConfig` | `false` | SVGO optimization for SVG assets |
| `experimental.cache` | `CacheSchema` | — | Response caching configuration |
| `experimental.routeRules` | `RouteRulesSchema` | — | Per-route configuration rules |
| `experimental.rustCompiler` | `boolean` | `false` | Use the Rust-based Astro compiler |
| `experimental.queuedRendering` | `{enabled?, poolSize?, contentCache?}` | `{enabled: false}` | Queued rendering via `NodePool` |

> [!NOTE]
> `experimental.queuedRendering` uses the `NodePool` class to manage concurrent rendering workers. The `poolSize` option controls parallelism. `contentCache` enables the `HTMLStringCache` for caching rendered HTML strings between requests.

---

## 4. Deployment & Scaling

### 4.1 Deployment Modes

Astro supports two fundamental output modes:

| Mode | Config | Use Case |
|------|--------|----------|
| `static` | `output: 'static'` | Pre-rendered HTML; host anywhere (CDN, object storage, static host) |
| `server` | `output: 'server'` + adapter | On-demand SSR; requires a runtime environment |

Static output produces a complete `dist/` directory deployable to any CDN or static host without server infrastructure.

Server output requires an adapter that produces a deployable artifact for the target platform.

### 4.2 Node.js Adapter (`@astrojs/node`)

The Node.js adapter supports two modes, and the `mode` option is **required** — omitting it throws an `AstroError`.

```javascript
// astro.config.mjs — standalone mode
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});
```

```javascript
// astro.config.mjs — middleware mode (Express/Fastify compatible)
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'middleware' }),
});
```

**Standalone mode**: Includes a built-in HTTP server. Run the output with `node ./dist/server/entry.mjs`.

**Middleware mode**: Exports an Express/Fastify-compatible middleware function. Integrate it into an existing Node.js server.

#### Node Adapter Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `mode` | `'standalone' \| 'middleware'` | **Required** | Deployment mode |
| `bodySizeLimit` | `number` | 1GB | Maximum request body size |
| `staticHeaders` | `object` | — | HTTP headers injected for static file responses |
| `experimentalDisableStreaming` | `boolean` | — | Disable response streaming |

#### Node Adapter Environment Variables

| Variable | Purpose |
|----------|---------|
| `ASTRO_NODE_AUTOSTART` | Auto-start the server in standalone mode |
| `ASTRO_NODE_LOGGING` | Control logging verbosity |
| `HOST` | Override the server host |
| `PORT` | Override the server port |
| `SERVER_CERT_PATH` | Path to TLS certificate for HTTPS |
| `SERVER_KEY_PATH` | Path to TLS private key for HTTPS |

HTTPS is enabled automatically when both `SERVER_CERT_PATH` and `SERVER_KEY_PATH` are set.

### 4.3 Vercel Adapter (`@astrojs/vercel`)

The Vercel adapter deploys to Vercel's serverless or edge runtime.

```javascript
// astro.config.mjs
import vercel from '@astrojs/vercel';

export default defineConfig({
  output: 'server',
  adapter: vercel(),
});
```

**Key capabilities:**

- **ISR (Incremental Static Regeneration)**: Combine static generation with on-demand revalidation
- **Skew Protection**: When `VERCEL_SKEW_PROTECTION_ENABLED` is set, the adapter syncs deployment identifiers
- **`maxDuration`**: Configure maximum function execution time (must be a positive number)
- `VercelBuilder` class handles the build configuration and output format expected by Vercel's build system

#### Vercel Environment Variables

| Variable | Purpose |
|----------|---------|
| `VERCEL_DEPLOYMENT_ID` | Vercel deployment identifier (auto-set by Vercel) |
| `VERCEL_SKEW_PROTECTION_ENABLED` | Enable deployment skew protection (auto-set by Vercel) |

### 4.4 Cloudflare Adapter (`@astrojs/cloudflare`)

The Cloudflare adapter targets Cloudflare Workers and Cloudflare Pages.

```javascript
// astro.config.mjs
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare(),
});
```

**Key capabilities:**

- Cloudflare Workers and Pages deployment
- Durable Objects support
- Custom entry file configuration
- Image service options for Cloudflare Images

#### Cloudflare Environment Variables

| Variable | Purpose |
|----------|---------|
| `CLOUDFLARE_VITE_BUILD` | Signal that a Cloudflare Vite build is occurring |

> [!WARNING]
> Cloudflare Workers have runtime constraints that differ from Node.js. The `nodejs_compat` compatibility flag must be enabled in your Cloudflare configuration when using Node.js-compatible APIs. A known issue (#16291) affects CSS nesting in the Cloudflare dev server — test in production preview environments when CSS nesting is used.

### 4.5 Netlify Adapter (`@astrojs/netlify`)

```javascript
// astro.config.mjs
import netlify from '@astrojs/netlify';

export default defineConfig({
  output: 'server',
  adapter: netlify(),
});
```

**Key capabilities:**

- Automatic `_redirects` file generation via `packages/underscore-redirects/`
- Netlify Functions deployment

**Known limitations:**

- `context.rewrite()` is not available in the Netlify adapter
- `Astro.url` and `Astro.cookies` have compatibility considerations in certain contexts

#### Netlify Environment Variables

| Variable | Purpose |
|----------|---------|
| `DEPLOY_ID` | Netlify deploy identifier (auto-set by Netlify) |
| `NETLIFY` | Netlify environment detection flag |
| `NETLIFY_LOCAL` | Local Netlify dev detection |
| `NETLIFY_DEV` | Netlify dev server detection |

### 4.6 Static Deployment

For `output: 'static'`, the build output in `outDir` (default `./dist`) is a complete set of static files deployable to any host:

```bash
# Build for static deployment
astro build

# dist/ can be deployed to:
# - GitHub Pages
# - Netlify (static)
# - Vercel (static)
# - Cloudflare Pages (static)
# - S3 + CloudFront
# - Any nginx/Apache host
```

Use `build.assetsPrefix` to point asset URLs at a CDN:

```javascript
export default defineConfig({
  build: {
    assetsPrefix: 'https://cdn.example.com',
  },
});
```

### 4.7 Concurrency and Scaling

For high-traffic SSR deployments, horizontal scaling at the load balancer level is the primary mechanism. The adapter handles individual requests; Astro itself does not manage process pools in standard deployments.

For build-time scaling, `build.concurrency` controls parallel page rendering. The `experimental.queuedRendering` feature provides a `NodePool`-based worker pool for controlled concurrency within a single process, with `poolSize` setting the pool size and `contentCache` enabling `HTMLStringCache` for repeated content.

---

## 5. Operations

### 5.1 Environment Variables Reference

| Variable | Source Module | Purpose |
|----------|--------------|---------|
| `ASTRO_TIMER_PATH` | `core/config/timer.ts` | Timer output path for build profiling |
| `ASTRO_NODE_AUTOSTART` | `node/preview.ts` | Auto-start Node adapter server |
| `ASTRO_NODE_LOGGING` | `node/standalone.ts` | Node adapter logging control |
| `HOST` | `node/preview.ts` | Node adapter server host override |
| `PORT` | `node/standalone.ts` | Node adapter server port override |
| `SERVER_CERT_PATH` | `node/standalone.ts` | HTTPS certificate file path |
| `SERVER_KEY_PATH` | `node/standalone.ts` | HTTPS private key file path |
| `VERCEL_DEPLOYMENT_ID` | `vercel/index.ts` | Vercel deployment ID |
| `VERCEL_SKEW_PROTECTION_ENABLED` | `vercel/index.ts` | Vercel skew protection activation |
| `DEPLOY_ID` | `netlify/index.ts` | Netlify deploy ID |
| `NETLIFY` | `netlify/index.ts` | Netlify environment detection |
| `NETLIFY_LOCAL` | `netlify/index.ts` | Local Netlify dev detection |
| `NETLIFY_DEV` | `netlify/index.ts` | Netlify dev server detection |
| `CLOUDFLARE_VITE_BUILD` | `cloudflare/index.ts` | Cloudflare build flag |
| `NODE_ENV` | various | Runtime environment (`development`/`production`) |
| `CI` | `scripts/cmd/test.js` | CI environment detection |

### 5.2 Monitoring and Health

Astro does not include built-in health check endpoints. For SSR deployments, implement health checks at the adapter layer:

- **Node standalone**: Add a health check route to your server configuration
- **Vercel/Netlify/Cloudflare**: Use platform-native health monitoring
- **All platforms**: Monitor the `/` route or a dedicated `/health` endpoint added to your Astro project

### 5.3 Telemetry

Astro collects anonymous usage telemetry via `packages/telemetry/`. The `AstroTelemetry` class sends anonymized events about command usage, configuration choices, and build outcomes. Persistent telemetry preferences are stored by `GlobalConfig`.

Telemetry can be disabled:

```bash
# Disable telemetry
astro telemetry disable

# Enable telemetry
astro telemetry enable

# Check telemetry status
astro telemetry status
```

No personally identifiable information is collected. The telemetry system tracks aggregate patterns to inform framework development priorities.

### 5.4 Dev Error Overlay

During development, errors surface through the dev error overlay defined in `packages/astro/src/core/errors/overlay.ts`. The overlay renders in a shadow DOM to prevent style conflicts and supports both dark and light themes. It displays:

- Error class and message
- Stack trace with source file links
- Hint for known error patterns

Errors shown in the overlay correspond to the error class hierarchy — `AstroError`, `CompilerError`, `CSSError`, `MarkdownError`, `InternalError`, `AggregateError` — with user-facing errors (`AstroUserError`) rendered with actionable messaging.

### 5.5 Cache Directory

Astro uses `./node_modules/.astro` as its default cache directory (`cacheDir`). This cache stores compiled component artifacts, type generation outputs, and build intermediates.

To clear the cache:

```bash
rm -rf ./node_modules/.astro
```

> [!NOTE]
> CI environments should cache `./node_modules/.astro` between runs to avoid redundant compilation. Include the cache key in your CI hash along with `pnpm-lock.yaml` and `astro.config.*` to invalidate appropriately when config changes.

### 5.6 Logging

Astro's logging is managed per-command and surfaces to stdout/stderr. The `ASTRO_NODE_LOGGING` environment variable controls log verbosity for the Node adapter. Production deployments should configure platform-native log aggregation (e.g., Vercel Log Drains, Netlify Log Streams, Cloudflare Workers Logpush).

---

## 6. Performance

### 6.1 Build Performance

**Increase build concurrency:**

```javascript
// astro.config.mjs
export default defineConfig({
  build: {
    concurrency: 4, // parallelize page rendering
  },
});
```

**Inline stylesheets aggressively:**

```javascript
export default defineConfig({
  build: {
    inlineStylesheets: 'always', // eliminates render-blocking CSS requests
  },
});
```

**Use CDN for assets:**

```javascript
export default defineConfig({
  build: {
    assetsPrefix: 'https://cdn.example.com',
  },
});
```

**Cache the Astro cache directory** in CI with a key based on `pnpm-lock.yaml` + `astro.config.*`.

### 6.2 Image Performance

The `sharp`-based image service (`astro/assets/services/sharp`) is the default and provides the best throughput. Configuration options in `image.service.config` are passed directly to sharp.

Responsive images via `image.responsiveStyles: true` auto-inject CSS for responsive layouts. Define `image.breakpoints` to control the set of generated sizes:

```javascript
export default defineConfig({
  image: {
    breakpoints: [320, 640, 768, 1024, 1280, 1920],
    responsiveStyles: true,
    layout: 'constrained',
  },
});
```

For SSR deployments, image transforms are computed on-demand at `/_image` (configurable via `image.endpoint.route`). High-traffic deployments should place a CDN in front of this endpoint and cache transformed images by URL.

### 6.3 JavaScript Bundle Performance

Astro's Islands Architecture inherently minimizes client JavaScript. Additional practices:

- Use `client:visible` instead of `client:load` for below-the-fold islands — they hydrate only when entering the viewport
- Use `client:idle` for non-critical islands to defer hydration until the main thread is idle
- Use `client:only` only when server rendering is impossible (third-party widgets, browser-only APIs)
- Prefer static components for content-only sections

### 6.4 HTML Performance

HTML compression is on by default (`compressHTML: true`). The HTML minification reduces whitespace in the rendered output. For content-heavy sites with large HTML payloads, this yields measurable transfer size reductions.

`build.inlineStylesheets: 'auto'` (the default) inlines small stylesheets and externalizes large ones. Tune with `'always'` or `'never'` based on profiling.

### 6.5 Prefetching

Prefetching reduces perceived navigation latency for multi-page sites:

```javascript
export default defineConfig({
  prefetch: {
    prefetchAll: true,        // prefetch all internal links
    defaultStrategy: 'hover', // prefetch on hover
  },
});
```

Strategy options and their behavior:

| Strategy | Trigger |
|----------|---------|
| `tap` | Prefetch on pointer down (minimal delay) |
| `hover` | Prefetch when hovering over a link |
| `viewport` | Prefetch links as they enter the viewport |
| `load` | Prefetch all eligible links on page load |

> [!TIP]
> `'viewport'` strategy is ideal for paginated content or listicles where the next page link is visible before the user clicks. `'hover'` balances bandwidth with responsiveness for most content sites.

### 6.6 Queued Rendering (Experimental)

```javascript
export default defineConfig({
  experimental: {
    queuedRendering: {
      enabled: true,
      poolSize: 4,
      contentCache: true,
    },
  },
});
```

When enabled, server-side rendering is handled by a `NodePool` of workers. `contentCache: true` activates `HTMLStringCache` to cache rendered HTML strings for repeated identical requests. This is a significant architectural change — evaluate with load testing before enabling in production.

### 6.7 Build Profiling

Set `ASTRO_TIMER_PATH` to a file path to capture build timing data:

```bash
ASTRO_TIMER_PATH=./build-timings.json astro build
```

The timer output can identify slow routes, modules, or integrations contributing to build time.

---

## 7. Security

### 7.1 CSRF Protection

Origin checking is enabled by default via `security.checkOrigin: true`. This validates the `Origin` request header on form submissions and server action calls, preventing cross-site request forgery. The validation is handled in the middleware chain during request processing.

To allow cross-origin requests from trusted domains:

```javascript
export default defineConfig({
  security: {
    checkOrigin: true,
    allowedDomains: [
      { hostname: 'trusted-partner.com', protocol: 'https' },
    ],
  },
});
```

> [!IMPORTANT]
> Never set `security.checkOrigin: false` in production SSR deployments unless you have an alternative CSRF mitigation. The origin check is a primary defense for server actions and form handlers against cross-site forgery attacks.

### 7.2 Content Security Policy

CSP is supported natively via `security.csp`:

```javascript
export default defineConfig({
  security: {
    csp: {
      algorithm: 'sha256',
      directives: {
        'default-src': ["'self'"],
        'img-src': ["'self'", 'data:', 'https:'],
      },
      scriptDirective: {
        // Hashes are auto-generated for inline scripts
      },
      styleDirective: {
        // Hashes are auto-generated for inline styles
      },
    },
  },
});
```

When CSP is configured with `algorithm`, Astro automatically generates content hashes for inline scripts and styles, eliminating the need for `'unsafe-inline'` in most cases.

### 7.3 Body Size Limits

Two separate body size limits protect against large payload attacks:

```javascript
export default defineConfig({
  security: {
    actionBodySizeLimit: 1048576,       // 1MB — server actions
    serverIslandBodySizeLimit: 1048576, // 1MB — server islands
  },
});
```

The Node adapter has a separate `bodySizeLimit` option (default 1GB) at the HTTP layer, applied before Astro's routing. When `BodySizeLimitError` is thrown (from `NodeApp`), it surfaces as a 413 Payload Too Large response.

### 7.4 HTTPS in Node Adapter

Configure HTTPS via environment variables:

```bash
export SERVER_CERT_PATH=/path/to/cert.pem
export SERVER_KEY_PATH=/path/to/key.pem
node ./dist/server/entry.mjs
```

When both variables are set, the standalone Node server binds to HTTPS automatically.

### 7.5 Static File Headers

The Node adapter's `staticHeaders` option injects HTTP headers for static file responses. Use this to add security headers to static assets without a reverse proxy:

```javascript
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'standalone',
    staticHeaders: {
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
    },
  }),
});
```

### 7.6 Remote Image Security

Untrusted remote images processed by the image optimization service represent an SSRF risk. Restrict allowed origins:

```javascript
export default defineConfig({
  image: {
    domains: ['images.example.com'],
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.trusted-cdn.com',
      },
    ],
  },
});
```

Any image URL not matching `domains` or `remotePatterns` is rejected by the image endpoint.

### 7.7 Server Island Security

Server islands — dynamic components rendered server-side within otherwise static pages — accept POST requests with component state. The `security.serverIslandBodySizeLimit` cap prevents oversized payloads. The origin check (`security.checkOrigin`) applies to server island requests.

### 7.8 Actions Security

Server actions defined with `defineAction()` are accessible via POST requests. Security layers:

- Origin validation (when `security.checkOrigin: true`)
- Body size capped at `security.actionBodySizeLimit`
- Input validation via Zod schemas (throws `ActionInputError` on schema violations)
- Error handling via `ActionError` with explicit HTTP status codes

> [!CAUTION]
> Actions that accept file uploads or large payloads should explicitly set `security.actionBodySizeLimit` above the default 1MB. For public-facing forms, implement rate limiting at the CDN or reverse proxy layer — Astro does not include built-in rate limiting.

---

## 8. Developer Internals

### 8.1 Error Class Reference

All error classes are defined in `packages/astro/src/core/errors/errors.ts` and share a common root through `AstroError`:

| Class | Extends | Use Case |
|-------|---------|----------|
| `AstroError` | `Error` | Base for all framework errors; carries error code, hint, location |
| `CompilerError` | `AstroError` | Errors from the Astro compiler (`.astro` file parsing) |
| `CSSError` | `AstroError` | CSS processing failures (PostCSS, scoping, nesting) |
| `MarkdownError` | `AstroError` | Markdown/MDX processing failures |
| `InternalError` | `AstroError` | Internal framework errors; always indicates a framework bug |
| `AggregateError` | `AstroError` | Multiple simultaneous errors (e.g., batch build failures) |
| `AstroUserError` | `Error` | User-facing errors with actionable messaging (separate hierarchy) |
| `MarkdocError` | `Error` | Errors from the Markdoc integration |
| `BodySizeLimitError` | `Error` | Request body exceeded the configured size limit |

`InternalError` should never be thrown in normal operation — encountering one indicates a framework bug that should be reported to the `withastro/astro` issue tracker.

### 8.2 Pipeline Internals

The `Pipeline` abstract class in `packages/astro/src/core/base-pipeline.ts` defines the contract for all request handling. Key responsibilities:

- Composing the middleware chain via `sequence()`
- Resolving server actions
- Managing session initialization and teardown
- Cache provider coordination
- Server island request routing
- File-based route resolution

`AppPipeline` (production) implements this contract for serving requests from the built artifact. During development, an equivalent dev pipeline operates against the Vite dev server's module graph.

`RenderContext` (`packages/astro/src/core/render-context.ts`) is instantiated per request and carries:

- The incoming request object
- Resolved route parameters
- Middleware-modified locals
- Session reference
- Action result state

### 8.3 Config Loading

Configuration loading happens in two phases:

1. **File discovery**: Astro looks for `astro.config.mjs`, `astro.config.ts`, `astro.config.js`, `astro.config.cjs` at the project root
2. **Schema validation**: The loaded config is validated against the Zod v4 schema in `packages/astro/src/core/config/schemas/base.ts`; unknown keys emit warnings, invalid values throw `AstroUserError`

`ASTRO_CONFIG_DEFAULTS` in the schema module defines all defaults, making the effective configuration always fully resolved with no partial states.

### 8.4 CLI Architecture

The CLI entry point at `packages/astro/src/cli/index.ts` uses `yargs-parser` for argument parsing with lazy imports for each subcommand. Lazy imports ensure the CLI starts fast — heavy dependencies (Vite, compiler) are only loaded when their command is actually invoked.

Commands are dispatched by subcommand name. Each command module is independently imported on demand.

### 8.5 Asset and Image Pipeline

The image pipeline in `packages/astro/src/assets/utils/` (17 files) handles:

- SVG passthrough and optional SVGO optimization
- Image format detection and conversion
- Responsive image `srcset` generation
- Remote image URL validation against configured patterns
- Sharp-based image transforms (resize, format conversion, quality)

The font system in `packages/astro/src/assets/fonts/` manages:

- Font file format detection
- `@font-face` CSS generation
- Font serving through the dev server and build output
- Integration with the `fonts` configuration array

### 8.6 Writing an Integration

Astro integrations are objects with a `name` and `hooks` property. Hooks fire at defined lifecycle points during build and dev:

```typescript
// my-integration.ts
import type { AstroIntegration } from 'astro';

export function myIntegration(): AstroIntegration {
  return {
    name: 'my-integration',
    hooks: {
      'astro:config:setup': ({ config, updateConfig, addRenderer, injectRoute }) => {
        // Modify config, add routes, add renderers
        updateConfig({
          vite: {
            plugins: [myVitePlugin()],
          },
        });
      },
      'astro:config:done': ({ config }) => {
        // Read the final resolved config
      },
      'astro:server:setup': ({ server }) => {
        // Access the Vite dev server
      },
      'astro:build:start': () => {
        // Before the build starts
      },
      'astro:build:done': ({ dir, routes, pages }) => {
        // After the build completes
      },
    },
  };
}
```

> [!NOTE]
> Integration hooks run in the order integrations are listed in `integrations: []`. When multiple integrations modify the same config value via `updateConfig`, the last write wins. Design integrations to be composable and avoid assuming exclusive ownership of any config key.

### 8.7 Writing a Renderer Integration

UI framework renderers (React, Vue, Svelte, Preact, Solid) are a specialized form of integration that add `addRenderer()` calls in the `astro:config:setup` hook:

```typescript
'astro:config:setup': ({ addRenderer }) => {
  addRenderer({
    name: 'my-framework',
    serverEntrypoint: 'my-framework/server',  // SSR render function
    clientEntrypoint: 'my-framework/client',  // Client hydration
  });
},
```

The renderer's server entrypoint exports a `render` function; the client entrypoint exports a `hydrate` function. These are called by Astro's component runtime during SSR and client hydration respectively.

### 8.8 Official Integrations Reference

| Integration | Package | Source | Purpose |
|-------------|---------|--------|---------|
| Node adapter | `@astrojs/node` | `node/src/` (11 files) | Node.js standalone and middleware deployment |
| Cloudflare adapter | `@astrojs/cloudflare` | `cloudflare/src/` (7 files + 9 utils) | Cloudflare Workers/Pages deployment |
| Vercel adapter | `@astrojs/vercel` | `vercel/src/` (3 files + 4 lib) | Vercel serverless/edge deployment |
| Netlify adapter | `@astrojs/netlify` | `netlify/src/` (6 files + 1 lib) | Netlify deployment |
| React | `@astrojs/react` | `react/src/` (12 files) | React 18 & 19 renderer |
| Vue | `@astrojs/vue` | `vue/src/` (6 files) | Vue 3 renderer |
| Svelte | `@astrojs/svelte` | `svelte/src/` (6 files) | Svelte 5 renderer |
| Preact | `@astrojs/preact` | `preact/src/` (8 files) | Preact renderer |
| Solid.js | `@astrojs/solid-js` | `solid/src/` | Solid.js renderer |
| Alpine.js | `@astrojs/alpinejs` | `alpinejs/src/` (1 file) | Alpine.js integration |
| MDX | `@astrojs/mdx` | `mdx/src/` (11 files) | MDX (Markdown + JSX) support |
| Markdoc | `@astrojs/markdoc` | `markdoc/src/` (10 files) | Markdoc authoring format support |
| Sitemap | `@astrojs/sitemap` | `sitemap/src/` (7 files) | XML sitemap generation |
| Partytown | `@astrojs/partytown` | `partytown/src/` (2 files) | Third-party script offloading to Web Workers |

### 8.9 Telemetry Internals

`AstroTelemetry` in `packages/telemetry/src/` tracks anonymized events from `packages/astro/src/events/`. `GlobalConfig` handles persistent storage of telemetry consent. Events fire for CLI commands, integration usage, and build completion. No source code, configuration values, or file paths are included in telemetry payloads.

### 8.10 RouteCache

`RouteCache` caches the results of route matching and resolution. It is populated during the dev server startup and cleared on file changes that affect routing. In production builds, routing is resolved at build time; the route cache is not used at runtime in static deployments.

### 8.11 Contributing to the Monorepo

**Setup:**

```bash
# Clone the repository
git clone https://github.com/withastro/astro.git
cd astro

# Install dependencies (pnpm required)
pnpm install

# Build all packages
pnpm build
```

**Common development tasks:**

```bash
# Format code (Biome + Prettier)
pnpm format

# Lint (Biome + knip + ESLint)
pnpm lint

# Run all tests
pnpm test

# Run core package tests only
pnpm test:astro

# Run integration tests
pnpm test:integrations

# Run language tools tests
pnpm test:language-tools

# Run E2E tests (Playwright, Firefox)
pnpm test:e2e

# Run smoke tests for examples
pnpm test:smoke

# Run type checking tests
pnpm test:types
```

**Creating a changeset:**

```bash
pnpm changeset
```

Follow the prompts to select affected packages and describe the change. Changesets are consumed during release to generate changelogs and bump version numbers.

**Building a release:**

```bash
pnpm run release
```

This runs the build pipeline and publishes packages via Changesets.

> [!NOTE]
> The monorepo enforces pnpm 10.30.3 via a `preinstall` hook using `only-allow`. Running `npm install` or `yarn install` will fail with an error instructing you to use pnpm. This enforcement is intentional to ensure lockfile consistency across all contributors.

---

## 9. Integration Points

### 9.1 Language Tooling

Astro provides first-class language tooling for `.astro` files through `packages/language-tools/`:

| Component | Package | Description |
|-----------|---------|-------------|
| Language Server | `@astrojs/language-server` | LSP implementation for `.astro` files — powers all editor integrations |
| VS Code Extension | `astro-vscode` | VS Code extension using the language server |
| TypeScript Plugin | `@astrojs/ts-plugin` | TypeScript language service plugin for `.astro` imports in `.ts` files |
| Astro Check | `@astrojs/check` | CLI diagnostics tool for type checking `.astro` files |

**Using `astro-check` in CI:**

```bash
# Install
npm install --save-dev @astrojs/check typescript

# Run type checking
astro check
```

`astro-check` exits non-zero on type errors, making it suitable for CI pipelines. It uses the language server's diagnostic engine to type-check `.astro` component scripts, props, and expressions.

> [!NOTE]
> The `tsconfck` library used by the language tooling has been discontinued (tracked in issue #16385). Monitor upstream developments for migration guidance. If you encounter errors related to tsconfig resolution in the language server, check for updates to `@astrojs/language-server`.

### 9.2 Vite Plugin Integration

Astro wraps Vite and exposes the Vite configuration via `vite: {}` in `astro.config`. Integrations can add Vite plugins via `updateConfig()` in the `astro:config:setup` hook.

Vite plugin caveats in Astro:

- Plugins run in multiple Vite environments (`ssr`, `client`, `prerender`). Use `enforce` and `apply` options appropriately
- The `astro` Vite environment is dev-only; plugins must handle its absence in production
- Avoid plugins that rely on `vite.config.js` — Astro generates its Vite config dynamically via `packages/astro/src/core/create-vite.ts`

### 9.3 RSS Feed Generation

`@astrojs/rss` in `packages/astro-rss/` provides a utility for generating RSS feeds from Astro endpoints:

```typescript
// src/pages/rss.xml.ts
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';

export async function GET(context) {
  const posts = await getCollection('blog');
  return rss({
    title: 'My Blog',
    description: 'My blog description',
    site: context.site,
    items: posts.map((post) => ({
      title: post.data.title,
      pubDate: post.data.date,
      link: `/blog/${post.slug}/`,
    })),
  });
}
```

### 9.4 Sitemap Generation

`@astrojs/sitemap` in `packages/integrations/sitemap/` generates `sitemap-index.xml` and per-page sitemaps during build:

```javascript
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [sitemap()],
});
```

The `site` option is required for sitemap generation — without it, the integration cannot construct absolute URLs.

### 9.5 Underscore Redirects

`packages/underscore-redirects/` generates `_redirects` files in the Netlify format, which Cloudflare Pages also supports. This package is used internally by the Netlify and Cloudflare adapters to translate Astro's `redirects` configuration into platform-native redirect rules.

### 9.6 Partytown Integration

`@astrojs/partytown` offloads third-party scripts (analytics, tag managers) to Web Workers using the Partytown library. This prevents third-party scripts from blocking the main thread:

```javascript
import partytown from '@astrojs/partytown';

export default defineConfig({
  integrations: [
    partytown({
      // Forward dataLayer.push calls from the worker to the main thread
      config: { forward: ['dataLayer.push'] },
    }),
  ],
});
```

### 9.7 Astro DB

`packages/db/` provides Astro DB — a local and cloud-connected SQLite database layer. The DB package includes a substantial CLI (20K+ chars) and core runtime (27K+ chars). It integrates with Astro's content pipeline and provides typed table access.

### 9.8 Create Astro Scaffolding

`packages/create-astro/` provides the project scaffolding wizard invoked via:

```bash
npm create astro@latest
```

The wizard guides through template selection, TypeScript preferences, and dependency installation. Templates are sourced from `examples/` in the monorepo.

### 9.9 Prism Integration

`packages/astro-prism/` provides a Prism-based syntax highlighting component. This predates Astro's Shiki integration (now the default). It remains for projects that prefer Prism's smaller bundle footprint or need Prism-specific language grammars.

To use Prism highlighting instead of Shiki:

```javascript
export default defineConfig({
  markdown: {
    syntaxHighlight: {
      type: 'prism',
      excludeLangs: [],
    },
  },
});
```

---

## 10. Troubleshooting

### 10.1 `output: 'hybrid'` Configuration Error

**Problem**: Build fails with an error about invalid `output` value.

**Cause**: The `hybrid` output mode was removed. Configuration files from earlier Astro versions may still reference it.

**Fix**: Change `output: 'hybrid'` to `output: 'server'` in `astro.config.*`. All pages prerender by default in server mode; add `export const prerender = false` to pages that need on-demand rendering.

### 10.2 Node Adapter Mode Missing

**Problem**: `AstroError` thrown during build: mode is required.

**Cause**: `@astrojs/node` requires the `mode` option (`'standalone'` or `'middleware'`).

**Fix**:
```javascript
adapter: node({ mode: 'standalone' }) // or 'middleware'
```

### 10.3 Dev Server Asset Errors (`TypeError in assets/internal.js`)

**Problem**: `TypeError` in `assets/internal.js` during development (issue #16309).

**Cause**: Usually caused by a version mismatch between `astro` and an integration, or a corrupted `.astro` cache.

**Fix**:
1. Clear the cache: `rm -rf ./node_modules/.astro`
2. Ensure all `@astrojs/*` packages are on compatible versions
3. Restart the dev server

### 10.4 Vue Scoped Styles Lost After Navigation

**Problem**: Vue component scoped styles disappear after `<ClientRouter>` (View Transitions) navigation (issue #16334).

**Cause**: Known issue with how Vue's scoped style injection interacts with ClientRouter's page replacement.

**Fix**: Monitor the issue tracker for a patch. As a workaround, use global CSS or CSS Modules for styles that must persist across view transitions.

### 10.5 Components Not Rendered on Page Refresh in Dev

**Problem**: Page shows missing components after hard refresh in the dev server (issue #15925).

**Cause**: Module graph inconsistency in the dev environment.

**Fix**: Stop and restart the dev server. If the issue recurs, clear `./node_modules/.astro` and restart.

### 10.6 CSS Missing with `export const partial = true`

**Problem**: CSS not injected when a page exports `partial = true` (issue #16296).

**Cause**: Partial pages bypass the normal HTML shell rendering, which includes CSS injection.

**Fix**: Manually include the CSS link in the partial's template, or inject styles via a shared stylesheet referenced by the parent page.

### 10.7 Cloudflare Dev Server CSS Nesting Issue

**Problem**: CSS nesting syntax causes errors in the Cloudflare adapter's local dev server (issue #16291).

**Cause**: The Cloudflare Workers runtime's CSS parser in the dev simulator does not support CSS nesting the same way as production.

**Fix**: Test CSS nesting in a Cloudflare Pages preview deployment rather than local dev. Use PostCSS with the `postcss-nesting` plugin as a compilation step to flatten nesting before it reaches the runtime.

### 10.8 UnoCSS `@apply` Incompatibility

**Problem**: UnoCSS `@apply` directives cause build errors or unexpected output (issue #16373).

**Cause**: Ordering conflict between UnoCSS's processing and Astro's CSS pipeline.

**Fix**: Configure UnoCSS's Vite plugin to run before Astro's CSS processing by adjusting plugin order in `vite.plugins`. Alternatively, avoid `@apply` and use UnoCSS's utility classes directly.

### 10.9 `tsconfck` Discontinuation

**Problem**: Language server errors related to `tsconfig.json` resolution (issue #16385).

**Cause**: The `tsconfck` library used by `@astrojs/language-server` has been discontinued.

**Fix**: Upgrade to the latest `@astrojs/language-server` version. The Astro team is tracking the migration away from `tsconfck`.

### 10.10 HTTPS Not Starting in Node Standalone

**Problem**: Node standalone server starts on HTTP despite setting cert/key paths.

**Cause**: Both `SERVER_CERT_PATH` and `SERVER_KEY_PATH` must be set simultaneously. Setting only one is ignored.

**Fix**: Verify both environment variables are exported before starting the server:
```bash
export SERVER_CERT_PATH=/path/to/cert.pem
export SERVER_KEY_PATH=/path/to/key.pem
node ./dist/server/entry.mjs
```

### 10.11 Image Optimization Failing in SSR

**Problem**: `<Image>` component throws errors during SSR.

**Cause**: The `sharp` package requires native binaries. Platform-specific builds (e.g., building on macOS, deploying to Linux) may have incompatible binaries.

**Fix**: Run `npm rebuild sharp` in the deployment environment, or configure the deployment platform to rebuild native modules. Alternatively, use a custom image service with `image.service.entrypoint`.

### 10.12 `BodySizeLimitError` on Large File Uploads

**Problem**: 413 errors when uploading files via server actions or server islands.

**Cause**: Default body size limits are 1MB for actions and server islands.

**Fix**: Increase the limits in security config:
```javascript
export default defineConfig({
  security: {
    actionBodySizeLimit: 10 * 1024 * 1024, // 10MB
  },
});
```
For very large files, consider pre-signed upload URLs directly to object storage instead of routing through Astro.

### 10.13 pnpm Version Mismatch in Monorepo

**Problem**: `pnpm install` fails with "This project requires pnpm X.Y.Z".

**Cause**: The monorepo enforces pnpm 10.30.3 via `only-allow`.

**Fix**: Install the correct pnpm version:
```bash
npm install -g pnpm@10.30.3
```

### 10.14 Build Failing Due to Missing `site` Config

**Problem**: Sitemap generation, canonical URLs, or RSS feeds produce incorrect output.

**Cause**: The `site` configuration option is not set.

**Fix**: Add `site` to `astro.config.*`:
```javascript
export default defineConfig({
  site: 'https://your-domain.com',
});
```

### 10.15 Prerender Conflicts

**Problem**: Build warnings or errors about prerender conflicts.

**Cause**: Two configurations are producing conflicting prerender decisions for the same route.

**Fix**: Set `prerenderConflictBehavior: 'error'` during development to catch conflicts early, then resolve by making prerender decisions explicit:
```javascript
export default defineConfig({
  prerenderConflictBehavior: 'error',
});
```

---

## Quick Reference

### Configuration Defaults Summary

| Config Key | Default |
|-----------|---------|
| `output` | `'static'` |
| `base` | `'/'` |
| `trailingSlash` | `'ignore'` |
| `compressHTML` | `true` |
| `scopedStyleStrategy` | `'attribute'` |
| `build.format` | `'directory'` |
| `build.assets` | `'_astro'` |
| `build.serverEntry` | `'entry.mjs'` |
| `build.inlineStylesheets` | `'auto'` |
| `build.concurrency` | `1` |
| `server.port` | `4321` |
| `server.host` | `false` |
| `image.service.entrypoint` | `'astro/assets/services/sharp'` |
| `image.endpoint.route` | `'/_image'` |
| `image.responsiveStyles` | `false` |
| `markdown.syntaxHighlight.type` | `'shiki'` |
| `markdown.gfm` | `true` |
| `security.checkOrigin` | `true` |
| `security.actionBodySizeLimit` | `1048576` (1MB) |
| `security.serverIslandBodySizeLimit` | `1048576` (1MB) |
| `security.csp` | `false` |
| `devToolbar.enabled` | `true` |
| `legacy.collectionsBackwardsCompat` | `false` |
| `env.validateSecrets` | `false` |
| `experimental.clientPrerender` | `false` |
| `experimental.rustCompiler` | `false` |
| `experimental.queuedRendering.enabled` | `false` |

### Adapter Compatibility Matrix

| Feature | Node | Vercel | Cloudflare | Netlify | Static |
|---------|------|--------|-----------|---------|--------|
| SSR | Yes | Yes | Yes | Yes | No |
| Server Actions | Yes | Yes | Yes | Yes | No |
| Server Islands | Yes | Yes | Yes | Yes | No |
| Sessions (auto) | Yes (filesystem) | — | — | — | No |
| ISR | — | Yes | — | — | — |
| HTTPS built-in | Yes | Platform | Platform | Platform | N/A |
| `context.rewrite` | Yes | Yes | Yes | No | N/A |

### Vite Environments Reference

| Environment | Build | Dev | Purpose |
|-------------|-------|-----|---------|
| `ssr` | Yes | Yes | Server-side rendering |
| `client` | Yes | No | Client bundles |
| `astro` | No | Yes | Dev process runtime |
| `prerender` | Yes | No | Static page generation |

---

_Generated May 2026 from withastro/astro at 1058428. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
