How to bundle a React app with Vite

Bundling React applications with Vite provides extremely fast development builds and optimized production bundles with minimal configuration. With over 12 years of React experience since 2014 and as the creator of CoreUI, I’ve migrated numerous projects to Vite for improved developer experience. Vite uses native ES modules during development and Rollup for production, delivering instant server start and lightning-fast hot module replacement. This approach dramatically improves development speed while maintaining excellent production build optimization.

Use Vite with @vitejs/plugin-react to bundle React applications with fast builds and optimized output.

Basic Vite configuration:

// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  },
  server: {
    port: 3000,
    open: true
  },
  build: {
    outDir: 'dist',
    sourcemap: true,
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          router: ['react-router-dom']
        }
      }
    }
  }
})

Advanced configuration:

// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { visualizer } from 'rollup-plugin-visualizer'
import compression from 'vite-plugin-compression'

export default defineConfig(({ mode }) => ({
  plugins: [
    react({
      babel: {
        plugins: [
          mode === 'production' && ['transform-remove-console', { exclude: ['error', 'warn'] }]
        ].filter(Boolean)
      }
    }),
    compression({
      algorithm: 'gzip',
      ext: '.gz'
    }),
    visualizer({
      open: true,
      filename: 'dist/stats.html'
    })
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
      '@utils': path.resolve(__dirname, './src/utils')
    }
  },
  server: {
    port: 3000,
    open: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  },
  build: {
    outDir: 'dist',
    sourcemap: mode !== 'production',
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: mode === 'production',
        drop_debugger: mode === 'production'
      }
    },
    rollupOptions: {
      output: {
        manualChunks: (id) => {
          if (id.includes('node_modules')) {
            if (id.includes('react') || id.includes('react-dom')) {
              return 'react-vendor'
            }
            if (id.includes('react-router')) {
              return 'router'
            }
            return 'vendor'
          }
        },
        chunkFileNames: 'assets/js/[name]-[hash].js',
        entryFileNames: 'assets/js/[name]-[hash].js',
        assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
      }
    },
    chunkSizeWarningLimit: 1000
  },
  optimizeDeps: {
    include: ['react', 'react-dom', 'react-router-dom']
  }
}))

Environment variables:

// .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My React App

// Access in code
const apiUrl = import.meta.env.VITE_API_URL
const appTitle = import.meta.env.VITE_APP_TITLE

Package.json:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "analyze": "vite build --mode analyze"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.2.1",
    "rollup-plugin-visualizer": "^5.11.0",
    "terser": "^5.26.0",
    "vite": "^5.0.8",
    "vite-plugin-compression": "^0.5.1"
  }
}

TypeScript support:

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import type { UserConfig } from 'vite'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': '/src'
    }
  }
} as UserConfig)

Best Practice Note

Vite requires minimal configuration compared to Webpack. Use environment variables prefixed with VITE_ for client-side access. Enable gzip compression for production builds. Use manualChunks to optimize code splitting. Leverage Vite’s fast HMR for improved development experience. Configure proxy for API requests during development. This is how we use Vite for CoreUI React projects—instant dev server startup, lightning-fast HMR, and optimized production builds with significantly less configuration than Webpack.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author