Vite
02 / 03

Vite Setup & Configuration

Vite Setup & Configuration

Vite is a next-generation frontend build tool. It uses native ES modules for instant dev server starts and Rollup for optimized production builds.

Scaffolding & Installation

# Create new project
npm create vite@latest my-app -- --template react-ts
npm create vite@latest my-app -- --template vue-ts
npm create vite@latest my-app -- --template svelte-ts

# Install dependencies
cd my-app && npm install

# Dev server
npm run dev

# Production build
npm run build

# Preview production build locally
npm run preview

vite.config.ts — Full Setup

import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig(({ command, mode }) => {
  // Load .env files based on mode
  const env = loadEnv(mode, process.cwd(), '');

  return {
    plugins: [
      react(),                        // React fast refresh (Babel or SWC)
      // react({ jsxRuntime: 'automatic' })
      // @vitejs/plugin-vue            — for Vue 3
      // @vitejs/plugin-svelte         — for Svelte
    ],

    resolve: {
      alias: {
        '@': path.resolve(__dirname, './src'),
        '@components': path.resolve(__dirname, './src/components'),
        '@hooks': path.resolve(__dirname, './src/hooks'),
        '@utils': path.resolve(__dirname, './src/utils'),
      },
    },

    server: {
      port: 3000,
      open: true,                     // auto-open browser
      strictPort: true,               // fail if port is taken
      cors: true,
      proxy: {
        '/api': {
          target: 'http://localhost:8000',
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, ''),
        },
        '/ws': {
          target: 'ws://localhost:8000',
          ws: true,
        },
      },
    },

    build: {
      outDir: 'dist',
      sourcemap: true,
      minify: 'esbuild',              // 'terser' for more aggressive minification
      target: 'esnext',
      chunkSizeWarningLimit: 1000,    // KB
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-dom'],
            router: ['react-router-dom'],
            ui: ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu'],
          },
        },
      },
    },

    css: {
      modules: {
        localsConvention: 'camelCase',
      },
      preprocessorOptions: {
        scss: {
          additionalData: '@import "@/styles/variables.scss";',
        },
      },
    },

    define: {
      __APP_VERSION__: JSON.stringify(env.npm_package_version),
    },
  };
});

Plugins — React, Vue, PWA

import react from '@vitejs/plugin-react';
import reactSwc from '@vitejs/plugin-react-swc'; // faster — uses SWC instead of Babel
import vue from '@vitejs/plugin-vue';
import { VitePWA } from 'vite-plugin-pwa';
import tsconfigPaths from 'vite-tsconfig-paths'; // auto-resolve TS paths

plugins: [
  // React (choose one)
  react(),
  reactSwc(),

  // Vue
  vue(),

  // PWA — generates service worker + manifest
  VitePWA({
    registerType: 'autoUpdate',
    manifest: {
      name: 'My App',
      short_name: 'App',
      theme_color: '#ffffff',
      icons: [
        { src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
        { src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
      ],
    },
    workbox: {
      runtimeCaching: [
        { urlPattern: /\/api\/.*/, handler: 'NetworkFirst' },
      ],
    },
  }),

  // Auto-resolve paths from tsconfig.json
  tsconfigPaths(),
]

Environment Variables

# .env files — loaded in priority order
.env                  # all modes
.env.local            # all modes, git-ignored
.env.development      # dev mode only (vite dev)
.env.production       # prod mode only (vite build)
.env.staging          # custom mode: vite build --mode staging

# Variables MUST be prefixed VITE_ to be exposed to client code
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
VITE_FEATURE_FLAG_DARK_MODE=true

# NOT prefixed — server-only, never exposed to client
DATABASE_URL=postgresql://...
SECRET_KEY=server-only-value
// Access env vars in client code
const apiUrl = import.meta.env.VITE_API_URL;       // string | undefined
const appTitle = import.meta.env.VITE_APP_TITLE;

// Built-in Vite env vars (always available)
const isProd = import.meta.env.PROD;               // boolean
const isDev = import.meta.env.DEV;                 // boolean
const mode = import.meta.env.MODE;                 // 'development' | 'production' | custom
const baseUrl = import.meta.env.BASE_URL;          // base URL from config

// TypeScript: declare env types in vite-env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
  readonly VITE_API_URL: string;
  readonly VITE_APP_TITLE: string;
  readonly VITE_FEATURE_FLAG_DARK_MODE: string;
}
interface ImportMeta {
  readonly env: ImportMetaEnv;
}

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free