Skip to main content
Astro is built on top of Vite, a fast and modern build tool. You can pass additional Vite configuration options through the vite key in your Astro config.

Basic Vite Configuration

Add Vite configuration to your astro.config.mjs:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    // Vite configuration options here
  }
});
Astro automatically configures Vite with sensible defaults. Only add custom Vite config when you need to override or extend the defaults.

Common Use Cases

Adding Vite Plugins

Extend Vite with community plugins:
astro.config.mjs
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  vite: {
    plugins: [tailwindcss()]
  }
});
Many popular tools have Astro integrations that handle Vite configuration for you. Check the integrations directory first.

Configuring SSR External Packages

Exclude problematic packages from SSR processing:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    ssr: {
      external: ['broken-npm-package']
    }
  }
});
Use this when a package:
  • Has CommonJS modules that break during SSR
  • Uses Node.js built-ins that need to be excluded
  • Has incompatible dependencies
  • Causes “Cannot use import statement outside a module” errors

Adding Module Aliases

Create import aliases (TypeScript users should also update tsconfig.json):
astro.config.mjs
import { defineConfig } from 'astro/config';
import path from 'path';

export default defineConfig({
  vite: {
    resolve: {
      alias: {
        '@components': path.resolve('./src/components'),
        '@lib': path.resolve('./src/lib')
      }
    }
  }
});
Then use in your code:
src/pages/index.astro
---
import Card from '@components/Card.astro';
import { formatDate } from '@lib/utils';
---
Astro provides @/* as an alias to src/* by default. For TypeScript projects, also configure path mappings in tsconfig.json.

Environment Variables

Customize which environment variables are exposed to your client-side code:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    define: {
      'import.meta.env.CUSTOM_VAR': JSON.stringify(process.env.CUSTOM_VAR)
    }
  }
});
Only use define for non-secret values. Secrets should never be exposed to client code.

Optimizing Dependencies

Control which dependencies Vite pre-bundles:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    optimizeDeps: {
      include: ['linked-package'],
      exclude: ['heavy-package']
    }
  }
});
Include when:
  • A package is linked locally and not being detected
  • A package has many internal modules that slow down dev server
  • You’re experiencing slow initial page loads
Exclude when:
  • A package is very large and slows down the dev server startup
  • A package has conditional imports that break when pre-bundled

Advanced Configuration

Build Options

Customize the build output:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'vendor': ['react', 'react-dom']
          }
        }
      },
      cssMinify: 'lightningcss',
      minify: 'terser'
    }
  }
});
Vite uses Rollup for production builds. Use rollupOptions to configure Rollup directly.

CSS Configuration

Configure CSS processing:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import "src/styles/variables.scss";`
        }
      }
    }
  }
});

Server Options

Configure the Vite dev server:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    server: {
      fs: {
        allow: ['..']  // Allow serving files from parent directory
      },
      watch: {
        usePolling: true  // Use polling for file watching (useful in Docker)
      }
    }
  }
});
  • server.fs.allow: Restrict file system access for security
  • server.watch.usePolling: Enable polling for file watching (Docker, WSL)
  • server.proxy: Configure proxy for API requests
  • server.cors: Enable CORS for development

Proxy Configuration

Proxy API requests during development:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    server: {
      proxy: {
        '/api': {
          target: 'http://localhost:3000',
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, '')
        }
      }
    }
  }
});
Now requests to /api/users are proxied to http://localhost:3000/users.

Framework-Specific Configuration

React

Customize React plugin options:
astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  integrations: [react()],
  vite: {
    esbuild: {
      jsxInject: `import React from 'react'`
    }
  }
});

Vue

Configure Vue plugin:
astro.config.mjs
import { defineConfig } from 'astro/config';
import vue from '@astrojs/vue';

export default defineConfig({
  integrations: [vue()],
  vite: {
    vue: {
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag.startsWith('ion-')
        }
      }
    }
  }
});

Performance Optimization

Code Splitting

Optimize bundle size with manual chunks:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    build: {
      rollupOptions: {
        output: {
          manualChunks(id) {
            if (id.includes('node_modules')) {
              if (id.includes('react')) {
                return 'vendor-react';
              }
              return 'vendor';
            }
          }
        }
      }
    }
  }
});

Benefits

  • Smaller initial bundle
  • Better caching
  • Parallel downloads

Trade-offs

  • More HTTP requests
  • Complex configuration
  • Overhead for small sites

Asset Optimization

Configure asset handling:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    build: {
      assetsInlineLimit: 4096,  // 4kb
      cssCodeSplit: true
    }
  }
});
  • assetsInlineLimit: Assets smaller than this are inlined as base64
  • cssCodeSplit: Enable CSS code splitting

Environment-Specific Configuration

Configure Vite differently for dev vs. build:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig(({ command, mode }) => {
  const isDev = command === 'dev';
  
  return {
    vite: {
      logLevel: isDev ? 'info' : 'warn',
      build: {
        sourcemap: isDev,
        minify: !isDev
      }
    }
  };
});
The config function receives command (“dev” | “build” | “preview”) and mode (“development” | “production”).

Debugging Vite

Enable Debug Logging

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

export default defineConfig({
  vite: {
    logLevel: 'info',  // 'error' | 'warn' | 'info' | 'silent'
    clearScreen: false
  }
});

Inspect Bundle

Use the rollup-plugin-visualizer to analyze your bundle:
astro.config.mjs
import { defineConfig } from 'astro/config';
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
  vite: {
    plugins: [
      visualizer({
        open: true,
        gzipSize: true,
        brotliSize: true
      })
    ]
  }
});
Run astro build to generate a visual report of your bundle.

Common Issues

Try adding the module to vite.optimizeDeps.include:
astro.config.mjs
export default defineConfig({
  vite: {
    optimizeDeps: {
      include: ['problematic-package']
    }
  }
});
Exclude large dependencies from optimization:
astro.config.mjs
export default defineConfig({
  vite: {
    optimizeDeps: {
      exclude: ['large-package']
    }
  }
});
Mark the package as external:
astro.config.mjs
export default defineConfig({
  vite: {
    ssr: {
      external: ['cjs-package']
    }
  }
});
Enable polling:
astro.config.mjs
export default defineConfig({
  vite: {
    server: {
      watch: {
        usePolling: true
      }
    }
  }
});

Complete Example

Here’s a comprehensive Vite configuration example:
astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import path from 'path';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  integrations: [react()],
  vite: {
    // Plugins
    plugins: [tailwindcss()],
    
    // Aliases
    resolve: {
      alias: {
        '@components': path.resolve('./src/components'),
        '@lib': path.resolve('./src/lib')
      }
    },
    
    // SSR Configuration
    ssr: {
      external: ['@prisma/client']
    },
    
    // Dependency Optimization
    optimizeDeps: {
      include: ['linked-package'],
      exclude: ['heavy-package']
    },
    
    // Build Options
    build: {
      sourcemap: true,
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-dom']
          }
        }
      }
    },
    
    // CSS Options
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import "src/styles/variables.scss";`
        }
      }
    },
    
    // Server Options
    server: {
      proxy: {
        '/api': 'http://localhost:3000'
      },
      watch: {
        usePolling: process.env.USE_POLLING === 'true'
      }
    }
  }
});

Learn More

Vite Documentation

Official Vite configuration reference

Astro Config

Complete Astro configuration reference

Integrations

Learn about Astro integrations

Build Options

Astro build configuration

Build docs developers (and LLMs) love