This document provides coding conventions and best practices for the SEED Angular app, which is built using Angular v19, TypeScript, RxJS, and TailwindCSS.
Following these guidelines helps keep the codebase clean, maintainable, and scalable.
- References
- Project Philosophy
- Angular Conventions
- TypeScript Conventions
- RxJS Best Practices
- CSS & Tailwind Conventions
- Code Organization & Structure
- General Best Practices
- ESLint & Code Quality
-
Angular Style Guide https://angular.dev/style-guide
-
Google TypeScript Style Guide https://google.github.io/styleguide/tsguide.html
-
Modular Code
- Keep functionality separated and organized into logical modules and lazy-loaded chunks.
- Avoid monolithic, overly large files.
- Write standalone, reusable components whenever possible.
-
Type-Safety First
- Never use
any
. - Always prefer explicit types for parameters, return values, etc.
- Never use
-
Responsive & Modern
- Use TailwindCSS for styling, following a mobile-first approach.
- Design components to support both light and dark themes.
-
Maintainability & Scalability
- Write code that is easy to reason about and test.
- Avoid global SCSS rules that can lead to unexpected cascading effects.
-
Minimal External Dependencies
- Do not use
lodash
or other large libraries that increase bundle size unnecessarily. - Use built-in language features and standard RxJS operators.
- Do not use
-
File & Folder Structure
- Separate logic into distinct modules (e.g.,
feature
modules,shared
modules, etc.). - Keep HTML, SCSS, and TS in separate files unless there is a strong reason to inline them (e.g., a single inline style:
:host { @apply flex }
).
- Separate logic into distinct modules (e.g.,
-
Component Templates
- Use
<ng-template>
for reusable snippets. - Follow Angular's official style guide for naming conventions (
kebab-case
file names,UpperCamelCase
component classes, etc.).
- Use
-
Services & Dependency Injection
- Leverage service classes for business logic.
- Use a pattern of services with private
BehaviorSubject
and publicObservable
streams. - Prefer to pass typed objects into methods rather than multiple parameters.
-
Lifecycle Hooks
- Always unsubscribe from observables in
ngOnDestroy()
to prevent memory leaks.
- Always unsubscribe from observables in
-
Routing & Lazy Loading
- Take advantage of Angular's lazy-loading capabilities for modules to optimize performance.
- Organize routes by feature or domain-specific modules.
-
No
any
- Avoid using
any
at all costs—favor explicit types or generics. - Ensure strong typing for parameters, return values, and variables.
- Avoid using
-
Types vs. Interfaces
- Use types instead of interfaces for consistency, unless there's a specific reason an interface is better.
-
Variable Declarations
- Strive for immutability. Use
const
whenever possible. - Use
let
sparingly (only when reassignments are truly necessary). - Avoid unnecessary mutable state.
- Strive for immutability. Use
-
Class Members
- Prefix private class variables with an underscore (e.g.,
_myService
). - Use the
private
access level as much as possible - if the variable is used in the component html then usepublic
orprotected
. If usingpublic
it isn't necessary to explicitly add thepublic
keyword.
- Prefix private class variables with an underscore (e.g.,
-
Functions & Methods
- Do not create functions with too many arguments; pass typed objects or create dedicated configuration objects.
- Prefer short, single-purpose functions for clarity and testability.
-
Observables > Promises
- Whenever possible, use RxJS Observables instead of Promises.
- Favor a reactive approach.
-
Naming Conventions
- Append a
$
suffix to variables that hold anObservable
(e.g.,myData$
). - Use standard RxJS operators rather than external libraries.
- Append a
-
Unsubscription
- Always unsubscribe from Observables in
ngOnDestroy()
or viatakeUntil
,AsyncPipe
, or other safe subscription patterns to prevent leaks.
- Always unsubscribe from Observables in
-
BehaviorSubjects & Streams
- Use private
BehaviorSubject
for internal state management and expose it as a publicObservable
for read operations.
- Use private
-
Tailwind & Mobile-First
- Use Tailwind's utility-first classes and mobile-first approach for styling.
- Avoid extensive global SCSS that can override or conflict with Tailwind utility classes.
-
Themes
- Consider both light and dark modes in your components and styling.
- Use Tailwind's design tokens or custom variables for theme management.
-
Scoped Styles
- Scope styles to components as much as possible.
- Inline styles are allowed if they're truly minimal and improve readability.
-
Modular Approach
- Group related services, components, and models within feature or domain modules.
- Use
index.ts
files to re-export modules and simplify imports when it makes sense.
-
Reusable Components
- Strive for standalone and reusable components that can be easily shared or moved.
- Abstract common UI patterns into shared modules/components.
-
File Naming
- Use clear, consistent naming conventions (
kebab-case
for file names,PascalCase
for class names). - Append
.component.ts
/.service.ts
/.types.ts
for clarity.
- Use clear, consistent naming conventions (
-
No Local Storage for User Data
- Avoid
localStorage
or similar in-browser storage for user-related settings. - Rely on backend APIs or secure storage methods.
- Avoid
-
Avoid Variable Mutation
- Keep data structures immutable wherever possible.
- Use spread operators and other immutable patterns instead of in-place mutations.
-
Graphics & Media
- Prefer
webp
orsvg
for images to reduce file sizes and maintain quality.
- Prefer
-
TODO Comments
- Use
// TODO:
comments to track incomplete work or future enhancements. - Prefer creating an issue or task in the project management tool for larger items.
- Use
-
Clean Code Principles
- Write readable, self-documenting code.
- Avoid repeating logic—extract functions or components for reuse.
-
Translations
- Add translations for all text that appears in the interface
-
ESLint
- Run ESLint frequently (ideally, before committing).
- Enable ESLint in your IDE to catch problems early.
- Fix lint errors promptly—do not commit code with lint issues.
-
Documentation
- Use JSDoc comment styles for public methods and classes, especially for complex logic.