Roadmap › Vue.js 3 (with Pinia, Vue Router & Nuxt basics) › Module: Basics
Lessons in this course (17)
3. Vue 3 project folder structure — with sample files
Basic★ Must knowLesson 3 of 17
npm create vue@latest shop-ui (Vite + Vue 3, optional TypeScript, Router, Pinia, Vitest) creates:
text
shop-ui/
├── index.html mount point <div id="app">
├── public/ static files (favicon)
├── src/
│ ├── main.ts createApp(App).use(router).use(pinia).mount('#app')
│ ├── App.vue root component with <RouterView />
│ ├── router/index.ts route definitions
│ ├── stores/ Pinia stores (cart.ts, auth.ts)
│ ├── views/ page-level components mapped to routes (ProductsView.vue)
│ ├── components/ reusable components (ProductCard.vue, BaseButton.vue)
│ ├── composables/ reusable composition functions (useProducts.ts, useDebounce.ts)
│ ├── services/ API calls (api.ts, productService.ts)
│ ├── assets/ css, images
│ └── types/ shared TypeScript types
├── .env.development / .env.production VITE_API_URL=...
├── vite.config.ts · tsconfig.json · package.jsonts
// src/main.ts
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
createApp(App).use(createPinia()).use(router).mount("#app");
// src/router/index.ts
import { createRouter, createWebHistory } from "vue-router";
export default createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: () => import("../views/ProductsView.vue") }, // lazy-loaded route
{ path: "/products/:id", component: () => import("../views/ProductDetailView.vue"), props: true },
],
});vue
<!-- src/App.vue -->
<template>
<header><RouterLink to="/">Shop</RouterLink></header>
<main><RouterView /></main>
</template>Nuxt projects (the Vue meta-framework, like Next.js for React) use pages/, components/, composables/, server/api/ (server routes) and nuxt.config.ts.