Vue.js course Β· Module 1: Vue and Vite

Vite - The Project Propulsion Engine

5 min read
In this lesson6

At NOVA LAB we use the most advanced tools. Vite is our "propulsion engine" - it compiles code faster than a rocket reaching first cosmic velocity!

Why do we need an engine at all? The browser doesn't understand .vue files or TypeScript, and a mission application consists of hundreds of modules that import one another. Older tools, known as bundlers, glued the entire application into one package before showing anything, so the bigger the project, the longer you waited for the server to start and for every fix to appear.

What is Vite?

Vite (a French word meaning "fast", pronounced "veet") is a next-generation build tool. Created by Evan You - the same creator as Vue.js. Vite combines two roles: a development server on which you test the application, and building the production version.

Why is Vite so fast?

  1. Native ES Modules - in development it serves your code to the browser as ES modules, on demand, without bundling the whole application; dependencies from node_modules are pre-bundled once, on the first start
  2. Hot Module Replacement - after you save a file, it swaps only the changed module, without reloading the page, regardless of the project size
  3. Native tooling - up to version 7 Vite used esbuild (which, according to the documentation of that time, pre-bundled dependencies 10-100x faster than bundlers written in JavaScript) and Rollup for production builds; since Vite 8 both roles have been taken over by Rolldown, a bundler written in Rust, and the code is processed by Oxc

Fuel: Node.js

The engine needs fuel, and that fuel is Node.js. Before you run the project wizard, check in the terminal which version you have installed:

1node --version

The Vue documentation currently requires Node.js 22.18 or newer from the 22 line, or 24.12 or newer. On an older version the tools may print warnings or refuse to start at all, so always do this step first.

Initializing a Mission Project

To launch a new system project, use the startup protocol. This command downloads and runs create-vue, the official Vue project wizard, and the @latest suffix guarantees its newest version:

1npm create vue@latest

The wizard will ask about mission configuration. You select features in the list with the space bar and confirm with Enter:

1β—‡  Project name (target directory):
2β”‚  mars-control-system
3β”‚
4β—‡  Use TypeScript?
5β”‚  Yes
6β”‚
7β—‡  Select features to include in your project:
8β”‚  Router (SPA development), Pinia (state management), Vitest (unit testing), Linter (error prevention), Prettier (code formatting)
9β”‚
10β—‡  Select experimental features to include in your project:
11β”‚  none
12β”‚
13β—‡  Skip all example code and start with a blank Vue project?
14β”‚  No

We skip JSX, because in Vue we write templates, and we don't enable experimental features on a production mission. Older versions of the wizard asked the same questions one by one, for example "Add TypeScript? … Yes" or "Add Pinia? … Yes" - the form changed, the choices stayed the same.

Mission System Structure

When it finishes, the wizard leaves a folder with this structure:

1mars-control-system/
2β”œβ”€β”€ public/           # Static assets (icons, manifests)
3β”œβ”€β”€ src/
4β”‚   β”œβ”€β”€ assets/       # Graphics, CSS styles
5β”‚   β”œβ”€β”€ components/   # Interface modules
6β”‚   β”œβ”€β”€ views/        # Main screens
7β”‚   β”œβ”€β”€ router/       # Navigation configuration
8β”‚   β”œβ”€β”€ stores/       # Pinia databases
9β”‚   β”œβ”€β”€ App.vue       # Main component
10β”‚   └── main.ts       # System entry point
11β”œβ”€β”€ index.html        # HTML template
12β”œβ”€β”€ package.json      # Dependency manifest
13β”œβ”€β”€ vite.config.ts    # Vite engine configuration
14└── tsconfig.json     # TypeScript configuration

Notice that index.html sits in the root folder, not in public/ - for Vite it is the entry point of the application. The router/ and stores/ folders appear only when you choose Router and Pinia. The component hierarchy starts with App.vue: below it are layout components, such as a header and a sidebar, which surround the views from views/, and the views are made of the smallest modules from components/, such as buttons and cards.

Engine Configuration

The vite.config.ts file (or vite.config.js without TypeScript) tells Vite how to work. The defineConfig function gives your editor hints, the vue() plugin from the @vitejs/plugin-vue package teaches Vite to understand .vue files, and the @ alias is a shortcut to the src folder:

1import { fileURLToPath, URL } from 'node:url'
2
3import { defineConfig } from 'vite'
4import vue from '@vitejs/plugin-vue'
5
6export default defineConfig({
7  plugins: [vue()],
8  resolve: {
9    alias: {
10      '@': fileURLToPath(new URL('./src', import.meta.url))
11    }
12  }
13})

The fileURLToPath and URL functions from the built-in node:url module turn ./src into a full path on disk. The wizard also adds the vueDevTools() plugin here, which we'll come back to with the diagnostic tools. The component code doesn't change - the configuration concerns only the tool - but an import from a deeply nested file becomes short:

