Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
sap avatar

Migrate

  • 16 installs
  • 293 repo stars
  • Updated August 4, 2026
  • sap/fundamental-ngx

Helps with ai & agent building tasks.

About

migrate is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.

  • migrate
  • AI & Agent Building
  • AI-coding skill

Migrate by the numbers

  • 16 all-time installs (skills.sh)
  • +3 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #11,068 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/sap/fundamental-ngx --skill migrate

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs16
repo stars293
Last updatedAugust 4, 2026
Repositorysap/fundamental-ngx

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

Angular 21+ Migration: $ARGUMENTS

If $ARGUMENTS is empty, ask the user for a component path or folder before proceeding.

Phase 1: Analyze

Read all files in the target path. For each component, directive, or service, scan for migration items below. If a folder is given, process all .ts and .html files within it.

What to migrate

Inputs / Outputs / Models:

  • @Input()input() or input.required()
  • @Input() with setter → input() + linkedSignal() (preferred) or effect() (only for DOM side effects)
  • @Input() + @Output() pair (e.g. value / valueChange) → model()
  • @Output()output()
  • Boolean inputs: add { transform: booleanAttribute }
  • Number inputs: add { transform: numberAttribute }

Host bindings:

  • @HostBinding('class.x')host: { '[class.x]': 'expr()' }
  • @HostBinding('attr.x')host: { '[attr.x]': 'expr()' }
  • @HostBinding('style.x')host: { '[style.x]': 'expr()' }
  • @HostListener('event')host: { '(event)': 'handler($event)' }

Queries:

  • @ViewChild()viewChild() or viewChild.required()
  • @ViewChildren()viewChildren()
  • @ContentChild()contentChild()
  • @ContentChildren()contentChildren()

Template syntax:

  • *ngIf@if
  • *ngFor@for (requires track expression)
  • *ngSwitch / *ngSwitchCase@switch / @case

State management:

  • BehaviorSubject used for local component state → signal()
  • BehaviorSubject + combineLatestcomputed()
  • Subject<void> used only to trigger side effects → effect()
  • effect() that only calls signal.set() for derived state → computed() or linkedSignal
  • Redundant markForCheck() after signal updates → remove
  • Object/array mutation in place + signal.set() with same ref → immutable update with signal.update()

CSS class building:

  • CssClassBuilder + @applyCssClasscomputed() returning class string + host: { '[class]': '_cssClass()' }

Cleanup patterns:

  • Custom DestroyedServiceDestroyRef + takeUntilDestroyed()
  • ngOnDestroy only for destroy$.next() → remove entirely after migration

Decorator cleanup:

  • Remove standalone: true (default since Angular 19)
  • Remove allowSignalWrites option in effect() (the option no longer exists)

Imports:

  • Deprecated *Module classes → individual component/directive imports

Member ordering (ESLint enforced):

1. Decorated properties (any remaining @Input, @Output, @ViewChild) 2. Signal inputs/outputs (input(), output(), model()) 3. Public → Protected → Private fields 4. Constructor 5. Public → Protected → Private methods

What NOT to migrate

Do NOT convert these — they should stay as-is:

  • RxJS for async operations: HTTP calls, WebSocket streams, timers, interval-based logic → keep as Observable
  • BehaviorSubject with complex operators: switchMap, debounceTime, distinctUntilChanged, combineLatest with async sources → keep as RxJS
  • Plain properties with no reactive consumer: If nothing in template, host binding, computed, or effect reads it → keep as plain property, do not wrap in signal()
  • Signals for internal bookkeeping: One-time flags, cached DOM measurements, counters with no reactive consumer → use plain property

Migration is optional for existing code

The migration targets are recommendations, not mandatory fixes. Present all findings but let the user decide scope. Existing @Input() / @Output() decorators are valid — only migrate them if the user wants to or if the code is being substantially reworked.

Phase 2: Present Plan

Output a structured migration plan:

## Migration Plan: [component name]

### Files affected
- path/to/component.ts
- path/to/component.html
- path/to/component.spec.ts

### Inputs / Outputs
| Current | Migration | Notes |
|---------|-----------|-------|
| `@Input() label: string` | `readonly label = input<string>('')` | |
| `@Input() disabled: boolean` | `readonly disabled = input(false, { transform: booleanAttribute })` | |
| `@Input() value` + `@Output() valueChange` | `readonly value = model<T>()` | Two-way binding |

### Host Bindings
| Current | Migration |
|---------|-----------|
| `@HostBinding('class.is-open')` | `host: { '[class.is-open]': 'isOpen()' }` |

### Template Changes
| Current | Migration |
|---------|-----------|
| `*ngIf="condition"` | `@if (condition) { ... }` |
| `*ngFor="let item of items"` | `@for (item of items; track item.id) { ... }` |

### State Management
| Current | Migration | Reason |
|---------|-----------|--------|
| `BehaviorSubject<boolean>` | `signal(false)` | Local state, no async consumers |

### Skipped (intentionally not migrated)
| Item | Reason |
|------|--------|
| `httpData$` Observable | Async HTTP stream |

### Test Updates
- [ ] Replace `component.input = value` with `fixture.componentRef.setInput('input', value)`
- [ ] Update module imports to individual components
- [ ] Verify existing tests still pass after migration

### Docs Updates
- [ ] Update examples if public API changed (input names, usage patterns)
- [ ] Ensure examples use individual imports, not deprecated modules

### Breaking Changes
- [ ] List any renamed/removed inputs or outputs
- [ ] Draft BREAKING CHANGE footer if needed

Stop here and wait for approval before proceeding.

Phase 3: Execute

After approval:

1. Apply all migrations from the approved plan 2. Format code: yarn format 3. Run build: nx run <library>:build 4. Run lint: nx run <library>:lint 5. Run tests: nx run <library>:test --testfile=<spec-file> --skip-nx-cache 6. Report results and any issues

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.