vite-mastery

0.2 · difficulty 1/4 · 5 min read

A working Vite project in five minutes

Scaffold a React + TS project with create-vite and learn what every file in the directory means.

Vite 8.1Stable

Scaffolding

bash
pnpm create vite@latest hello-vite --template react-ts
cd hello-vite
pnpm install
pnpm dev

Open http://localhost:5173 and you should see the default Vite welcome page. A few things are worth noticing:

  • Cold start took under a second, and we did nothing to optimize Vite
  • Edit a string in src/App.tsx and the browser updates without a refresh (HMR)
  • The project root has no webpack.config.js-style monster

Directory anatomy

text
hello-vite/
├── index.html         ← Vite's entry — not a JS file under src
├── vite.config.ts     ← config entry
├── package.json
├── tsconfig.json
├── src/
│   ├── main.tsx       ← React mount point
│   ├── App.tsx
│   └── vite-env.d.ts  ← global types Vite injects
└── public/            ← static assets that bypass the build

The most counter-intuitive bit: index.html sits at the project root, not under public/. Vite treats index.html as the entry node of the module graph. The line <script type="module" src="/src/main.tsx"> is where Vite finds every source file from.

What one line of config buys you

ts
// vite.config.ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"

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

Once @vitejs/plugin-react is installed, you get for free:

  • React Fast Refresh (component state preserved during HMR)
  • JSX compilation
  • automatic JSX runtime support, so most new files do not need import React from "react"

We'll take this plugin apart later.

What The Four Commands Actually Do

The setup sequence looks like simple scaffolding, but it maps to four different project phases:

CommandWhat actually happens
pnpm create vite@latestDownloads create-vite and writes the minimal template files
pnpm installInstalls Vite, the React plugin, React runtime packages, and TypeScript-related dependencies
pnpm devStarts the Vite dev server and serves source through native ESM
Opening localhost:5173The browser requests index.html, then follows module imports into your source files

When pnpm dev starts quickly, do not assume Vite already compiled the whole project. It prepared the server and dependency cache; source modules are transformed when the browser asks for them.

Verify Three Things Immediately

After the first successful run, do not stop at the welcome page. Run three quick checks:

  1. Edit React component text: change src/App.tsx and confirm the page updates without a full reload.
  2. Edit CSS: change src/App.css and confirm styles hot-update as well.
  3. Open the Network panel: refresh and observe separate requests for main.tsx, App.tsx, and other source modules.

These checks correspond to Vite's three basic ideas: on-demand source transform, HMR, and native browser ESM. The rest of the guide keeps returning to them.

Common Startup Problems

Triage common failures in this order:

SymptomCheck first
pnpm create vite@latest is slownpm registry, proxy, company network
pnpm dev reports a Node version errorWhether Node satisfies the project requirement
Port is not 51735173 is occupied; Vite tries the next available port
Page opens but HMR does not workBrowser console, WebSocket connection, proxy setup
TypeScript cannot find Vite globalsWhether src/vite-env.d.ts exists

Do Not Rush Into Configuration

The easiest beginner mistake is to add configuration immediately after creating a project. A better order:

  1. Understand why index.html is the entry.
  2. Learn what the plugin array in vite.config.ts does.
  3. Learn the separate jobs of dev, build, and preview.
  4. Only then add aliases, proxies, build output rules, or other real requirements.

Configuration is not better because it arrives earlier. Vite's defaults are intentionally enough for the first stage of most frontend apps.

What Counts As Actually Working

"A page appears in the browser" is only the first step. A Vite project is really working when:

  1. pnpm dev starts and HMR works for both TSX and CSS.
  2. pnpm build produces dist/ without TypeScript or build errors.
  3. pnpm preview can serve the production output with correct asset paths.
  4. The browser console has no React Refresh preamble, module resolution, or asset 404 errors.

This check order appears again throughout the hands-on projects. Dev working only proves the dev server path. Build and preview passing means the production build and deployment paths are basically sound.

Self-check

  1. Why is index.html at the project root rather than inside public/?
  2. After pnpm dev, the Network panel shows lots of ?t=xxxxx query strings. What are they?
  3. Without any plugin, can Vite compile .tsx files? Why?