Skip to content

File and Folder Architecture

There are many different ways we can go about structuring an Angular application in terms of its files and folders, but the one I find works very well and is reasonably straight-forward to follow is a style popularised by the Nx team (which was founded by former Googler’s and people who actually worked on the Angular team at Google).

The way this works within Nx (which relies on modular libraries) is a little different, but I am adapting it to be used in generic Angular projects. The key idea is to have four different folder types.

The four folder types are:

  • feature — for the smart/routed components
  • ui — for the dumb components that make up the UI of the feature
  • data-access — for things like services and state management
  • utils — for helpers and utilities

We will talk more about the roles of each of these folders in more depth in just a moment, but first I want to give you a basic idea of what using this structure looks like.

Generally speaking, we consider the feature to be whatever the routed smart component is. For example, if we had a HomeComponent that was routed to when the user visited the /home route, then the HomeComponent would be our “feature”. Since we generally only have one smart/routed component per feature, we will generally exclude the feature folder type and instead opt for a structure like this:

Folder structure

We have the HomeComponent at the root of the home folder since it is our “feature”, and then we have folders for everything that supports that feature: ui, data-access, and utils. We will not always use all of these folders, we will just add them as they are required.

Now let’s talk about the role of each folder type in more depth.

The Feature Folder

As we just discussed, the feature folder is responsible for holding our routed/smart components, but to make things simpler we can omit this folder if we have just a single smart component for our feature.

We already have a good idea of what a smart component is from our previous lesson.

The UI Folder

The ui folder is for anything related to displaying the user interface for this feature, which generally means our dumb/presentational components like lists, search bars, buttons, and so on.

However, we might also use our ui folder to store directives and pipes that are specific to this feature, as these also affect the user interface.

The Data Access Folder

We will use this folder for anything related to data access for this feature specifically. This is often our services. However, a service will only live in the data access folder for a feature if it is intended to be used by that feature only. Often we have global services which are used throughout the application, so something like that would not go here. But something like a state management service that is dedicated to the smart component for this specific feature would go in the data access folder.

The Utils Folder

This one is generally the least used folder, but it can be used for any utility/helper sorts of classes/functions you might create. Maybe you have a checkout feature and in the utils folder you export some method for calculating the total for a user’s order.

The Shared Folder

This is one we haven’t mentioned yet. Generally, we are aiming to keep our code colocated. That means that everything related to the home feature lives within the home folder. Everything related to the clients feature lives within the clients folder. This makes it much easier to find code relevant to what we are working on.

However, some code is shared among multiple different features. That is where the shared folder comes into play. The shared folder also uses the same folder structure of having:

  • ui
  • data-access
  • utils

Theoretically, you could also have shared features (smart components) but I personally never run into this scenario. These folders follow all the same rules as for individual features, but it is for code that is shared among multiple different features.

Let’s take a look at an example from the first real application we will build:

Shared folder

In this case we have the following folders:

  • data-access
  • ui
  • interfaces

Our data-access folder in this case includes the global ChecklistService that is used by multiple features, and also a StorageService to handle saving data to and retrieving it from permanent storage.

The ui folder contains a generic form-modal component that is used in multiple places throughout the application.

One thing to note about the shared folder is that, at least for me, it is often a place to bend the rules a little. For example, we often have interfaces that define our data types that we share globally throughout the application. You could argue that maybe they are best suited to the shared/data-access folder, but I think that’s a bit awkward. I generally place them in shared/interfaces or shared/models.

Another example is something like an Angular route guard or interceptor. These are also something that are generally shared globally, where should they live? They don’t really neatly fit into any of our categories, so it’s fine to just create a specific folder for them if you have them e.g. shared/guards and shared/interceptors. Or, maybe you would prefer to be more strict and categorise them under utils. My point is that it is good to follow this structure we have laid out in general, but if there is a structure that works for you or your team, do that instead. There is no point in following a strict architecture that is actually hurting your development efforts.

Recap

One thing in particular I like about this approach is that following it tends to encourage good application architecture. For example, it encourages the separation of smart/dumb components which I think is probably one of the key ways to improve your application architecture.

And the other benefit of this approach is that it is obviously going to translate very well to an Nx workspace. If you ever do find yourself wanting to transition to using Nx as you get more advanced, you will already have most of the key ideas down, and you will just need to add a few additional concepts like generating libraries on top of that.

    What are the four folder types inspired by the Nx approach to structuring projects?

    When should something be placed in the shared folder?

    Which folder would a dumb component go in?