JJ.
Back to Blog

How to Structure Your Vue.js Project Correctly

By Jiss Johnson 6 min read Architecture

A house is only as strong as its foundation. The same applies to your Vue.js applications. If you don't organize your files and folders properly from day one, your project will quickly become a mess. Let's look at the best way to structure a modern Vue.js application.

The Ideal Root Structure

When you use create-vue to generate a new project, it gives you a basic src/ folder. However, for a real-world application, you need to expand it. Here is the standard folder structure used by professional teams:

src/
├── assets/          # Static files like images, fonts, and global CSS
├── components/      # Reusable Vue components (buttons, modals, cards)
├── composables/     # Reusable Vue 3 Composition API logic
├── layouts/         # Page wrappers (e.g., MainLayout, AuthLayout)
├── router/          # Vue Router configuration
├── services/        # API calls and external services
├── stores/          # Pinia or Vuex state management
├── views/           # Page components (Home.vue, About.vue)
├── App.vue          # The main root component
└── main.js          # The entry file that mounts the Vue app
        

1. Components vs. Views

Many beginners confuse components and views. A simple rule is:

  • Views (or Pages): These are directly linked to a URL route. For example, HomeView.vue or DashboardView.vue. They usually fetch data and pass it down.
  • Components: These are reusable pieces of UI that you use inside your views. Examples include Navbar.vue, PrimaryButton.vue, or UserCard.vue.

2. The Power of Composables

In Vue 3, you can write standalone logic functions called "Composables". If you find yourself writing the same piece of code in multiple components (like checking if the user is clicking outside a menu, or formatting a date), you should extract it into a file in the composables/ folder. By convention, name these files starting with "use", like useClickOutside.js.

3. Keep API Calls in Services

Do not write fetch() or axios.get() directly inside your Vue components! This makes testing difficult and your code messy. Create a services/ folder and put your API logic there. For example, create an authService.js file that exports a login() function. Then, import and call that function in your component.

4. Manage Global Data in Stores

If a piece of data needs to be accessed by many different pages (like the current user's profile, or items in a shopping cart), keep it in the stores/ folder using Pinia. If the data is only used on one page, keep it as local state inside the component using ref() or reactive().

Final Thoughts

By following this folder structure, your code will be predictable. When a new developer joins your team, they will immediately know where to look for an API call, where to find a button component, and where the page layouts live. Consistency is the secret to maintainable code.

JJ

Jiss Johnson

Senior Vue.js Engineer helping companies build scalable frontend architectures. Open to new opportunities.