angular-best-practices
191
总安装量
191
周安装量
#1405
全站排名
安装命令
npx skills add https://github.com/boise-state-development/agentcore-public-stack --skill angular-best-practices
Agent 安装分布
codex
153
opencode
152
gemini-cli
143
github-copilot
141
kimi-cli
122
amp
122
Skill 文档
Angular 21 Best Practices
TypeScript
- Use strict type checking
- Prefer type inference when type is obvious
- Avoid
any; useunknownwhen type is uncertain
Components
- Always use standalone components (do NOT set
standalone: trueâ it’s the default in v20+) - Set
changeDetection: ChangeDetectionStrategy.OnPush - Use
input()andoutput()functions instead of decorators - Use
computed()for derived state - Keep components small and single-responsibility
- Prefer inline templates for small components
- Use Reactive forms over Template-driven
- Use
classbindings instead ofngClass - Use
stylebindings instead ofngStyle - For external templates/styles, use paths relative to the component TS file
- Do NOT use
@HostBinding/@HostListenerâ use thehostobject in the decorator instead
State Management with Signals
- Use signals for local component state
- Use
computed()for derived state - Keep state transformations pure and predictable
- Do NOT use
mutateon signals â useupdateorsetinstead
For complex derived state patterns, see references/signal-patterns.md.
Resources (Async Data)
Use resource() for async data fetching with signals:
const userResource = resource({
params: () => ({ id: userId() }),
loader: ({ params, abortSignal }) => fetch(`/api/users/${params.id}`, { signal: abortSignal }),
});
const userName = computed(() => userResource.hasValue() ? userResource.value().name : undefined);
Key resource patterns:
paramsreturnsundefinedâ loader doesn’t run, status becomes'idle'- Use
abortSignalto cancel in-flight requests - Check
hasValue()before accessingvalue()to handle loading/error states - Status values:
'idle','loading','reloading','resolved','error','local'
Templates
- Use native control flow:
@if,@for,@switch(NOT*ngIf,*ngFor,*ngSwitch) - Use async pipe for observables
- Keep templates simple â no complex logic
- Do NOT use arrow functions in templates (not supported)
- Do NOT assume globals like
new Date()are available
Services
- Single responsibility per service
- Use
providedIn: 'root'for singletons - Use
inject()function instead of constructor injection
@Injectable({ providedIn: 'root' })
export class UserService {
private readonly http = inject(HttpClient);
}
Routing
- Implement lazy loading for feature routes:
export const routes: Routes = [
{
path: 'admin',
loadComponent: () => import('./admin/admin.page').then(m => m.AdminPage),
},
];
File Naming
- Routable view components:
file-name.page.ts,file-name.page.html,file-name.page.css - Regular components:
file-name.component.ts - Services:
file-name.service.ts
Icons (ng-icon)
import { NgIcon, provideIcons } from '@ng-icons/core';
import { heroSparkles, heroTrash } from '@ng-icons/heroicons/outline';
@Component({
selector: 'app-example',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [NgIcon],
providers: [provideIcons({ heroSparkles, heroTrash })],
template: `<ng-icon name="heroSparkles" />`,
})
export class ExampleComponent {}
Images
- Use
NgOptimizedImagefor all static images NgOptimizedImagedoes NOT work for inline base64 images
Styling
- Use Tailwind 4.1 for CSS (see tailwind skill if available)
- Angular CDK is available when needed
Accessibility
- MUST pass all AXE checks
- MUST meet WCAG AA minimums: focus management, color contrast, ARIA attributes