Migrate from AngularJS to Angular using hybrid mode, incremental component rewriting, and dependency injection updates. Use when upgrading AngularJS applications, planning framework migrations, or modernizing legacy Angular code.
SKILL.md
Angular Migration
Master AngularJS to Angular migration, including hybrid apps, component conversion, dependency injection changes, and routing migration.
Use this skill when
Migrating AngularJS (1.x) applications to Angular (2+)
Running hybrid AngularJS/Angular applications
Converting directives to components
Modernizing dependency injection
Migrating routing systems
Updating to latest Angular versions
Implementing Angular best practices
Do not use this skill when
You are not migrating from AngularJS to Angular
The app is already on a modern Angular version
You need only a small UI fix without framework changes
Instructions
Assess the AngularJS codebase, dependencies, and migration risks.
Choose a migration strategy (hybrid vs rewrite) and define milestones.
Set up ngUpgrade and migrate modules, components, and routing.
Validate with tests and plan a safe cutover.
Safety
Avoid big-bang cutovers without rollback and staging validation.
Keep hybrid compatibility testing during incremental migration.
Migration Strategies
1. Big Bang (Complete Rewrite)
Rewrite entire app in Angular
Parallel development
Switch over at once
Best for: Small apps, green field projects
2. Incremental (Hybrid Approach)
Run AngularJS and Angular side-by-side
Migrate feature by feature
ngUpgrade for interop
Best for: Large apps, continuous delivery
3. Vertical Slice
Migrate one feature completely
New features in Angular, maintain old in AngularJS
// After: Angular service
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private http: HttpClient) {}
getUser(id: number): Observable<any> {
return this.http.get(`/api/users/${id}`);
}
saveUser(user: any): Observable<any> {
return this.http.post('/api/users', user);
}
}
Dependency Injection Changes
Downgrading Angular → AngularJS
// Angular service
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class NewService {
getData() {
return 'data from Angular';
}
}
// Make available to AngularJS
import { downgradeInjectable } from '@angular/upgrade/static';
angular.module('myApp')
.factory('newService', downgradeInjectable(NewService));
// Use in AngularJS
angular.module('myApp').controller('OldController', function(newService) {
console.log(newService.getData());
});
Upgrading AngularJS → Angular
// AngularJS service
angular.module('myApp').factory('oldService', function() {
return {
getData: function() {
return 'data from AngularJS';
}
};
});
// Make available to Angular
import { InjectionToken } from '@angular/core';
export const OLD_SERVICE = new InjectionToken<any>('oldService');
@NgModule({
providers: [
{
provide: OLD_SERVICE,
useFactory: (i: any) => i.get('oldService'),
deps: ['$injector']
}
]
})
// Use in Angular
@Component({...})
export class NewComponent {
constructor(@Inject(OLD_SERVICE) private oldService: any) {
console.log(this.oldService.getData());
}
}