Skip to content

Folder structure

Raphaël Balet edited this page May 6, 2025 · 26 revisions

Reglements

Naming convention: Folders & Files

  • kebab-case
  • should become increasingly more specific as you read from left to right
// Example
src
└─+ app
    └─+ pages
       └─+ home
           ├── home.page.ts
           └─+ home-descriptipn
               └── home-description.component.ts

The structure

Note: + indicates that the folder has additional files.

public
├─+ fonts
├─+ i18n
├─+ icons
   └── [name]-[direction]-[color].svg
├─+ img
   └─+ components
       └── [page, component, ...]-[name]
           └── bg-desktop.jpg
           └── bg-mobile.jpg
├─+ js
├─+ json
├─+ pdf
└─+ video

src
├─+ app
   ├─+ pages
      ├─+ auth
         ├─+ login
         ├─+ register
         └─+ auth-layout
      └─+ [page]
          ├── [page].page.html
          ├── [page].page.scss
          ├── [page].page.ts
          ├── [page].module.ts
          └─+ [page]-[name]
              ├── [page]-[name].component.html
              ├── [page]-[name].component.scss
              ├── [page]-[name].component.ts
              ├── [page]-[name].module.ts
              └─+ [components, modals, ...]
   ├─+ configs
      ├── [name].config.ts
      └── global.config.ts
   ├─+ core
      ├─+ animations
         └── global.ts
      ├─+ interceptors
         ├── version.interceptor.ts
         └── auth.interceptor.ts
      ├─+ guards
         ├── auth.guard.ts
         └── admin.guard.ts
      ├─+ directives
         └── validation.directive.ts
      ├─+ services
         ├── dal.service.ts
         ├── session.service.ts
         └── [another-api].service.ts
      ├─+ bases
         └── base-[type].[service, query, component].ts
      └─+ models
          ├── core.enums.ts
          ├── core.d.ts // interfaces
          └── core.models.ts
          └── core.types.ts
   └─+ shared
       ├─+ components
          └── [name]
           	└── [name].component.ts
       ├─+ layouts
          └── [name]
           	└── [name].layout.ts
       ├─+ modals 
          └── [name]
           	└── [name].modals.ts
       ├─+ pipes
          └── [name]
           	└── [name].pipe.ts
       ├─+ services
          └── [name]
           	└── [name].service.ts
       └─+ vendors
           ├─+ components
              └── [name].component.ts
           └─+ layouts
               └── [name].layout.ts
├─+ environments
   ├── environment.prod.ts
   └── environment.ts
└─+ styles
    ├─+ base
       ├── _colors.scss
       ├── _img.scss
       ├── _reset.scss
       └── _typography.scss
    ├─+ components
       ├── _buttons.scss
       └── _gallery.scss
    ├─+ themes
       ├── _admin.scss
       └── _theme.scss
    ├─+ utils
       ├── _functions.scss
       ├── _mixins.scss
       └── _variables.scss
    ├── _shared.scss
    └── main.scss

Logic explained

folder description
public Contains static assets
- i18n International language files
- icons Contains only .svg files
pages Contains different pages
- [page] Page name (ex: home, about)
- [page]-[name] Contains the component
configs Contains global logic, normally constant variables
core App core logic
- guards For restricted routes
- store Storing values coming from the services
- services Getting values from an API or a Database
- bases Intended to be extended (inheritance)
- models  
- - enums Enumeration of constant variable
- - interfaces Contain globally used types
- - models Type that has function let var = new MyModel({})
shared Used many times by different elements
- components Imported directly by the pages (ex: footer)
- directives logic like longPress or other event listener
- layouts Positioning of many components
- modals Reused modal
- pipes Converting data directly inside the html
- vendors Third-party code

Core vs Shared vs Children

Core

Contains the code that is specific to the application and implements the Cross-Cutting Concerns of the applications.

  • Should be imported only once, usually into the app.module.ts
  • Services are usually {provideIn: 'root'} And therefore singelton

Shared

Contains the code that is being reused across different components

Children

Elements that are only used within a specific folder and not shared elsewhere.

// Example: Auth might require its own dedicated layout
└─+ pages
    └─+ auth
        ├─ login
          └─ login.page.ts
        ├─ signup 
          └─ signup.page.ts
        └─ layout  
           └─ auth.layout.ts

Layouts & pages: Why not components only

Visual example available here

In large-scale projects, the components folder can grow overwhelming very quickly.
To reduce complexity and improve maintainability, we divide components into distinct categories:

Components

What isn’t a page nor a layout

  • Examples: Card, Sidebar, Table, ...
  • Naming convention:
    • File: card.component.ts
    • Class: CardComponent

Pages

Route destinations, typically mapped to URLs

  • Examples: Home, Login, Blogs, ...
  • Naming convention:
    • File: home.page.ts
    • Class: HomePage

Layouts

Define the structure and positioning of UI areas

  • Examples: Main website layout (Sidenav, main content & footer), Auth layout (logo & Centered container) , Article (Header, Content), ...
  • Naming convention:
    • File: main.layout.ts
    • Class: MainLayout

Etc...

Logical elements can also be moved into their own dedicated folder if the project requires it.

Note: Avoid creating a logical folder if it would contain three or fewer components.

  • Examples: modals, buttons, ...
  • Naming convention:
    • File: [name].[element].ts
    • Class: [Name][Element]

TsConfig paths

Additionally, you could add the following to your tsconfig.json file.

"baseUrl": "./src",
"paths": {
  "@auth/*": ["app/pages/auth/*"],
  "@pages/*": ["app/pages/*"],
  "@configs/*": ["app/configs/*"],
  "@bases/*": ["app/core/bases/*"],
  "@guards/*": ["app/core/guards/*"],
  "@store/*": ["app/core/store/*"],
  "@models/*": ["app/core/models/*"],
  "@services/*": ["app/core/services/*"],
  "@components/*": ["app/shared/components/*"],
  "@directives/*": ["app/shared/directives/*"],
  "@layouts/*": ["app/shared/layouts/*"],
  "@modals/*": ["app/shared/components/modals/*"],
  "@pipes/*": ["app/shared/pipes/*"],
  "@vendors/*": ["app/shared/vendors/*"],
  "@shared/*": ["app/shared/*"],
  "@app/*": ["app/*"],
}

Summary

I've done my best to be as exhaustive as my current knowledge allows. However, integrating additional libraries , such as NgRx, TanStack, and others, will inevitably require some adjustments to the architecture, though its core principles should remain largely the same.

If you have any suggestions that could help others, please feel free to open a PR.

Acknowledgments

Clone this wiki locally