Vite And Project Setup
Vite turns a pile of disconnected files into a fast dev server and an optimized production bundle -- and understanding what it is doing makes the config obvious.
The no-build-step setup from two posts ago has a hard ceiling. The moment you want to import from a second file, or pull in an npm package, or split code across modules, a CDN script tag breaks down. The browser cannot resolve those imports on its own.
That is the problem Vite solves.
What Vite Is
Vite is not primarily a bundler. The actual bundling is handled by Rollup underneath. What Vite provides is developer experience: a fast dev server with instant Hot Module Replacement, a simple config format, and an opinionated but sensible set of defaults that mean you rarely need to touch the configuration.
It was created by the same person who built Vue. The name is French for "fast." The dev server runs on port 5173, which is V-I-T-E in a combination of Roman numerals and leet speak -- a detail that is entirely useless but impossible to forget.
Git Ignore First
Before adding Vite, create a .gitignore so git does not track the things it should never track:
node_modules
dist
.env
coverage
.DS_Storenode_modules is the big one. It can contain hundreds of thousands of files. Check it into git once and your repository is slow forever. The contract is: commit package.json, run npm install to restore node_modules. Everyone who clones the project gets the same packages without any of those files living in the repo.
Run git init if you want to start tracking the project -- even on a private repo, version control is worth having. If you are inside a larger cloned repo, git init creates an inner repo that git treats independently.
Installing Vite
Install Vite and its React plugin:
npm install --save-dev vite@5.4.2 @vitejs/plugin-reactInstall React as a production dependency (not dev -- it ships to the browser):
npm install react@18.3.1 react-dom@18.3.1Configuring Vite
Create vite.config.js at the project root:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
});That is the entire config. defineConfig is a helper that gives editor completions. The only thing Vite needs to know for a React project is that it should apply the React plugin, which handles JSX transformation. Everything else -- module resolution, HMR, dev server, source maps -- is on by default.
Updating the HTML
Remove the two CDN script tags from index.html. Replace them with a single module script pointing at your app entry:
<script type="module" src="./src/App.js"></script>The type="module" attribute is required. Vite only works with ES modules -- the import/export style. If you leave it off, Vite will refuse to serve the file.
Updating the Scripts
Remove the CDN React references from App.js and add proper imports:
import React from "react";
import { createRoot } from "react-dom/client";
const App = () => {
return React.createElement("div", {}, React.createElement("h1", {}, "Padre Gino's"));
};
const container = document.getElementById("root");
const root = createRoot(container);
root.render(React.createElement(App));Notice react-dom/client -- not react-dom. The /client path is the modern entry point. The top-level react-dom still works in React 18 but will likely break in React 19. Use /client and you are forward-compatible.
Add scripts to package.json, plus "type": "module" so tools know this project uses ES modules:
{
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css}\"",
"lint": "eslint"
}
} ExpandVite pipeline: source files and npm packages go in, dev server or production bundle comes out
Three Commands, Three Purposes
npm run dev starts the local dev server. This is the command you run every time you sit down to work. Changes to source files appear in the browser instantly without a full page reload -- that is HMR.
npm run build produces an optimized static bundle in dist/. This is what a CI pipeline runs before deploying to Vercel, Netlify, or any static host. Vite minifies the output, chunks it for caching, and generates source maps.
npm run preview serves the dist/ folder locally, as if it were a production environment. Most developers rarely need this, but it is the right tool when a bug only reproduces in the production build and not in the dev server.
Now run npm run dev and open localhost:5173. The app looks exactly the same as it did with the CDN script tags. The difference is invisible from the browser -- but the project is now set up to scale.
In the next post JSX arrives and the React.createElement calls finally go away.
The Essentials
- Vite wraps Rollup with great developer experience. The bundling engine is Rollup. Vite adds HMR, simple config, and a fast dev server on top.
type: "module"is required. Vite works exclusively with ES modules. Add it topackage.jsonand<script type="module">to the HTML entry point.react-dom/client, notreact-dom. The/clientpath is the modern React 18+ entry point for browser rendering. Use it to stay compatible with React 19.- Three script commands.
devfor local work,buildfor CI/production,previewfor debugging production-only issues. .gitignorebefore first commit.node_modulesanddistshould never be committed.node_modulesis restored bynpm install;distis regenerated bynpm run build.
Further Reading and Watching
- Vite official docs -- Why Vite? -- the Vite team's explanation of why they built it and how it differs from webpack-era bundlers
- Vite Crash Course (Traversy Media) -- a practical walkthrough of Vite setup across different framework types
Keep reading