estructura-app-vue

Structure of a Vue.js Project

  • 6 min

Once we have seen how to create our Vue application, we will see that the project we created has a structure with folders and files (in fact, with many).

In reality, not all projects are exactly the same. In the end, the structure depends on your application, the elements you use… many things.

But, more or less, a “typical” Vue.js project might have a structure similar to this,

my-app/
├── node_modules/
├── public/
├── src/
│   ├── assets/
│   ├── components/
│   ├── views/
│   ├── router/
│   ├── stores/
│   ├── services/
│   ├── utils/
│   ├── App.vue
│   └── main.js
├── .eslintrc.js
├── .gitignore
├── index.html
├── package.json
└── vite.config.js

As I said, it is not a single unchangeable structure. The organization will depend on your project, and even on your tastes. You have room for structure.

But many of the elements are common and frequent in Vue projects. You need to at least know what each thing is.

So let’s review some of them, because at first, it can be a bit overwhelming to see so many files and folders.

Files in the project root

Index.html

HTML entry point of the application:

File/DirectoryFunction
index.htmlMain HTML template; Vue is mounted within this file.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Vue Application</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

Node.js Files

File/DirectoryFunction
package.jsonManages dependencies, scripts, and project metadata.
node_modules/Dependencies installed automatically by npm or yarn.

The package.json file is essential in any Node.js project. It contains metadata about the project, such as its name, version, dependencies, and scripts.

  • Dependencies: Here, all the necessary dependencies for the project are listed.
  • Scripts: Defines useful commands to run common tasks, such as starting the development server or building the project for production.

This directory contains all the Node.js dependencies your project needs. You should not manually modify anything in this directory, as it is managed automatically by npm or yarn.

It contains all dependencies installed via npm install. We do not need to modify anything here directly, as this directory is automatically managed by npm and Vite.

Configuration Files

FileFunction
vite.config.jsCustom configuration for Vite.
.gitignoreList of files and folders that Git should ignore (not version).
.envEnvironment variables for custom configuration.
.eslintrc.jsESLint configuration to ensure code quality.

Depending on whether you are using Vite or Vue CLI, you will find one of these configuration files. Here you can customize the behavior of the development server, the build, and other project-specific configurations.

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
plugins: [vue()],
server: {
port: 3000,
},
});

This file specifies which files and directories should be ignored by Git. It is useful to avoid uploading unnecessary or sensitive files to the repository.

node_modules/
dist/
.env

These files contain environment variables that can be used in your application. For example, you can define the URL of an API or authentication keys.

VUE_APP_API_URL=https://api.example.com

ESLint configuration to maintain code standards:

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended'
  ],
  parserOptions: {
    ecmaVersion: 2020
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}

/src Directory

This is the heart of the project where all the source code resides:

FileFunction
src/Contains all the source code of the application.
src/main.js or main.tsMain entry point of the application; mounts the app to the DOM.
src/App.vueRoot component of the application.

Entry point of the application. Here Vue is mounted and the application is configured.

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

import './assets/main.css'

const app = createApp(App)

app.use(router)

app.mount('#app')

The root component of the application:

<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <header>
    <img alt="Vue logo" src="./assets/logo.svg" width="125" height="125" />
    <div class="wrapper">
      <HelloWorld msg="Welcome to your Vue 3 application!" />
      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
      </nav>
    </div>
  </header>

  <RouterView />
</template>

<style scoped>
header {
  line-height: 1.5;
  max-height: 100vh;
}

/* More styles... */
</style>

Subdirectories of src

DirectoryFunction
src/assets/Resources like images, styles, and fonts, processed by Vite.
src/components/Reusable UI components.
src/views/Main views associated with routes.
src/router/Route configuration with Vue Router.
src/stores/Management of global state (Pinia).
src/services/Modules for accessing APIs or external logic.
src/composables/Reusable functions with the Composition API.
src/utils/General utility functions, like validations or formatting.

This directory contains static resources like images, fonts, and global styles. Unlike files in public/, files in assets/ are processed by Vue’s build system.

import '@/assets/global.css';

This directory stores static resources that will be processed by Vite. For example,

assets/
├── logo.svg
└── main.css

This directory stores reusable Vue components. Components in Vue are independent interface pieces that we can combine to build the application’s structure.

Each Vue component has its own .vue file, which includes the template, script, and styles.

Components should be named using the PascalCase (HelloWorld.vue) or kebab-case (hello-world.vue) format to follow Vue conventions. For example,

components/
├── HelloWorld.vue
├── TheHeader.vue
├── TheFooter.vue
└── ui/
    ├── BaseButton.vue
    └── BaseInput.vue

Here we store the main views of the application, which are usually associated with specific routes in Vue Router. For example,

views/
├── HomeView.vue
└── AboutView.vue

Here we configure Vue Router to manage navigation in our application. For example,

router/
└── index.js

For state management with Pinia (if we use it of course). For example,

stores/
└── counter.js

For APIs and external services. For example,

services/
├── api.js
└── authService.js

Composables are reusable functions that encapsulate shared logic. For example,

utils/
├── useFilterTable.js
└── useValidateNumber.js

For utility functions. For example,

utils/
├── formatter.js
└── validation.js

Remember that these are examples of folders you will commonly find. It does not mean that you have to have all of them by obligation.

Public Folder

The public/ directory contains static files that are served directly without going through Vue’s build process.

Here you can place files like index.html, images, fonts, or any other static resource.

public/
├── favicon.ico
└── robots.txt

Example: If we add an image logo.png in public/, we can access it from:

http://localhost:5173/logo.png

What is the difference between assets and public?

  • Files in src/assets/ are processed by the bundle (they can be imported via modules and optimized, etc)
  • Files in public/ are copied without modifications to the root of the server when we build the application