Skip to main content

What is Vite?

  • For Beginners
  • Why We Use It
Vite (pronounced “veet”, French for “fast”) is a build tool that helps you develop web applications quickly. Here’s what it does:
  • Development Server: Starts your app instantly (no waiting!) and updates immediately when you save changes
  • Build Tool: Bundles your code for production, making it fast and optimized for users
  • Modern Approach: Uses native ES modules in development for lightning-fast hot reloading
Think of it this way:
  • Traditional tools (like Webpack) rebuild your entire app on every change → slow
  • Vite only rebuilds what changed → instant updates
Key benefits for learners:
  • Starts in milliseconds, not seconds
  • Works with React, Vue, or vanilla JavaScript
  • Simple configuration (or none at all!)
  • Great for learning because you see changes instantly

Instant Server

Starts dev server in milliseconds with native ESM

Hot Module Replacement

Lightning-fast updates without losing app state

Optimized Builds

Production builds with Rollup for optimal performance

When to Use

  • Perfect For
  • Use Next.js Instead
  • Single-page applications (SPAs)
  • Client-side only apps
  • Prototypes and MVPs
  • Component libraries
  • Static web apps
  • Learning React/Vue

Project Setup

1

Create New Project

# With React
pnpm create vite@latest my-app -- --template react-ts

# With Vue
pnpm create vite@latest my-app -- --template vue-ts

# Vanilla TypeScript
pnpm create vite@latest my-app -- --template vanilla-ts
2

Install Dependencies

cd my-app
pnpm install
3

Start Development

pnpm dev

Best Practices

File Structure

src/
├── assets/
│   └── images/
├── components/
│   ├── ui/
│   └── features/
├── hooks/
├── lib/
│   └── utils.ts
├── styles/
│   └── main.css
├── App.tsx
└── main.tsx

Configuration

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
  }
})

Essential Packages

# UI Framework
pnpm add react react-dom
pnpm add -D @types/react @types/react-dom

# Routing
pnpm add react-router-dom

# Data Fetching
pnpm add @tanstack/react-query axios

# State Management
pnpm add zustand

# Styling
pnpm add tailwindcss postcss autoprefixer
pnpm add -D @tailwindcss/forms @tailwindcss/typography

Common Patterns

React Router Setup

// main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>
)
// App.tsx
import { Routes, Route } from 'react-router-dom'
import HomePage from './pages/Home'
import AboutPage from './pages/About'

export default function App() {
  return (
    <Routes>
      <Route path="/" element={<HomePage />} />
      <Route path="/about" element={<AboutPage />} />
    </Routes>
  )
}

Environment Variables

VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
Environment variables in Vite must be prefixed with VITE_ to be exposed to client code. Never expose sensitive secrets in client-side code!

Code Splitting

import { lazy, Suspense } from 'react'

// Lazy load components
const Dashboard = lazy(() => import('./pages/Dashboard'))
const Settings = lazy(() => import('./pages/Settings'))

export default function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  )
}

Performance Optimization

// Import images as URLs
import logoUrl from './assets/logo.png'

// Import images as modules
import logo from './assets/logo.png?url'

// Import as raw string
import svg from './assets/icon.svg?raw'

// Explicit URL with query
<img src={logoUrl} alt="Logo" />
// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'react-vendor': ['react', 'react-dom'],
          'router': ['react-router-dom'],
          'query': ['@tanstack/react-query']
        }
      }
    },
    chunkSizeWarningLimit: 1000
  }
})
# Build for production
pnpm build

# Preview production build locally
pnpm preview

Deployment

Vercel

# Auto-detected, zero config
vercel

Netlify

# netlify.toml
[build]
  command = "pnpm build"
  publish = "dist"

GitHub Pages

// vite.config.ts
export default defineConfig({
  base: '/repo-name/'
})

Railway

# Build and serve static files
railway up

Vite vs Next.js

FeatureViteNext.js
Dev Speed⚡ InstantFast
SSR/SSG❌ No✅ Yes
API Routes❌ No✅ Yes
File Routing❌ No✅ Yes
Build Tool✅ RollupWebpack/Turbopack
Best ForSPAs, PrototypesFull-stack apps
Start with Vite for learning and prototypes. Graduate to Next.js when you need SSR, API routes, or SEO optimization.