From ng
Migrate deprecated Angular patterns to modern equivalents. Auto-invoked when editing NgModule files or using deprecated APIs.
npx claudepluginhub mayeedwin/angular-plugin --plugin ngThis skill uses the workspace's default tool permissions.
**Reference**: https://angular.dev/update-guide
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
Reference: https://angular.dev/update-guide
When reading Angular files, flag these patterns for migration:
| Deprecated pattern | Modern replacement |
|---|---|
*.module.ts with declarations | Standalone components |
*ngIf, *ngFor, *ngSwitch | @if, @for, @switch |
constructor(private svc: Service) | inject(Service) |
ngOnDestroy + Subject + takeUntil | takeUntilDestroyed() |
Class-based CanActivate guard | CanActivateFn functional guard |
Class-based HttpInterceptor | HttpInterceptorFn functional interceptor |
APP_INITIALIZER + factory | provideAppInitializer(() => ...) |
RouterModule.forRoot() | provideRouter(routes) in app.config.ts |
HttpClientModule import | provideHttpClient() in app.config.ts |
BrowserModule import | Remove — not needed for standalone |
platformBrowserDynamic().bootstrapModule | bootstrapApplication(AppComponent, appConfig) |
Zone.js dependency only | Consider zoneless: provideExperimentalZonelessChangeDetection() |
When converting a module-based component:
standalone: true to @ComponentNgModule.imports entries to component's imports arrayNgModule.declarationsloadComponent instead of loadChildrenReplace all structural directives in templates:
<!-- Old → New -->
<div *ngIf="show">...</div>
→ @if (show) { <div>...</div> }
<div *ngIf="show; else other">...</div>
<ng-template #other>...</ng-template>
→ @if (show) { <div>...</div> } @else { ... }
<li *ngFor="let item of items; trackBy: trackById">...</li>
→ @for (item of items; track item.id) { <li>...</li> }
<div [ngSwitch]="status">
<span *ngSwitchCase="'active'">Active</span>
</div>
→ @switch (status) { @case ('active') { <span>Active</span> } }
After migrating control flow, remove CommonModule if it was only providing NgIf/NgFor.
app.config.ts Migration// Old: main.ts + AppModule
platformBrowserDynamic().bootstrapModule(AppModule);
// New: main.ts
bootstrapApplication(AppComponent, appConfig);
// New: app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(withInterceptors([authInterceptor])),
provideAnimationsAsync(),
provideStore(),
provideEffects(),
],
};
// Old
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(): boolean {
return this.auth.isLoggedIn() || (this.router.navigate(['/login']), false);
}
}
// New
export const authGuard: CanActivateFn = () => {
return inject(AuthService).isLoggedIn() || inject(Router).createUrlTree(['/login']);
};
DestroyRef, takeUntilDestroyed@if/@for/@switch stable, @defer stableAlways check package.json Angular version before suggesting a migration — don't suggest APIs unavailable in the project's version.