Structure Angular Apps in 2021
Tags: angular, webdev, productivity, beginners
Published: 2021-04-23 07:28:03

There are many ways one can structure an Angular app. But this is how I structure my applications for extensive flexibility, scalability, and small initial bundle size.

![Alt text of image](http://95.182.121.107:7009/images/1680/how-to-structure-angular-apps-in-2021.webp)

**Core**: The things that are absolutely essential for the app to start.
**Features**: Business logic. Contains modules, components, services, and other angular building blocks (if required) for a particular business feature.
**Shared**: Components so dumb that it hurts!
**Pages**: Routed components with lazy loaded modules.

###Core

Core directory is the place where you put singleton services, injection tokens, constants, app configurations, pipes, interceptors, guards, auth service, utils, etc. that will be used app-wide. If there is something which is specific to the application itself, deployment, CI/CD, API, and the Developer — chances are, it belongs to the core.

![text of image](http://95.182.121.107:7009/images/1681/fig1-example-core-directory.webp)

###Features

Business features live in this directory. Make a module per feature. That module can contain components, directives, pipes, services, interfaces, enums, utils, and so on. The idea is to keep things close. So, a pipe, that is solely used in the Speakers module should not be defined in the global scope or inside Core. The same goes for any other angular building block required by this module only.

![of image](http://95.182.121.107:7009/images/1682/fig2-an-example-feature-module.webp)

Components are prefixed according to the module name e.g.- if the module name is SpeakersModule, components would be named SpeakerAbcComponent, SpeakerXyzComponent etc.

**Keep the component tree inside the directory flat**. That means, if SpeakerListComponent is the parent and SpeakerListItemComponent is child, do not create speaker-list-item component inside the speaker-list directory.
The prefixed naming should be clear to indicate such a relation. The idea is to be able to see what components reside in the module at a glance.

Feature modules can import other features and obviously from shared modules.

###Shared

Consider shared modules a mini library for your UI components. They are not specific to a single business feature. They should be super dumb that you can take all the components, drop in another angular project, and expect to work (given the dependencies are met). You might already know that wrapping UI components provided by other libraries such as Material, ng-zorro-antd, ngx-bootstrap, etc. is a good practice. It protects you from their API changes and allows you to replace the underlying library if required. Components in shared modules are a good place for such wrapping.

![of image](http://95.182.121.107:7009/images/1683/fig3-example-shared-directory.webp)

**Do not make a giant SharedModule**, rather granularize each atomic feature into its own module (see Fig-3). Criss-cross import of atomic shared modules is allowed, but try to minimize as best as possible. To bring a flavor of a tiny library, you could even prefix the directories & modules with your angular application’s custom prefix (by default it is app ).

Thanks for reading!