vite

SKILL.md

Vite

Platform: Web only. Mobile demos use Expo with Metro bundler. See the expo-sdk skill.

Use Context7 MCP (resolve-library-id then query-docs) for full API reference, plugin ecosystem, and advanced configuration options.

Overview

Build tool and development server for Vite 7.x. Provides instant server start, fast HMR, optimized production builds, and first-class TypeScript support.

Install: pnpm add -D vite

Workflows

Initial setup:

  1. Create vite.config.ts with TypeScript types
  2. Install React plugin: pnpm add -D @vitejs/plugin-react
  3. Configure path aliases for clean imports
  4. Set up environment variables with .env files
  5. Test dev server: pnpm vite

Production optimization:

  1. Configure code splitting and chunk optimization
  2. Enable build compression (gzip/brotli)
  3. Run production build: pnpm vite build
  4. Preview build locally: pnpm vite preview

Basic Configuration

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'node:path';

export default defineConfig({
  plugins: [react()],

  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: 5173,
    strictPort: true,
    open: true,
    hmr: { overlay: true },
    proxy: {
      '/api': { target: 'http://localhost:3000', changeOrigin: true }
    }
  },

  build: {
    outDir: 'dist',
    sourcemap: true,
    minify: 'esbuild',
  }
});

Update tsconfig.json paths to match aliases:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"]
    }
  }
}

React with SWC (faster alternative): pnpm add -D @vitejs/plugin-react-swc, import from @vitejs/plugin-react-swc.

Fast Refresh is enabled by default — no configuration needed.

Environment Variables

# .env - Base config (committed)
VITE_APP_NAME=MyApp
VITE_API_VERSION=v1

# .env.local - Local overrides (gitignored — put secrets here)
VITE_API_URL=http://localhost:3000

# .env.development / .env.production - mode-specific defaults

CRITICAL: All env vars must start with VITE_ to be exposed to client code.

// Access in code
const apiUrl = import.meta.env.VITE_API_URL;
const isDev = import.meta.env.DEV;
const isProd = import.meta.env.PROD;
const mode = import.meta.env.MODE; // 'development' | 'production'

// Type-safe env vars — add to vite-env.d.ts or src/env.d.ts
interface ImportMetaEnv {
  readonly VITE_APP_NAME: string;
  readonly VITE_API_URL: string;
}

// Runtime validation
if (!import.meta.env.VITE_API_URL) {
  throw new Error('VITE_API_URL is required');
}

Dynamic config with loadEnv:

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');
  return {
    server: { port: Number(env.PORT) || 5173 }
  };
});

Build Optimization

Code Splitting

export default defineConfig({
  build: {
    chunkSizeWarningLimit: 500, // KB
    rollupOptions: {
      output: {
        manualChunks: {
          'react-vendor': ['react', 'react-dom'],
          'router-vendor': ['react-router-dom'],
          'animation-vendor': ['framer-motion'],
        },
        chunkFileNames: 'js/[name]-[hash].js',
        entryFileNames: 'js/[name]-[hash].js',
        assetFileNames: 'assets/[name]-[hash][extname]',
      }
    }
  }
});

Advanced function-based chunking — use when you need per-view splitting:

manualChunks(id) {
  if (id.includes('node_modules')) {
    if (id.includes('framer-motion')) return 'vendor-animation';
    if (id.includes('react')) return 'vendor-react';
    return 'vendor';
  }
}

Compression

import { compression } from 'vite-plugin-compression2';
// pnpm add -D vite-plugin-compression2

plugins: [
  compression({ algorithm: 'gzip', include: /\.(js|css|html|svg)$/ }),
  compression({ algorithm: 'brotliCompress', include: /\.(js|css|html|svg)$/ }),
]

For production-only minification:

minify: isDev ? false : 'terser',
terserOptions: { compress: { drop_console: true, drop_debugger: true } }

CSS and Assets

PostCSS / Tailwind: Point css.postcss to your postcss.config.js. Enable cssCodeSplit: true (default) for large apps.

Asset handling:

// src/assets — processed by Vite (hashed, optimized)
import logo from '@/assets/logo.svg';

// /public — served as-is, NOT processed
<img src="/images/logo.svg" />
// ❌ Never import from public directory

Inline limit: Assets under 4 KB are inlined as base64 by default (assetsInlineLimit: 4096).

Base path for subdirectory hosting: base: '/my-app/'

Vite 7 Notes

  • Rolldown — new Rust-based bundler (optional, faster builds)
  • Improved TypeScript support and tree-shaking
  • Default config works for most projects; advanced bundler options rarely needed

Best Practices

  • Use path aliases to avoid ../../../ import hell
  • Prefix client env vars with VITE_ for automatic exposure
  • Split large vendors into separate chunks for better caching
  • Use .env.local for secrets — never commit to git
  • Configure proxy for API calls to avoid CORS in development
  • Preview builds before deploying: pnpm vite build && pnpm vite preview
  • Use esbuild for faster builds, terser for smaller output
  • Set strictPort: true to avoid silent port conflicts

Anti-Patterns

  • ❌ Forgetting VITE_ prefix on environment variables
  • ❌ Importing from /public directory instead of src/assets
  • ❌ Committing .env.local with API keys
  • ❌ Not configuring path aliases (messy imports)
  • ❌ Using terser in development (unnecessary slowdown)
  • ❌ Not setting strictPort (silent port conflicts)
  • ❌ Ignoring chunk size warnings (impacts load time)
  • ❌ Missing tsconfig.json paths when using aliases
  • ❌ Hardcoding localhost URLs (use env vars)
  • ❌ Placing all vendors in single chunk (defeats caching)

Feedback Loops

Build analysis:

pnpm vite build
# Output shows chunk sizes:
# dist/js/vendor-react-abc123.js  142.34 kB
# dist/js/index-def456.js          87.21 kB

Preview testing:

pnpm vite build && pnpm vite preview
# Verify: all routes work, assets load, no console errors

HMR speed: Should be < 50ms for most updates. Check Chrome DevTools → Network → Filter by "vite".

Weekly Installs
8
GitHub Stars
43
First Seen
Feb 18, 2026
Installed on
opencode8
gemini-cli8
claude-code8
github-copilot8
codex8
amp8