DEV Community

Cover image for Vue - App Architecture
Michał Dulik
Michał Dulik

Posted on

Vue - App Architecture

When it comes to project structure Vue has no documentation specifying a particular structure, it does provide a good starting layout (folder-by-type) generated with Vue CLI.

Folder-by-type Vue-CLI

Folder by type is the most common architecture in Vue projects, it is simple and comes by default with every Vue app created using Vue CLI.

With this type of architecture you separate your files by types, for instance you store your components store routes utils etc. in their corresponding folders.

...
└── src
    ├── main.ts  
    ├── App.vue          
    ├── assets
    │   └── logo.png  
    └── components
        └── HelloWorld.vue
...
Enter fullscreen mode Exit fullscreen mode

This is a pretty good architecture for small projects. However, as your app grows up you quickly notice that it becomes harder to navigate and develop, especially when you are focused on working on a specific feature.

Let's say you have a store management application with three features, which are the orders, products and clients. Working on a product's feature, you have to jump between several folders (assets, components, routes, stores, tests, etc.) and find the files that correspond to that feature.

When your project gets more and more features, this becomes really unmanageable, and you will end up with bloated component routes and store folders.

Pros:

  • Most developers are familiar with this structure
  • Ensures a flat folder structure

Cons:

  • Each directory contains items that usually aren't relative to each other
  • It can get quite tricky to find out which files are used by which features

Folder-by-feature

Folder by feature or in other words, the modular architecture puts all of your files related to a specific feature into its own folder.

...
└── src
    ├── main.ts  
    ├── App.vue          
    ├── modules
        ├── products
        │   ├── image.jpg
        │   ├── ProductsModule.vue
        │   ├── routes.ts
        │   ├── index.ts
        │   └── ...
        ├── order
        │   └── ...
        └── client  
            └── ...
...
Enter fullscreen mode Exit fullscreen mode

You can notice that in this architecture, the root folders in the modules directory hold only feature related files.

Inside each module folder, you can have any structure that you want, as long as you expose the common module interface for registering it.

However, if you use folder-by-feature, you end up losing information about the type of file (because it's no longer in a components, store or assets folder).

Pros:

  • The folder structure itself communicates the application features
  • Separated files by feature

Cons:

  • Sometime it is hard to draw the boundaries of the feature exactly

Which is the right one to pick ?

Unfortunately, there is no right or wrong here. Based on what I've seen, I can tell you that folder by feature performs better when it comes to scaling.

Hybrid structure:

Use both folder-by-feature and folder-by-type:

...
└── src
    ├── main.ts  
    ├── App.vue          
    ├── modules
        ├── core
        │   ├── components
        │   │   └── MyButton.vue
        │   └── store
        │   │   └── GlobalStore.ts
        │   └── ...
        ├── products
        │   ├── assets
        │   ├── components
        │   ├── pages
        │   ├── store
        │   ├── middlewares
        │   ├── ProductsModule.vue
        │   ├── routes.ts
        │   ├── index.ts
        │   └── ...
        ├── order
        │   └── ...
        └── client  
            └── ...
...
Enter fullscreen mode Exit fullscreen mode

Now we have mixed features and types folders:

  • assets, components and middlewares are the type ones

  • products, orders and clients are the features

Countless have been the hours of me trying to decide what structure to choose. I have tried both of them over the past years. I have come up to the conclusion that the Hybrid structure is the best one for me.

PS.

I was thinking about making a tutorial series about Vue's modular app architecture. Let me know in the comments what you thinki about it.

Bye ✋

Top comments (1)

Collapse
 
arthur_chf profile image
Arthur • Edited

Thanks for your article. However, I don't really agree with the architectures you propose. Of course, modular architecture allows you to separate by functionality, but you end up finding all types of files in them (you always get lost). And with hybrid architecture, you have to repeat all the file types by feature, which is a bit tedious when a new feature is added. The architecture I'm proposing (and adopting on all my projects) is effectively a mixed approach to separation by type and by functionality, but in this way :

└── src
    ├── main.ts
    ├── App.vue
    ├── assets
    └── components
        ├── products
        │   ├── Product.vue
        ├── orders
        │   └── ...
        └── clients
            └── ...
    └── interfaces
        ├── products
        │   ├── ProductInterface.ts
        │   ├── ProductTypeInterface.ts
        ├── orders
        │   └── ...
        └── clients
            └── ...
Enter fullscreen mode Exit fullscreen mode