←  Back to blog

A Vite config I actually understand

Apr 09, 2026 · 2 min read tooling vite

My build config had become a haunted house — options copied from blog posts, plugins added to fix errors I no longer remembered, comments that lied. So I deleted it and started from an empty file, adding back only what I could justify out loud. Here’s what survived.

Start with nothing

Vite’s defaults are genuinely good. The honest starting point is an empty object, and most projects never need much more.

import { defineConfig } from "vite";

export default defineConfig({});

Everything below is something I added because a real need showed up — not preemptively.

Path aliases, because relative imports rot

The one quality-of-life change I add to every project. ../../../ is a refactoring hazard; a @ alias is stable.

import { defineConfig } from "vite";
import { fileURLToPath, URL } from "node:url";

export default defineConfig({
    resolve: {
        alias: {
            "@": fileURLToPath(new URL("./src", import.meta.url)),
        },
    },
});

If you use TypeScript, mirror this in tsconfig.json under compilerOptions.paths or the editor won’t follow it.

A dev server that fails loudly

Two settings save real time. strictPort stops Vite from silently hopping to a different port when 5173 is taken — I’d rather know. And explicit proxy rules keep API calls same-origin in dev so cookies and CORS behave like production.

server: {
  strictPort: true,
  proxy: {
    '/api': { target: 'http://localhost:8787', changeOrigin: true },
  },
},

Build options worth their weight

I only touch the build config when a bundle analysis tells me to. The two that earned a place:

build: {
  sourcemap: false,
  rollupOptions: {
    output: {
      manualChunks: { vendor: ['react', 'react-dom'] },
    },
  },
},

Every manual chunk is a bet that a dependency changes less often than your app code. Make that bet on purpose, with numbers — not by reflex.

The rule I kept

For each line I asked: what breaks if I delete this? If I couldn’t answer, it went. The config that’s left is short, boring, and — for the first time in years — something I can read top to bottom and actually understand.

~
Husnul Aman
Full-Stack Developer
Email GitHub
 Keep reading
Type-safe forms without the boilerplate architecturetooling