Skip to content

Folder structure

Raphaël Balet edited this page Apr 16, 2025 · 26 revisions

Reglements

Naming convention

  1. should become increasingly more specific as you read from left to right
  2. no underscores
  3. All lowercase
  4. No special characters

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
         ├─+ auth-login
         ├─+ auth-signup
         ├─+ auth-password-request
         └─+ auth-password-reset
      └─+ [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
       ├─+ fragments
          └── [name]
           	└── [name].fragment.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
           ├─+ fragments
              └── [name].fragment.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
- @pages Contains components
- [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
- fragments Smallest piece of code, shall import not something else
- layouts Positioning of many components
- modals Reused modal
- pipes Converting data inside fragments / components
- vendors Third-party code

Core vs Shared

Extended example here

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

Fragments, 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:

Fragments

Basic, atomic components that do not use any other components

  • Examples: Button, chip, label, ...
  • Naming convention:
    • File: button.fragment.ts
    • Class: ButtonFragment

Components

A complex structure of elements

  • Examples: Sidebar, Card, Table, ...
  • Naming convention:
    • File: sidebar.component.ts
    • Class: SidebarComponent

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

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/*"],
  "@fragments/*": ["app/shared/fragments/*"],
  "@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