Skip to main content
Astro supports multiple UI frameworks, allowing you to use your favorite component library or mix and match frameworks in the same project.

Available Framework Integrations

React

Use React components with server-side rendering and client-side hydration

Vue

Add Vue 3 components to your Astro project

Svelte

Integrate Svelte components with support for Svelte 3, 4, and 5

Solid

Use SolidJS components with fine-grained reactivity

Preact

Add lightweight Preact components as a React alternative

Alpine.js

Add Alpine.js for lightweight JavaScript behavior

React

The React integration enables server-side rendering and client-side hydration for React components.

Installation

npx astro add react
Or manually:
npm install @astrojs/react react react-dom

Configuration

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

export default defineConfig({
  integrations: [react()],
});

Options

react({
  // Only include React in specific directories
  include: ['**/react/*'],
  
  // Exclude specific patterns
  exclude: ['**/ignore/*'],
  
  // Experimental: Support React children in Astro components
  experimentalReactChildren: false,
  
  // Experimental: Disable streaming for React components
  experimentalDisableStreaming: false,
  
  // Custom Babel configuration
  babel: {
    plugins: [],
    presets: [],
  },
})

Usage Example

Create a React component:
src/components/Counter.tsx
import { useState } from 'react';

export default function Counter({ count: initialCount }: { count: number }) {
  const [count, setCount] = useState(initialCount);
  
  return (
    <div className="counter">
      <button onClick={() => setCount(count - 1)}>-</button>
      <pre>{count}</pre>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}
Use it in an Astro page:
src/pages/index.astro
---
import Counter from '../components/Counter.tsx';
---

<html>
  <body>
    <h1>React in Astro</h1>
    <Counter count={0} client:load />
  </body>
</html>

Vue

The Vue integration adds support for Vue 3 components with server-side rendering.

Installation

npx astro add vue
Or manually:
npm install @astrojs/vue vue

Configuration

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

export default defineConfig({
  integrations: [vue()],
});

Options

vue({
  // Pass options to @vitejs/plugin-vue
  template: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('custom-')
    }
  },
  
  // Support for Vue JSX
  jsx: true,
  
  // App entrypoint for Vue plugins
  appEntrypoint: '/src/pages/_app',
})

Usage Example

src/components/Greeting.vue
<template>
  <div class="greeting">
    <h2>{{ greeting }}</h2>
    <button @click="updateGreeting">Change Greeting</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const greeting = ref('Hello from Vue!');

function updateGreeting() {
  greeting.value = 'Updated greeting!';
}
</script>

Svelte

The Svelte integration supports Svelte 3, 4, and 5 with server-side rendering.

Installation

npx astro add svelte

Configuration

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

export default defineConfig({
  integrations: [svelte()],
});

Options

svelte({
  // Pass options to the Svelte compiler
  compilerOptions: {
    css: 'injected',
  },
  
  // Preprocess Svelte files
  preprocess: [],
})

Usage Example

src/components/Todo.svelte
<script>
  export let task = '';
  let completed = false;
  
  function toggleComplete() {
    completed = !completed;
  }
</script>

<div class="todo" class:completed>
  <input type="checkbox" bind:checked={completed} on:change={toggleComplete} />
  <span>{task}</span>
</div>

<style>
  .todo.completed span {
    text-decoration: line-through;
  }
</style>

Solid

The Solid integration enables SolidJS components with fine-grained reactivity.

Installation

npx astro add solid

Configuration

astro.config.mjs
import { defineConfig } from 'astro/config';
import solid from '@astrojs/solid-js';

export default defineConfig({
  integrations: [solid()],
});

Usage Example

src/components/Signal.tsx
import { createSignal } from 'solid-js';

export default function Signal() {
  const [count, setCount] = createSignal(0);
  
  return (
    <button onClick={() => setCount(count() + 1)}>
      Count: {count()}
    </button>
  );
}

Preact

Preact is a lightweight alternative to React with the same modern API.

Installation

npx astro add preact

Configuration

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

export default defineConfig({
  integrations: [preact()],
});

Options

preact({
  // Include only in specific paths
  include: ['**/preact/*'],
  
  // Use Preact's compatibility layer for React
  compat: true,
})

Alpine.js

Alpine.js allows you to add interactive behavior with minimal JavaScript.

Installation

npx astro add alpinejs

Configuration

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

export default defineConfig({
  integrations: [alpinejs()],
});

Usage Example

src/components/Dropdown.astro
<div x-data="{ open: false }">
  <button @click="open = !open">Toggle</button>
  <div x-show="open" @click.outside="open = false">
    Dropdown content
  </div>
</div>

Using Multiple Frameworks

Astro supports using multiple frameworks in the same project:
astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import vue from '@astrojs/vue';
import svelte from '@astrojs/svelte';

export default defineConfig({
  integrations: [react(), vue(), svelte()],
});

Avoiding JSX Conflicts

When using multiple JSX frameworks (React, Preact, Solid), use the include option:
astro.config.mjs
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
import solid from '@astrojs/solid-js';

export default defineConfig({
  integrations: [
    preact({ include: ['**/preact/*'] }),
    react({ include: ['**/react/*'] }),
    solid({ include: ['**/solid/*'] }),
  ],
});
Organize your components by framework:
src/
├── components/
│   ├── react/
│   │   └── Counter.tsx
│   ├── preact/
│   │   └── Button.tsx
│   └── solid/
│       └── Signal.tsx

Client Directives

All framework components support Astro’s client directives for controlling hydration:
  • client:load - Hydrate immediately on page load
  • client:idle - Hydrate when the browser is idle
  • client:visible - Hydrate when the component enters the viewport
  • client:media - Hydrate when a media query matches
  • client:only - Skip server rendering, only render on the client
<Counter client:load />
<HeavyComponent client:idle />
<ChartWidget client:visible />
<MobileMenu client:media="(max-width: 768px)" />
<ClientOnlyWidget client:only="react" />

Next Steps

Official Integrations

Explore MDX, Sitemap, Partytown, and more

SSR Adapters

Deploy with server-side rendering

Build docs developers (and LLMs) love