Angular Migration
Seth HobsonCommunityCreated by Seth Hobson
- Skill
- Guidelines
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach for upgrading AngularJS (1.x) applications to modern Angular (2+). It covers various migration strategies, including Big Bang rewrites and incremental hybrid approaches using ngUpgrade. The documentation details the technical transformation of core concepts such as controllers, directives, services, dependency injection, and routing, while providing a phased roadmap for project execution.
What it does
- Outlines strategies for Big Bang, incremental, and vertical slice migrations.
- Provides configuration patterns for bootstrapping hybrid AngularJS/Angular applications.
- Demonstrates code transformation from AngularJS controllers and directives to Angular components.
- Explains how to migrate services and handle dependency injection across the hybrid boundary.
- Details the transition from AngularJS routing to the Angular Router.
- Offers a phased timeline for managing the migration process from setup to final cleanup.
When to use it
- When planning to modernize a legacy AngularJS application.
- When you need to run AngularJS and Angular side-by-side during a transition.
- When converting specific features or components to modern Angular standards.
- When updating dependency injection systems to match Angular best practices.
Advantages
- Enables incremental modernization without requiring a complete application rewrite.
- Provides clear side-by-side code comparisons for common AngularJS and Angular patterns.
- Includes specific techniques for interoperability between the two frameworks.
- Offers a structured, phased approach to minimize risk during large-scale migrations.
Usage examples
- “How do I bootstrap a hybrid application with both AngularJS and Angular?”
- The skill provides the main.ts and app.module.ts configuration patterns using UpgradeModule to initialize both frameworks simultaneously.
- “Show me how to convert an AngularJS directive to an Angular component.”
- The skill provides a direct comparison showing the transition from a directive definition object to an Angular component class with @Input and @Output decorators.
- “How can I share a service between AngularJS and Angular?”
- The skill explains how to use downgradeInjectable to expose Angular services to AngularJS, and how to use InjectionToken to expose AngularJS services to Angular.
- “What is the recommended timeline for an Angular migration?”
- The skill outlines a four-phase timeline covering setup, infrastructure, feature migration, and final cleanup.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/wshobson/angular-migration/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip angular-migration.zip -d .agents/skills
Documentation by Seth Hobson
Angular Migration
Master AngularJS to Angular migration, including hybrid apps, component conversion, dependency injection changes, and routing migration.
When to Use This Skill
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
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
Gradually replace
Best for: Medium apps, distinct features
Hybrid App Setup
// main.ts - Bootstrap hybrid app
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { UpgradeModule } from "@angular/upgrade/static";
import { AppModule } from "./app/app.module";
platformBrowserDynamic()
.bootstrapModule(AppModule)
.then((platformRef) => {
const upgrade = platformRef.injector.get(UpgradeModule);
// Bootstrap AngularJS
upgrade.bootstrap(document.body, ["myAngularJSApp"], { strictDi: true });
});// app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { UpgradeModule } from "@angular/upgrade/static";
@NgModule({
imports: [BrowserModule, UpgradeModule],
})
export class AppModule {
constructor(private upgrade: UpgradeModule) {}
ngDoBootstrap() {
// Bootstrapped manually in main.ts
}
}Component Migration
AngularJS Controller → Angular Component
// Before: AngularJS controller
angular
.module("myApp")
.controller("UserController", function ($scope, UserService) {
$scope.user = {};
$scope.loadUser = function (id) {
UserService.getUser(id).then(function (user) {
$scope.user = user;
});
};
$scope.saveUser = function () {
UserService.saveUser($scope.user);
};
});// After: Angular component
import { Component, OnInit } from "@angular/core";
import { UserService } from "./user.service";
@Component({
selector: "app-user",
template: `
<div>
<h2>{{ user.name }}</h2>
<button (click)="saveUser()">Save</button>
</div>
`,
})
export class UserComponent implements OnInit {
user: any = {};
constructor(private userService: UserService) {}
ngOnInit() {
this.loadUser(1);
}
loadUser(id: number) {
this.userService.getUser(id).subscribe((user) => {
this.user = user;
});
}
saveUser() {
this.userService.saveUser(this.user);
}
}AngularJS Directive → Angular Component
// Before: AngularJS directive
angular.module("myApp").directive("userCard", function () {
return {
restrict: "E",
scope: {
user: "=",
onDelete: "&",
},
template: `
<div class="card">
<h3>{{ user.name }}</h3>
<button ng-click="onDelete()">Delete</button>
</div>
`,
};
});// After: Angular component
import { Component, Input, Output, EventEmitter } from "@angular/core";
@Component({
selector: "app-user-card",
template: `
<div class="card">
<h3>{{ user.name }}</h3>
<button (click)="delete.emit()">Delete</button>
</div>
`,
})
export class UserCardComponent {
@Input() user: any;
@Output() delete = new EventEmitter<void>();
}
// Usage: <app-user-card [user]="user" (delete)="handleDelete()"></app-user-card>Service Migration
// Before: AngularJS service
angular.module("myApp").factory("UserService", function ($http) {
return {
getUser: function (id) {
return $http.get("/api/users/" + id);
},
saveUser: function (user) {
return $http.post("/api/users", user);
},
};
});// 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());
}
}Routing Migration
// Before: AngularJS routing
angular.module("myApp").config(function ($routeProvider) {
$routeProvider
.when("/users", {
template: "<user-list></user-list>",
})
.when("/users/:id", {
template: "<user-detail></user-detail>",
});
});// After: Angular routing
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
const routes: Routes = [
{ path: "users", component: UserListComponent },
{ path: "users/:id", component: UserDetailComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}Additional patterns and templates
More detailed templates and worked examples live in references/details.md. Read that file for the full pattern library.
Files
- ATTRIBUTION.mdAdded by AutoGineer989 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md7.0 KiB
- references/details.md1.8 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Seth Hobson
- Publisher
- Seth Hobson (Community)
- Source
- wshobson/agents · plugins/framework-migration/skills/angular-migration · commit 4bde316
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Seth Hobson.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download angular-migration.zip