Your Angular app structure will change depending on the scenario, but these tips will help get you started right every time.
When you build a new Angular app, the file structure is something to take special care of. A wrong file structure could impact extensibility, scalability and maintenance in the future.
A flat structure (where everything is available in a single dimension) is suitable for a small project with few components and a single module. But if your application grows with modules, features, components and business entities, you need to find a scalable file structure.
Today let’s look at how to structure your projects in Angular with a scalable and modular file structure. Also, how to organize your code in features and modules in the following topics:
Creating a good file structure in your apps does not make your Angular better, faster or more performant. It makes it easy to navigate source files and understand where everything is. Structure is key to the maintenance of your app.
If you don’t have a good structure, when you or newcomers need to find the place to add or change files, the project quickly becomes complex and makes you feel like finding a safe place in the jungle.
Next, we will discuss implementing structure using modules and splitting app requirements into features.
The official Angular documentation embraces modularity using Angular Modules to group app features and provide a starting point to organize with modules.
The modules help group and encapsulate code, focusing on consistent structure, scalability and modularity and making it easy to find code and maintain it.
The Angular team promotes the following point on structure, with the acronym LIFT:
Structure the app such that you can:
- Locate code quickly
- Identify the code at a glance
- Keep the Flattest structure you can
- And Try to be DRY
The goal is to make it easy to navigate your code and find what you are looking for: the services are in the services, pipes are in this directory, and there is no deeply nested hierarchy to find something—you can reuse components and services rather than creating them again.
By default, the Angular CLI creates the module
app.module, AKA root module. It works as the starting point for your app, which works great for small applications. As we said initially, if your app grows with more features, you can create
extra modules tagged in:
The root module takes responsibility for loading all other modules in your app. When you start a new project, Angular creates the
app.module into the
src/app; it works as your root module.
The core module provides root-scoped singleton services and models used in the whole application and doesn’t have any relation to feature modules.
The feature modules contain an application feature—for example, payment, purchase or teams. Each module has components, directives, pipes, pages and interfaces required by the module, creating each as a block.
Read more about feature modules.
The feature module makes your code self-contained, independent and with a single responsibility focused on specific features.
The share module doesn’t relate to a feature; it lists reusable services, components, pipes or directives used in other feature modules.
Read more about shared modules.
We already have a basic overview of each module type. Let’s put them in action.
To put our skills to the test, we will build the NBA application structure, and the idea is to show how to split the features like players, teams and games, declare the core, and share items.
Using the Angular CLI, create the new project:
ng new NBA
This generates the app.module working as our root module loading core, shared and feature modules.
Next, create three directories
Using the Angular CLI, we create the core module and create the directories for the constants, guards and interceptors provided by the core module to the app.
~/Documents/nba - (master) $ ng g m core/core CREATE src/app/core/core/core.module.ts (190 bytes)
core ┣ constants ┃ ┗ settings.ts ┣ guards ┣ interceptors ┣ models ┃ ┣ game.ts ┃ ┗ players.ts ┗ core.module.ts
The feature directory has multiple modules, each of which is a feature in our app. For example, nba.com provides games, drafts, fantasy, players and teams for each feature or module, giving our users an experience like showing the list of players and going to the details.
Using the Angular CLI, create modules for each app feature—for example,
~/Documents/nba - (master) $ ng g m features/draft CREATE src/app/features/draft/draft.module.ts (192 bytes)
Add everything the module provides into the draft directory like pages, pipes, services, directives and components used around the game context.
The file [featurename].routing.module.ts provides routing into each feature. Read more about routing.
The final structure for the NBA feature:
features ┣ draft ┃ ┣ components ┃ ┣ directives ┃ ┣ pages ┃ ┃ ┣ details ┃ ┃ ┃ ┣ details.component.html ┃ ┃ ┃ ┣ details.component.scss ┃ ┃ ┃ ┣ details.component.spec.ts ┃ ┃ ┃ ┗ details.component.ts ┃ ┃ ┗ list ┃ ┃ ┃ ┣ list.component.html ┃ ┃ ┃ ┣ list.component.scss ┃ ┃ ┃ ┣ list.component.ts ┃ ┃ ┃ ┗ list.module.ts ┃ ┣ draft.module.ts ┃ ┗ teams.routing.module.ts ┣ fantasy ┃ ┣ components ┃ ┣ directives ┃ ┣ pages ┃ ┃ ┣ details ┃ ┃ ┗ list ┃ ┣ fantasy.module.ts ┃ ┗ fantasy.routing.module.ts ┣ games ┃ ┣ components ┃ ┣ directives ┃ ┣ pages ┃ ┃ ┣ details ┃ ┃ ┗ list ┃ ┣ games.module.ts ┃ ┗ games.routing.module.ts ┣ players ┃ ┣ components ┃ ┣ directives ┃ ┣ pages ┃ ┃ ┣ details ┃ ┃ ┗ list ┃ ┣ players.module.ts ┃ ┗ players.routing.module.ts ┗ teams ┃ ┣ components ┃ ┣ directives ┃ ┣ pages ┃ ┃ ┣ details ┃ ┃ ┗ list ┃ ┣ teams.module.ts ┃ ┗ teams.routing.module.ts
The share module doesn’t have any relation to any feature; it provides shared services, modules, components, pipes and more required to communicate between the whole application.
Using the CLI again, create the share module and create everything related to the module into the directory, like components, pipes and services.
~/Documents/nba - (master) $ ng g m share/share CREATE src/app/features/share/share.module.ts (192 bytes)
It looks like this:
share ┣ components ┣ pipes ┣ services ┗ share.module.ts
Perfect, we finished the base structure. If tomorrow we need to add a new feature like a playoff or a new feature, create a new module in the feature directory.
For the app sample, check out the Github repository.
And check out this great resource from Angular: Angular File Structure
We’ve covered a lot of ground. Let’s recap so we have a clear idea about what a features and modules are and why they are important.
Share the structure with your team about the plan: split your app into feature modules and keep one module per feature, use core and share modules to avoid duplication, and share components and services in the app.
Remember, there’s no blueprint for structuring your Angular app—it will change depending on each scenario, but I hope this helps to start building your app.
We have plenty more Angular Basics posts to help you on your next steps. Check them out!
Developers! Our premier dev conference is back! Hosted in Boston and remotely, this is the event to check out (here are 7.5 reasons why). We hope you’ll join us this September 11-14!
Dany Paredes is a Google Developer Expert on Angular and loves sharing content and writing articles about Angular, TypeScript and testing in his blog and on Twitter (@danywalls).
Subscribe to be the first to get our expert-written articles and tutorials for developers!
All fields are required
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.