Astro Integrations and Adapters: An Overview
Understand the difference between Astro integrations and adapters, when to reach for each, and how they shape your deployment pipeline.
What you'll learn
- ✓What an Astro integration is and how it hooks into the build
- ✓What an adapter is and why SSR needs one
- ✓Popular integrations like Tailwind, MDX, and React
- ✓Choosing the right adapter for your host
- ✓How to write a tiny custom integration
Prerequisites
- •HTML basics
- •An existing Astro project
What and Why
Astro ships a minimal core. Everything else, from MDX support to React components to deploying on Cloudflare, comes through two extension points: integrations and adapters. Understanding the difference saves hours of confusion when you wonder why your site builds locally but breaks on Vercel.
An integration is a plugin that extends Astro at build time or dev time. It can add file types, inject scripts, register UI frameworks, or modify the build pipeline.
An adapter is a special kind of integration that tells Astro how to produce a server-rendered build for a specific host. Without an adapter, Astro outputs static HTML. With one, it outputs handlers ready for Node, Vercel, Netlify, Cloudflare, or Deno.
Mental Model
Picture Astro as a car factory. Integrations are bolt-on features like sunroof kits, custom paint, or a stereo. They change what the car has. An adapter is the shipping container that determines which country the car gets delivered to. You can fit many integrations into one build, but only one adapter, because the car can only land in one place.
Static sites need no adapter at all. The moment you add output: 'server' or output: 'hybrid', an adapter becomes mandatory.
Hands-on Example
Install a few common integrations:
npx astro add tailwind
npx astro add mdx
npx astro add react
Each command edits astro.config.mjs for you:
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import mdx from '@astrojs/mdx';
import react from '@astrojs/react';
export default defineConfig({
integrations: [tailwind(), mdx(), react()],
});
Now add an adapter for server rendering on Vercel:
npx astro add vercel
Your config grows:
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'server',
adapter: vercel(),
integrations: [tailwind(), mdx(), react()],
});
astro.config.mjs
|
v
+-----------------+
| Astro Build |
+-----------------+
| |
| +--> integrations (tailwind, mdx, react)
| |
| v
| transformed files
v
adapter (vercel / node / cloudflare)
|
v
deployable output A minimal custom integration is just an object with hooks:
export default function logBuild() {
return {
name: 'log-build',
hooks: {
'astro:build:done': ({ pages }) => {
console.log(`Built ${pages.length} pages`);
},
},
};
}
Add it to the integrations array and you have a build-time logger.
Common Pitfalls
- Forgetting the adapter. Setting
output: 'server'without an adapter fails the build with a confusing error. - Mixing adapters. You cannot stack two adapters. Pick the one matching your host.
- Edge vs serverless confusion. Vercel and Cloudflare have separate edge and serverless modes. Pick the one matching your runtime needs.
- Order of integrations. Some integrations depend on others. MDX should come after framework integrations if you embed components in MDX.
- Outdated adapters. Adapters track host APIs. An old version can break deploys even when your code is fine.
Best Practices
- Prefer
npx astro addover manual install. It writes the config correctly. - Pin adapter and integration versions in CI to avoid surprise breaks.
- Keep
output: 'static'for as long as possible; switch to'hybrid'only when you need dynamic routes. - Read each integration’s README. Many have config knobs you will want.
- Write small custom integrations for repetitive build tasks. The hook API is friendly.
Wrap-up
Integrations add capabilities; adapters pick a deployment target. Once that distinction clicks, the Astro ecosystem stops feeling like a maze. Start with astro add, layer features as needed, and pick exactly one adapter per project. Custom integrations are a few dozen lines of code and can replace a lot of glue scripts. With this mental model, scaling an Astro project from a personal blog to a hybrid commerce site stays straightforward.
Related articles
- Astro Astro Content Collections Tutorial
Build a typed blog with Astro content collections, including Zod schemas, references, and dynamic routes generated from Markdown files.
- Astro Astro Image Component and Optimization
Master Astro's built-in Image and Picture components to ship responsive, lazy-loaded, modern-format images without external services.
- Astro Astro Islands Architecture Explained
Learn how Astro ships zero JavaScript by default and only hydrates the interactive components you mark as islands.
- Astro Astro Middleware Tutorial
Use Astro middleware to run code on every request: auth gates, locals injection, redirects, and response headers. Learn the onRequest signature, the next() flow, sequencing, and common production patterns.