You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices.
- Use strict type checking
- Prefer type inference when the type is obvious
- Avoid the
anytype; useunknownwhen type is uncertain
- Always use standalone components over NgModules
- Must NOT set
standalone: trueinside Angular decorators. It's the default in Angular v20+. - Do NOT set
changeDetection: ChangeDetectionStrategy.OnPushexplicitly.OnPushis the default in Angular v22+. - Use signals for state management
- Implement lazy loading for feature routes
- Do NOT use the
@HostBindingand@HostListenerdecorators. Put host bindings inside thehostobject of the@Componentor@Directivedecorator instead - Use
NgOptimizedImagefor all static images.NgOptimizedImagedoes not work for inline base64 images.
- It MUST pass all AXE checks.
- It MUST follow all WCAG AA minimums, including focus management, color contrast, and ARIA attributes.
- Keep components small and focused on a single responsibility
- Use
input()andoutput()functions instead of decorators - Use
model()for two-way bound properties with[(prop)]syntax instead of pairinginput()withoutput() - Use
computed()for derived state - Use
linkedSignal()for state derived from multiple reactive sources that must stay synchronized - Prefer inline templates for small components
- Prefer Signal Forms (
@angular/forms/signals) for new forms. They are stable in Angular v22+ and provide signal-based state, type-safe field access, and schema-based validation - When not using Signal Forms, prefer Reactive forms instead of Template-driven ones
- Do NOT use
ngClass, useclassbindings instead - Do NOT use
ngStyle, usestylebindings instead - Do NOT import
CommonModule, import only the directives and pipes the template uses, such asAsyncPipeorDatePipe - When using external templates/styles, use paths relative to the component TS file.
- Use signals for local component state
- Use
computed()for derived state - Keep state transformations pure and predictable
- Do NOT use
mutateon signals, useupdateorsetinstead
- Keep templates simple and avoid complex logic
- Use native control flow (
@if,@for,@switch) instead of*ngIf,*ngFor,*ngSwitch - Use the async pipe to handle observables
- Do not assume globals like (
new Date()) are available.
- Design services around a single responsibility
- Use the
providedIn: 'root'option for singleton services - Prefer the
@Servicedecorator over@Injectable({providedIn: 'root'})for new singleton services (Angular v22+) - Use the
inject()function instead of constructor injection
- Demo app (SSR):
pnpm build --configuration development && node dist/angular-devtools/server/server.mjs→ http://localhost:4000 - Devtools SPA (hot reload):
pnpm devtools:dev→ http://localhost:5173 (requires the SSR server running for RPC data) - Demo app (SPA, no SSR):
pnpm start→ http://localhost:4200 (runsng servewith SSR and hot reload; devtools popup + RPC work without a separate server) - The devtools popup appears on the demo app page; click it to open the inspector panel
- Changes to
app/src/(devtools SPA) are visible live viapnpm devtools:dev; the SSR server serves the SPA built intopackages/ng-devtools/dist/public(or the npm-published copy when it has not been built), so runpnpm devtools:build-pkgto refresh it - To publish: update the version in
packages/ng-devtools/package.json, then runpnpm devtools:publish(the package build bundles the SPA)