Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    wshobson

    angular-migration

    wshobson/angular-migration
    Coding
    28,185
    3 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Migrate from AngularJS to Angular using hybrid mode, incremental component rewriting, and dependency injection updates...

    SKILL.md

    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 {}
    

    Forms Migration

    <!-- Before: AngularJS -->
    <form name="userForm" ng-submit="saveUser()">
      <input type="text" ng-model="user.name" required />
      <input type="email" ng-model="user.email" required />
      <button ng-disabled="userForm.$invalid">Save</button>
    </form>
    
    // After: Angular (Template-driven)
    @Component({
      template: `
        <form #userForm="ngForm" (ngSubmit)="saveUser()">
          <input type="text" [(ngModel)]="user.name" name="name" required>
          <input type="email" [(ngModel)]="user.email" name="email" required>
          <button [disabled]="userForm.invalid">Save</button>
        </form>
      `
    })
    
    // Or Reactive Forms (preferred)
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    
    @Component({
      template: `
        <form [formGroup]="userForm" (ngSubmit)="saveUser()">
          <input formControlName="name">
          <input formControlName="email">
          <button [disabled]="userForm.invalid">Save</button>
        </form>
      `
    })
    export class UserFormComponent {
      userForm: FormGroup;
    
      constructor(private fb: FormBuilder) {
        this.userForm = this.fb.group({
          name: ['', Validators.required],
          email: ['', [Validators.required, Validators.email]]
        });
      }
    
      saveUser() {
        console.log(this.userForm.value);
      }
    }
    

    Migration Timeline

    Phase 1: Setup (1-2 weeks)
    - Install Angular CLI
    - Set up hybrid app
    - Configure build tools
    - Set up testing
    
    Phase 2: Infrastructure (2-4 weeks)
    - Migrate services
    - Migrate utilities
    - Set up routing
    - Migrate shared components
    
    Phase 3: Feature Migration (varies)
    - Migrate feature by feature
    - Test thoroughly
    - Deploy incrementally
    
    Phase 4: Cleanup (1-2 weeks)
    - Remove AngularJS code
    - Remove ngUpgrade
    - Optimize bundle
    - Final testing
    
    Recommended Servers
    Neon
    Neon
    Svelte
    Svelte
    Supabase
    Supabase
    Repository
    wshobson/agents
    Files