Skip to content

Folder Structure

Project Structure Overview

A well‑organized Vue 3 project structure helps maintain clarity, modularity, and scalability. Below is a recommended folder structure that aligns with modern Vue 3 conventions and best practices.

Project Structure

[APP] represents your project root directory. Placeholders like <MODULE>, <intent>, and <name> represent your actual module, intent, or file names.

[APP]
├── public/                     # Publicly served static files
│   └── assets/                 # Static assets (images, fonts)
├── src/
│   ├── assets/                 # Shared application assets bundled with the build (not publicly addressable)
│   ├── clients/                # API client wrappers and helpers
│   ├── components/             # Reusable shared Vue components
│   │   ├── icons/              # Icon components
│   │   ├── layout/             # Layout components (e.g., Header.vue)
│   │   └── <intent>/           # Shared components by role (forms, modals, feedback, navigation, etc.)
│   ├── composables/            # Reusable composition functions
│   │   └── <name>.ts           # Example composable file
│   ├── config/                 # Shared configuration files (env, routes, etc.)
│   │   └── <domain>.ts         # Domain-specific config (e.g., api.ts, dates.ts)
│   ├── locales/                # Internationalization files (Optional)
│   │   └── <LANGUAGE>/         # Example locale folder
│   │       └── <MODULE>.json   # Example locale file by module
│   ├── models/                 # Application interfaces and types
│   ├── pages/                  # Page components (root level)
│   │   ├── About.vue           # Example page component
│   │   ├── Home.vue            # Example page component
│   │   └── <MODULE>/           # Module specific page components
│   │       ├── components/     # Component library for the feature
│   │       └── composables/    # Module-only composables (optional)
│   ├── plugins/                # Vue plugins and global configurations
│   ├── queries/                # Query definitions (server state)
│   ├── router/                 # Vue Router (routes.ts, guards.ts)
│   ├── services/               # Business logic and service layer
│   │   ├── api/                # API communication layer and client
│   │   │   └── models/         # API response DTOs
│   │   └── <MODULE>/           # Module-specific service implementations
│   ├── stores/                 # Pinia stores for client-side state
│   │   └── <MODULE>/           # Module-specific store
│   ├── types/                  # Shared utility types and global TypeScript declarations
│   ├── utils/                  # General utility functions
│   └── main.ts                 # Main application entry point
└── tests/
    ├── e2e/                    # End-to-end tests
    │   └── <MODULE>/           # Module-specific e2e test files
    ├── fixtures/               # Shared static or semi-static test data used to run tests
    ├── mocks/                  # Simulated implementations of functions, modules, or APIs used during tests
    ├── stubs/                  # Minimal fake components/services
    └── utils/                  # Test utilities/helper functions

Directory Purpose

DirectoryPurposeSee also
public/assets/Static files served directly by URL (not processed by the build)
src/assets/Files processed by the build (hashed, optimized)
src/clients/API client wrappers and HTTP helpers (e.g., Axios/fetch instances)
src/components/icons/Shared icon components01.Naming
src/components/layout/Layout components (Header, Footer, Sidebar)03.Components
src/components/<intent>/Shared components grouped by role (forms, navigation, feedback)03.Components
src/composables/Reusable composition functions (use<Name>.ts)04.Composables
src/config/Shared configuration files (env, routes, Pinia setup)01.Naming
src/locales/Internationalization files (optional)
src/models/Domain types and interfaces (e.g., User, Order)01.Naming
src/pages/<MODULE>/Page components; each module is self-contained01.Naming, 03.Components
src/pages/<MODULE>/components/Module-scoped components (not shared)03.Components
src/pages/<MODULE>/composables/Module-scoped composables (not shared)04.Composables
src/plugins/Vue plugin registration and global configuration (e.g., app.use(...) setup)
src/queries/Query and mutation definitions for server state05.Queries-Mutations
src/router/Vue Router configuration (routes, guards)08.Routing
src/services/api/API communication layer and response DTOs01.Naming
src/services/<MODULE>/Module-specific business logic and service implementations06.State-Management
src/stores/<MODULE>/Pinia stores for client-side state06.State-Management
src/types/Shared utility types and global .d.ts declarations01.Naming
src/utils/General utility functions01.Naming
src/main.tsApplication entry point; mounts the Vue app06.State-Management
tests/e2e/End-to-end tests organized by module under tests/e2e/<ModuleName>/09.Testing
tests/fixtures/Shared static or semi-static test data; project-specific fixtures may be colocated with their test09.Testing, 01.Naming
tests/mocks/, tests/stubs/Test mocks and stubs (optional; depends on testing setup)09.Testing
tests/helpers/Shared action-oriented test flows and utilities (optional; depends on testing setup)09.Testing

Guidelines for Use

  • Keep each module self-contained under pages/<MODULE>, with colocated components/ and composables/.
  • Place shared logic in utils/ or services/, not in stores or pages.
  • Use models/ for domain-wide types; keep store-specific types colocated with the store.
  • public/ holds files served directly by URL; src/assets/ holds files processed by the build (hashed, optimized). Put nothing in public/ that the build should transform.
  • Don't create "bucket" folders without clear responsibility — every folder must have a defined purpose.
  • Colocate page-specific components and composables under pages/<MODULE>/components/ and pages/<MODULE>/composables/. Move them to src/components/<domain>/ or src/composables/ when reused across modules. See 03.Components and 13.Decision-Matrix for the full decision rules.
  • models/ holds domain types and interfaces (e.g., User, Order). types/ holds shared utility types and global .d.ts declarations. See 01.Naming for naming rules.

See Also

For placement decisions (services vs utils vs composables vs stores), see the Decision Matrix.

Rationale

  • Modularity — each module owns its pages, components, composables, and store slice. Changes to one module stay local.
  • Discoverability — a consistent layout means any developer can locate a file by convention, not by search.
  • No bucket folders — every directory has a single, clear purpose. Ambiguous catch-all folders accumulate unrelated code.
  • Colocation — page-specific code lives beside the page it serves. Shared code lives in dedicated directories. This makes imports predictable and reduces cross-module coupling.
  • Separation of concerns — server-state queries, client-state stores, business-logic services, and UI components each have their own home.