1// instead of '../../components/ModuleCard.vue'
2import ModuleCard from '@/components/ModuleCard.vue'

The alias works the same from anywhere in the project, so after you move a file to another folder, you don't fix the paths inside it.

Launching the System

Three commands remain: entering the project folder, installing dependencies and starting the development server:

1cd mars-control-system
2npm install           # Load modules
3npm run dev           # Run in development mode

The system will start at http://localhost:5173 - our local simulator. Change a label in any component and save the file, and HMR will swap the module without reloading the page. I recommend keeping the server running in a separate terminal window for your whole working session. In the next lesson we'll look inside the .vue files that the Vue plugin compiles for the browser.

In the editor below, type a message in the text field or change any label in the code and watch the preview refresh without a reload.

Remember: npm create vue@latest builds the rocket, npm install fuels its modules, and npm run dev fires up the Vite engine on port 5173.

Code for this lesson: src/App.vue
1<template>
2  <div class="nova-lab">
3    <h1>Vite + Vue.js - Lightning-Fast Configuration</h1>
4
5    <section class="info-panel">
6      <h2>Why Vite?</h2>
7      <div class="feature-grid">
8        <div class="feature" v-for="feature in viteFeatures" :key="feature.title">
9          <span class="icon">{{ feature.icon }}</span>
10          <h3>{{ feature.title }}</h3>
11          <p>{{ feature.description }}</p>
12        </div>
13      </div>
14    </section>
15
16    <section class="demo-panel">
17      <h2>Hot Module Replacement in Action</h2>
18      <p>Edit the code and see changes instantly!</p>
19      <div class="hmr-demo">
20        <input v-model="message" placeholder="Type a message..." />
21        <p class="preview">{{ message || 'Your message will appear here...' }}</p>
22      </div>
23    </section>
24  </div>
25</template>
26
27<script setup>
28import { ref } from 'vue'
29
30const message = ref('')
31
32const viteFeatures = [
33  {
34    icon: '',
35    title: 'Lightning-fast start',
36    description: 'Server starts in milliseconds thanks to native ES modules'
37  },
38  {
39    icon: '',
40    title: 'Hot Module Replacement',
41    description: 'Changes visible instantly without page reload'
42  },
43  {
44    icon: '',
45    title: 'Optimized build',
46    description: 'Rolldown under the hood (Vite 8+) for production bundles'
47  },
48  {
49    icon: '',
50    title: 'TypeScript',
51    description: 'TypeScript support out-of-the-box'
52  }
53]
54</script>
55
56<style>
57.nova-lab {
58  min-height: 100vh;
59  background: #0a0e27;
60  color: #e0e0e0;
61  padding: 2rem;
62  font-family: system-ui, sans-serif;
63}
64
65h1 {
66  color: #00ff88;
67  text-align: center;
68  margin-bottom: 2rem;
69}
70
71section {
72  background: rgba(26, 30, 55, 0.8);
73  border: 1px solid #00b4d8;
74  border-radius: 12px;
75  padding: 1.5rem;
76  margin-bottom: 1.5rem;
77  max-width: 900px;
78  margin-left: auto;
79  margin-right: auto;
80}
81
82h2 {
83  color: #00b4d8;
84  margin-top: 0;
85}
86
87.feature-grid {
88  display: grid;
89  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
90  gap: 1rem;
91}
92
93.feature {
94  background: rgba(0, 180, 216, 0.1);
95  padding: 1rem;
96  border-radius: 8px;
97  text-align: center;
98}
99
100.feature .icon {
101  font-size: 2rem;
102}
103
104.feature h3 {
105  color: #00ff88;
106  margin: 0.5rem 0;
107}
108
109.feature p {
110  font-size: 0.9rem;
111  color: #aaa;
112  margin: 0;
113}
114
115.hmr-demo {
116  margin-top: 1rem;
117}
118
119.hmr-demo input {
120  width: 100%;
121  padding: 1rem;
122  background: #1a1e37;
123  border: 2px solid #00b4d8;
124  border-radius: 8px;
125  color: #fff;
126  font-size: 1rem;
127}
128
129.hmr-demo input:focus {
130  outline: none;
131  border-color: #00ff88;
132}
133
134.preview {
135  margin-top: 1rem;
136  padding: 1rem;
137  background: rgba(0, 255, 136, 0.1);
138  border-radius: 8px;
139  color: #00ff88;
140  font-style: italic;
141}
142</style>

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. Why is Vite faster than traditional bundlers?

  2. 2. What command creates a new Vue project with Vite?

  3. 3. What is HMR (Hot Module Replacement) in Vite?

Hands-on tasks in the game

  • Code editor

    Complete the vite.config.js file by adding the Vue plugin and an '@' alias pointing to src/.

  • Vertical ordering

    Arrange the steps for creating a new Vue + Vite project in the correct order:

Useful articles