Angular Migration

by wshobson46891e7e60daNo licenseListed Oct 8, 2026Updated Oct 8, 2026

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.

Instructions onlySoftware Development
AI-generated overview

Guides migration of AngularJS applications to Angular, covering hybrid apps, component conversion, dependency injection and routing.

What it does
This skill provides instructions and code patterns for moving an AngularJS (1.x) application to Angular (2+). It covers migration strategies such as big-bang rewrite, incremental hybrid mode with ngUpgrade, and vertical slice migration. It shows before-and-after examples for converting controllers and directives into components, migrating services, adjusting dependency injection in both directions, and rewriting routing. A reference file holds additional templates and worked examples.
When to use it
Use it when upgrading an AngularJS application, planning a framework migration, or modernizing legacy Angular code. It also fits teams running hybrid AngularJS/Angular apps or converting directives, services and routing.
Requirements
No scripts are shipped; it is instructions only. The described work assumes an AngularJS and Angular project with the Angular upgrade module and related framework packages, but the skill itself needs nothing beyond the agent.

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

typescript
// main.ts - Bootstrap hybrid appimport { 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 });  });
typescript
// app.module.tsimport { 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

javascript
// Before: AngularJS controllerangular  .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);    };  });
typescript
// After: Angular componentimport { 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

javascript
// Before: AngularJS directiveangular.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>    `,  };});
typescript
// After: Angular componentimport { 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

javascript
// Before: AngularJS serviceangular.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);    },  };});
typescript
// After: Angular serviceimport { 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

typescript
// Angular serviceimport { Injectable } from "@angular/core";
@Injectable({ providedIn: "root" })export class NewService {  getData() {    return "data from Angular";  }}
// Make available to AngularJSimport { downgradeInjectable } from "@angular/upgrade/static";
angular.module("myApp").factory("newService", downgradeInjectable(NewService));
// Use in AngularJSangular.module("myApp").controller("OldController", function (newService) {  console.log(newService.getData());});

Upgrading AngularJS → Angular

typescript
// AngularJS serviceangular.module('myApp').factory('oldService', function() {  return {    getData: function() {      return 'data from AngularJS';    }  };});
// Make available to Angularimport { 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

javascript
// Before: AngularJS routingangular.module("myApp").config(function ($routeProvider) {  $routeProvider    .when("/users", {      template: "<user-list></user-list>",    })    .when("/users/:id", {      template: "<user-detail></user-detail>",    });});
typescript
// After: Angular routingimport { 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.

Source and attribution

Source:wshobson/agentsinplugins/framework-migration/skills/angular-migrationat commit46891e7

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal