Type something to search...
What are Astro integrations and how to add them?

What are Astro integrations and how to add them?

Astro integrations are packages that plug into Astro's build process and dev server to add features your project doesn't have out of the box, such as React or Vue components, MDX support, sitemap generation or third-party scripts moved into a web worker. The quickest way to add one is the astro add command, for example npx astro add react, which installs the package, updates astro.config.mjs and adjusts tsconfig.json if needed. You can also install a package with npm and add it to the integrations array in your config by hand.

Integrations are how most of Astro's optional features are delivered, so you'll use them in almost every real project. They're built on a hooks API inspired by Rollup and Vite, which means they can change configuration, inject routes, add scripts and run code after a build. In this article you'll learn what integrations are and what kinds exist, how to add them automatically and manually, how to pass options and toggle them, how to keep them up to date, how to remove them, and which older integrations you should no longer use.

What an Integration Actually Is

An integration is a plain JavaScript object with a name and a set of hooks. Astro calls those hooks at specific moments: when the config is being set up, when the dev server starts, when a build begins and when it finishes. Most packages export a factory function that returns this object, so you call it in your config:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

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

Calling sitemap() returns an object along the lines of { name: '@astrojs/sitemap', hooks: { ... } }. You never need to look inside it to use the integration, but knowing the shape helps when you read error messages or decide to build a custom Astro integration yourself.

Because integrations hook into the whole lifecycle, they can do far more than a component library can:

  • Add a renderer: let .astro files render and hydrate React, Vue, Svelte, Solid or Preact components.
  • Change configuration: add Vite plugins, Markdown settings or other config on your behalf.
  • Inject routes and scripts: add pages to your site or scripts to every page.
  • Process build output: read the generated pages and write extra files, as the sitemap integration does.

Types of Integrations

The official integrations maintained by the Astro team fall into three broad groups.

GroupPackagesWhat they do
UI framework renderers@astrojs/react, @astrojs/preact, @astrojs/vue, @astrojs/svelte, @astrojs/solid-js, @astrojs/alpinejsRender framework components and hydrate them as islands
Server adapters@astrojs/node, @astrojs/vercel, @astrojs/netlify, @astrojs/cloudflareEnable on-demand rendering on a specific host
Other features@astrojs/mdx, @astrojs/markdoc, @astrojs/sitemap, @astrojs/partytownAdd content formats, SEO files and script handling

Adapters are a special case. They're added with the same astro add command, but they go in the adapter field of your config rather than in integrations. The post on Astro adapters covers them in detail.

Beyond the official list, hundreds of community packages are listed in the integrations directory at astro.build/integrations, covering analytics, icons, image tools, SEO and more. Community packages work the same way: a factory function you call inside integrations.

Adding an Integration with astro add

For official integrations, and many community ones, astro add does all the setup for you:

npx astro add react

You can add several at once:

npx astro add react sitemap mdx

The command shows the changes it plans to make and asks for confirmation before each step. Pass --yes to accept every prompt, which is handy in scripts. Here's what running the multi-package command looks like on a fresh Astro 7.4 project:

  Astro will make the following changes to your config file:
╭─astro.config.mjs───────────────────────────────╮
│  // @ts-check                                  │
│  import { defineConfig } from 'astro/config';  │
│                                                │
│  import react from '@astrojs/react';           │
│  import sitemap from '@astrojs/sitemap';       │
│  import mdx from '@astrojs/mdx';               │
│                                                │
│  // https://astro.build/config                 │
│  export default defineConfig({                 │
│    integrations: [react(), sitemap(), mdx()]   │
│  });                                           │
╰────────────────────────────────────────────────╯

   success  Added the following integrations to your project:
  - @astrojs/react
  - @astrojs/sitemap
  - @astrojs/mdx

For React, it also updated tsconfig.json with the JSX settings the framework needs:

{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"],
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react"
  }
}

It also installed the peer dependencies (react, react-dom and their types), which is the main reason to prefer astro add over a manual install. If you ever see a warning such as Cannot find package 'react' after adding an integration, your package manager didn't install a peer dependency, and you can fix it with a normal npm install react.

How astro add Finds Packages

astro add react expands to the official @astrojs/react package. For a community package you pass its full npm name, and the command works only if the package author has added the astro-integration keyword to their package.json and exports a default factory function. If astro add can't set a package up, check that package's README for manual steps.

Adding an Integration Manually

Manual installation is two steps: install the package, then add it to your config.

  1. Install the package with your package manager:

    npm install @astrojs/sitemap
    
  2. Import it and add it to integrations in astro.config.mjs:

    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    import sitemap from '@astrojs/sitemap';
    
    export default defineConfig({
      site: 'https://example.com',
      integrations: [sitemap()],
    });
    
  3. Install any peer dependencies the integration's documentation lists. Renderers in particular need the framework itself, so @astrojs/react also needs react and react-dom.

The integrations array accepts three kinds of entries, which you can mix freely:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import vue from '@astrojs/vue';
import localIntegration from './integrations/my-integration.js';

export default defineConfig({
  integrations: [
    // 1. From an installed npm package
    vue(),
    // 2. From a local file in your project
    localIntegration(),
    // 3. An inline object
    { name: 'my-site:inline', hooks: {} },
  ],
});

Inline objects are useful for a small one-off hook, such as logging something after every build. Once the code grows, move it into its own file.

Configuring Integrations with Options

Because integrations are factory functions, you configure them by passing an options object. Each integration documents its own options. For example, the sitemap integration takes a filter function to exclude pages:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import sitemap from '@astrojs/sitemap';
import mdx from '@astrojs/mdx';

export default defineConfig({
  site: 'https://example.com',
  integrations: [
    react(),
    mdx(),
    sitemap({
      filter: (page) => !page.includes('/secret/'),
    }),
  ],
});

With pages at /, /post/ and /secret/, the build logs show the integration running after the pages are generated:

 generating static routes
11:00:37   ├─ /post/index.html (+6ms)
11:00:37   ├─ /secret/index.html (+2ms)
11:00:37   ├─ /index.html (+8ms)
11:00:37 ✓ Completed in 34ms.

11:00:37 [build] ✓ Completed in 331ms.
11:00:37 [@astrojs/sitemap] `sitemap-index.xml` created at `dist`
11:00:37 [build] 3 page(s) built in 495ms
11:00:37 [build] Complete!

The generated sitemap-0.xml contains only the two pages that passed the filter:

<url><loc>https://example.com/</loc></url>
<url><loc>https://example.com/post/</loc></url>

Some integrations also depend on top-level config. The sitemap integration needs site to build absolute URLs, and without it the build doesn't fail but prints a warning and skips the file:

[WARN] [@astrojs/sitemap] The Sitemap integration requires the `site` astro.config option. Skipping.

This is a good reminder to read the build output after adding anything new. The sitemap guide goes through its other options, such as serialize() and i18n.

Integrations That Inherit Config

Some integrations read your existing Astro config instead of asking you to repeat it. @astrojs/mdx, for example, inherits every markdown option, including the processor, syntax highlighting theme and plugins, so .mdx files render the same way as .md files unless you override something in mdx({ ... }). In Astro 7 the default Markdown processor is Sätteri, and astro add mdx installs @astrojs/markdown-satteri alongside the MDX package for that reason.

Toggling Integrations On and Off

Astro ignores falsy values in the integrations array, so you can switch an integration on or off with a plain expression and not worry about leaving false or undefined behind:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
import partytown from '@astrojs/partytown';

const isProduction = process.env.NODE_ENV === 'production';

export default defineConfig({
  site: 'https://example.com',
  integrations: [
    sitemap(),
    // Only add Partytown for production builds
    isProduction && partytown(),
  ],
});

This keeps environment-specific setup in one place instead of maintaining two config files.

Integration Order

Integrations run in the order they appear in the array. With [react(), svelte()], React's hooks run before Svelte's at each stage. Well-written integrations don't care about order, but when one does, its documentation will tell you to place it first or last. If two integrations seem to conflict, reordering them is a quick first experiment.

Some packages return an array of integrations rather than one. These are called presets, and you add them exactly like a normal integration. Starlight is a well-known example: one starlight() call sets up several features, including MDX, which is why you shouldn't add mdx() separately in a Starlight project.

Upgrading Integrations

Official integrations are versioned alongside Astro, and a new major version of Astro usually needs new majors of the integrations too. The simplest way to keep everything in step is the upgrade tool:

npx @astrojs/upgrade

This upgrades astro and every official integration in your package.json to their latest versions together. To upgrade specific packages yourself, install them with the @latest tag:

npm install @astrojs/react@latest @astrojs/sitemap@latest

At the time of writing, with Astro 7.4.2, the official packages are at versions such as @astrojs/react 7.1, @astrojs/mdx 8.1, @astrojs/sitemap 3.7 and @astrojs/node 11.1. The guide to upgrading Astro to the latest version walks through a full major upgrade.

Removing an Integration

Removing an integration is the reverse of adding one:

  1. Uninstall the package:

    npm uninstall @astrojs/react
    
  2. Remove the import and the call from astro.config.mjs:

    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      integrations: [],
    });
    
  3. Clean up leftovers: for a renderer, remove the framework's peer dependencies and the JSX settings in tsconfig.json if nothing else needs them, and delete or convert any components that used it.

If you forget step 2, the config will fail to load because the import can't be resolved, so the error is easy to spot.

Integrations You Should No Longer Use

Several packages you'll still find in older tutorials have been replaced:

  • @astrojs/tailwind: deprecated. Tailwind 4 ships a Vite plugin, @tailwindcss/vite, and npx astro add tailwind now sets that up instead of an integration. See using Tailwind CSS with Astro.
  • @astrojs/db: deprecated in Astro 6.4 and removed in Astro 7. Use Node's built-in node:sqlite, Drizzle ORM or another database library.
  • @astrojs/lit: deprecated since Astro 5. You can still use Lit by importing your custom elements in a client-side <script>.
  • @astrojs/prefetch: replaced by Astro's built-in prefetch option back in Astro 3.5.

If an old project still lists any of these, deal with them before or during an upgrade, as they won't receive fixes for current Astro versions.

When Something Goes Wrong

Most integration problems come down to a handful of causes:

  1. Missing peer dependency: install the package named in the Cannot find package error.
  2. Version mismatch: an integration built for an older Astro major may fail to load or behave oddly. Run npx @astrojs/upgrade so Astro and its integrations match.
  3. Missing required config: read warnings in the build output, like the sitemap's site warning above.
  4. Duplicate setup: adding an integration that a preset already includes, such as mdx() inside a Starlight site, can cause conflicts.
  5. Order-dependent behaviour: try moving the integration earlier or later in the array.

Running npx astro info prints your Astro, Vite and Node versions along with the adapter and integrations in use, which is exactly what you need when reporting an issue.


FAQ: Astro Integrations

A Vite plugin works at the bundler level, transforming modules and serving files. An Astro integration works at the framework level, with hooks for Astro's config, routes, dev server and build output. Integrations often add Vite plugins for you through their config setup hook.

Yes, if the package includes the astro-integration keyword in its package.json and exports a default factory function. Pass the full package name, such as npx astro add some-package. If that fails, follow the package's manual installation steps.

Yes. Astro can't render or hydrate React components without the @astrojs/react renderer. The same applies to Vue, Svelte, Solid and Preact, each of which has its own official integration.

Some integrations need TypeScript settings to work correctly. UI framework renderers set jsx and jsxImportSource so that type checking and editor support understand the framework's JSX. Astro shows you the change and asks before applying it.

Technically yes, since they use the same hooks API, but you configure them in the adapter field of astro.config.mjs rather than in the integrations array. You only need one when pages are rendered on demand on a server.

Run npx @astrojs/upgrade in your project. It upgrades Astro and every official integration listed in package.json to matching latest versions. Community integrations still need to be updated with your package manager.


Conclusion

Astro integrations are the official way to extend a project: a factory function in the integrations array that hooks into the config, dev server and build. npx astro add handles installation, config changes and peer dependencies in one step, while a manual install gives you the same result with a little more typing. Options go in the factory call, falsy entries are ignored so toggling is trivial, and order only matters when an integration says it does.

Keep integrations matched to your Astro version with npx @astrojs/upgrade, read the build output for warnings after adding one, and replace deprecated packages like @astrojs/tailwind and @astrojs/db with their modern alternatives. Once you're comfortable using them, the natural next step is writing a small integration of your own for the tasks your project repeats on every build.

Tags :
Share :

Related Posts

What are Astro Actions and how do they work?

What are Astro Actions and how do they work?

Astro Actions are type-safe backend functions that you define once on the server and then call from the browser as if they were ordinary async fu

Dive Deeper
What are Astro adapters and which one should you choose?

What are Astro adapters and which one should you choose?

An Astro adapter is an integration that builds the server part of your project for a specific runtime, such as Node.js, Vercel Functions, Netlify

Dive Deeper
How to build API endpoints in Astro?

How to build API endpoints in Astro?

To build an API endpoint in Astro, create a .js or .ts file in src/pages/ and export a function named after an HTTP method, such as GET or

Dive Deeper