Code Quality Help

Repository and File Structure Organization

Monorepo Layout

All libraries reside in a single monorepo, enabling shared tooling, unified dependency management, and atomic cross‑package changes. The repository root contains workspace‑level configuration files, while each library is an independent package under a dedicated directory.

root/ .eslintrc.js # shared ESLint configuration .prettierrc # shared Prettier configuration stylelint.config.js # shared Stylelint configuration tsconfig.base.json # base TypeScript configuration angular.json # Angular workspace definition (if using Angular CLI) package.json # workspace scripts and dev dependencies packages/ filter/ # @company/filter notification/ # @company/notification inputs/ # @company/inputs ...

Library Internal Structure

Every library follows a consistent, predictable layout. The core implementation lives under src/lib/, while the single public entry point is src/public-api.ts. Configuration files required by the Angular Package Format (ng-package.json, tsconfig.lib.json) are placed at the library root.

packages/filter/ package.json # library metadata, peerDependencies ng-package.json # ng-packagr configuration tsconfig.lib.json # TypeScript configuration for the build README.md # library documentation src/ public-api.ts # re‑exports everything a consumer may use lib/ filter.module.ts # Angular module (if needed) filter.component.ts filter.component.spec.ts # unit test – colocated filter.component.stories.ts # Storybook story – colocated filter.component.scss filter.service.ts filter.service.spec.ts filter.models.ts # interfaces, enums, types index.ts # barrel that re‑exports from this directory components/ # sub‑components (when needed) ... index.ts services/ ... index.ts ... test.ts # global test setup (optional)
  • ng-package.json defines the entry point as src/public-api.ts and ensures the built output follows the Angular Package Format.

  • tsconfig.lib.json extends the root tsconfig.base.json and enables strict mode for the library.

  • package.json specifies the library name (@company/filter), version, and necessary peer dependencies (@angular/core, @angular/common, etc.).

Test and Storybook Colocation

Unit tests and Storybook stories are kept in the same directory as the source file they relate to. This colocation makes it easy to find, run, and maintain tests and stories, and it naturally scopes changes.

  • Unit tests: files with the suffix .spec.ts (e.g., filter.component.spec.ts). They sit next to the implementation file, not in a separate __tests__ folder.

  • Storybook stories: files with the suffix .stories.ts (e.g., filter.component.stories.ts). A story is mandatory for every exported component; it lives alongside the component’s .ts, .scss, and .spec.ts files.

Barrel Exports and index.ts

To keep public-api.ts concise and maintainable, barrel files (index.ts) are used throughout the library’s internal structure. Each logical group (components, services, directives, models) aggregates its exports into a single barrel, and public-api.ts re‑exports only from those barrels.

Example:

// packages/filter/src/lib/components/index.ts export { FilterComponent } from './filter.component'; export { FilterChipComponent } from './filter-chip.component';
// packages/filter/src/lib/services/index.ts export { FilterService } from './filter.service'; export { FilterStateManager } from './filter-state-manager.service';
// packages/filter/src/public-api.ts export * from './lib/components'; export * from './lib/services'; export { FilterModule } from './lib/filter.module'; export type { FilterConfig, FilterOption } from './lib/filter.models';

This approach:

  • Prevents public-api.ts from growing into a thousand‑line file.

  • Provides clear boundaries and discoverability of public symbols.

  • Allows internal refactoring without touching the public entry point, as long as the barrel exports remain stable.

File Naming Conventions

Consistent naming reduces mental overhead and simplifies refactoring.

  • Components: kebab‑case file name, dots for suffixes – filter-chip.component.ts, filter-chip.component.scss, filter-chip.component.spec.ts, filter-chip.component.stories.ts.

  • Services: kebab‑case with .service.tsfilter-api.service.ts.

  • Directives: kebab‑case with .directive.tshighlight.directive.ts.

  • Pipes: kebab‑case with .pipe.tstruncate.pipe.ts.

  • Modules: kebab‑case with .module.tsfilter.module.ts.

  • Models / types: descriptive kebab‑case with .models.ts or .types.tsfilter.models.ts, notification.types.ts.

  • Styles: .scss extension, colocated with the component unless shared across several components (in which case a dedicated _shared.scss partial may be placed in a styles/ subdirectory).

All source files are located inside src/lib/ (or its subdirectories). Only the files that are explicitly exported from public-api.ts (directly or through barrels) become part of the library’s public API.

03 July 2026