Project structure and the CLI

Vite · Essentials · 10 min

Vite's conventions differ from older tools, and knowing them avoids broken paths.

In a Vite project, `index.html` is the entry point and sits at the project root, not in public/. Vite reads it, follows <script type="module" src="/src/main.ts">, and builds the module graph from there. During build it rewrites the HTML with hashed asset URLs. Multi-page apps simply have several HTML files.

Typical layout:

  • index.html: entry; may reference /src/... paths, which are resolved from the project root.
  • src/: your code and imported assets. Anything imported is processed, hashed and tree-shaken.
  • public/: files copied as-is to the output root, served at /. Use it for robots.txt, favicon.ico or files that must keep exact names. Reference them with absolute paths (/robots.txt) and never import them.
  • vite.config.ts (optional): configuration.

The CLI:

  • vite (or vite dev): dev server on port 5173, --host to expose it on your network, --open to launch a browser.
  • vite build: production build into dist/.
  • vite preview: serve dist/ locally on port 4173. Not a production server.

Scripts in package.json usually map dev, build and preview to these. For TypeScript projects, templates run tsc -b before vite build, because Vite only strips types and never type-checks.

Example

my-app/
├── index.html            # entry point (at the root!)
├── public/
│   └── robots.txt        # copied as-is -> /robots.txt
├── src/
│   ├── main.ts           # <script type="module" src="/src/main.ts">
│   ├── App.tsx
│   └── assets/logo.svg   # imported -> processed and hashed
├── vite.config.ts
└── package.json
    "scripts": {
      "dev": "vite",
      "build": "tsc -b && vite build",   // Vite strips types, tsc checks them
      "preview": "vite preview"
    }

Remember

  • index.html at the root is the entry point
  • Imported files are processed; public/ files are copied verbatim
  • dev on 5173, preview on 4173
  • Vite strips TypeScript types but never type-checks

Watch out for

  • Importing files from public/, which bypasses hashing and breaks with a non-root base.

Check yourself

  1. Where should a file live if it must be served at exactly `/robots.txt`, unprocessed?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: vite.dev/guide/