Back to Tutorials
angular6/8/2025

The Differences Between Angular 1.X and Angular 2

angularangular 2frontendjavascriptweb components
The Differences Between Angular 1.X and Angular 2

Angular is undoubtedly one of the most popular web application frameworks out there today. It powers countless web apps in the wild, and has cemented its fame as the front-end part of the extremely popular MEAN stack.

A new milestone was added to the history of the framework when the beta of Angular 2 was released in December 2015. It made a dramatic shift towards component-based architecture, rearranged some internal concepts, shunned all backward compatibility with Angular 1.x, and pushed users towards using Microsoft’s Typescript, a superset of the JavaScript language.

All of this created quite a stir in the community.

In this post, we are going to explore the differences between the classic Angular 1.X and the more recent Angular 2. Let’s start by introducing this shiny new version of the framework (currently RC6).

What is Angular 2?

Angular 2 is built around the concept of components, and more precisely, with the Web Components standard in mind. It was rewritten from scratch by the Angular team using Typescript (although you can use it with ES5, ES6, or Dart as well). The digest cycle from Angular 1.X has been replaced by another internal mechanism known as "Change Detection". This feature, along with other improvements and tweaks, yields a considerable increase in performance (up to 5 times faster, according to some official sources).

A Note On Typescript...

We’ll use Typescript for demonstrating the new aspects of Angular 2, mostly because that’s the way the official documentation is written, and you’ll get the most benefits getting to know Angular 2 this way. It’s also safe to assume that most of the tutorials and articles on Angular 2 will also feature Typescript.

Barebones App Comparison

For simplicity’s sake, let’s take Plunkr’s templates for Angular 1.5 and Angular 2 as a foundation, and weed out unnecessary code and files like README. It’ll feature a simple component/directive called "coffee-machine" that’ll insert the string "Have a nice cup of coffee" in the HTML view.

We will analyze the two projects in the next section, but for now, here are the two projects.

Angular 1.X

With this version of Angular, we instantiate the app and declare a directive and a nominal controller in order to keep things simple. Here is the link to the Plunker project.

Here is the index.html file:

<!-- index.html -->
<!DOCTYPE html>
<html ng-app="coffeeApp">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.5.x" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="coffeeController">
    <coffee-machine></coffee-machine>
  </body>
</html>

And a simple app.js file containing our coffeeMachine directive:

// app.js
angular.module('coffeeApp', [])
  .directive('coffeeMachine', function() {
    return {
      restrict: 'E',
      scope: {},
      template: '<p>Have a nice cup of {{serveCoffee()}}</p>',
      link: function(scope, element, attributes) {
        scope.coffee = 'coffee';
        scope.serveCoffee = function() {
          return scope.coffee;
        };
      }
    };
  })
  .controller('coffeeController', function($scope) {
    $scope.coffee = 'coffee';
    $scope.dispenseCoffee = function(coffee) {
      return "Have a nice cup of " + coffee;
    };
  }
);

Angular 2

With Angular 2, we load everything we need before defining our component. This project also comes with a config.js file not included below that loads the needed libraries and define Typescript as the transpiler. Here is the link to the Plunker project, containing the config.js file.

<!-- index.html -->
<!DOCTYPE html>
<html>

  <head>
    <base href="." />
    <title>angular2 playground</title>
    <link rel="stylesheet" href="style.css" />
    <script src="https://unpkg.com/zone.js@0.6.21/dist/zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="https://unpkg.com/typescript@1.8.10/lib/typescript.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <coffee-machine></coffee-machine>
  </body>

</html>
// app.ts
//our root app component
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'coffee-machine',
  template: `<p>Have a nice cup of {{name}}</p>`
})

export class App {
  constructor() {
    this.name = 'coffee'
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})

export class CoffeeModule {}
// main.ts
// main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {CoffeeModule} from './app';

platformBrowserDynamic().bootstrapModule(CoffeeModule)

Bootstrapping

Let's start our comparison by looking at how our applications are set up.

Angular 1.X

We declare our Angular 1.X application via the ng-app directive in our HTML template:

<html ng-app="coffeeApp">

Angular 2

For Angular 2, the application is initiated in our code by registering CoffeeModule via the bootstrapModule() function, making it the "parent" module:

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {CoffeeModule} from './app';

platformBrowserDynamic().bootstrapModule(CoffeeModule)

Where are Directives, Controllers and $scope?

Roughly speaking, a component in Angular 2 replaces what was known as a directive and becomes the foundation of any Angular 2 application. Controllers and $scope are gone. Sorry for your loss, but it was changed with a good reason in mind - the rise of the Web Components standard.

Angular 1.X

In Angular 1.X, we have a very simple controller and a directive:

// app.js
angular.module('coffeeApp', [])
  .directive('coffeeMachine', function() {
    return {
      restrict: 'E',
      scope: {
      },
      template: '<p>Have a nice cup of {{serveCoffee()}}</p>',
      link: function(scope, element, attributes) {
        scope.coffee = 'coffee';
        scope.serveCoffee = function() {
          return scope.coffee;
        };
      }
    };
  })
  .controller('coffeeController', function($scope) {
    $scope.coffee = 'coffee';
    $scope.dispenseCoffee = function(coffee) {
      return "Have a nice cup of " + coffee;
    };
  });

Angular 2

In Angular2, we have a component that encapsulates both a directive and a controller’s capability to expose variables to templates. A component is defined as a class with a @Component decorator.

// app.ts
// imports

@Component({
  selector: 'coffee-machine',
  template: `
      <p>Have a nice cup of {{name}}</p>
  `
})

export class App {
  constructor() {
    this.name = 'coffee'
  }
}

Directives and Local Variable Syntax

Local variables are now defined using the let keyword. Structural directives like ng-repeat and ng-for are now prefixed by an asterisk, and all directives should be written in camelCase:

Angular 1.X

<ul>
  <li>
  ng-repeat="coffee of coffeeList">
    {{coffee.name}}
  </li>
</ul>
<p ng-class="highlight" ng-if="coffee.isReady">Ding!</p>

Angular2

<ul>
  <li ngClass="highlight" *ngFor="let coffee of coffeeList">
    {{coffee.name}}
  </li>
</ul>
<p ngClass="highlight" *ngIf="coffee.isReady">Ding</p>

One-way Data Binding

Angular 1.X used ng-bind directive to bind a property to a value. In Angular 2, this is done by placing the [property] attribute in a tag.

Angular 1.X

<input ng-bind="coffee.name"></input>

Angular 2

<input [value]="coffee.name"></input>

Two-way Data Binding

The ng-model directive used in Angular 1.X is replaced by the [(ngModel)] directive in Angular 2.

Angular 1.x

<input ng-model="coffee.name"></input>

Angular 2

<input [(ngModel)]="coffee.name"></input>

Event Binding

Event binding attributes have also changed. Now they have to be enclosed in (parentheses), or have the on- prefix instead of ng-click.

Angular 1.x

<button ng-click="dispenseCoffee()"></button>

Angular 2

<button (click)="coffee.name"></button>
// or
<button on-click="coffee.name"></button>

Routing

Angular 2 release candidates have gone through several iterations of routers. Explaining all the intricacies would require writing a separate article, but we’ll try to scratch the surface.

Angular 1.x

Let’s remember how we used to do it in Angular 1.X, via an injected $routeProvider service from the ngRoute module.

// app.js
angular.module("coffeeModule", ["ngRoute"])
  .config(function ($routeProvider) {
    $routeProvider
    .when("/coffee", { templateUrl: "coffee.html", controller: "coffeeController" });
  })
 .controller("coffeeController", function ($scope) {
    $scope.message = "Eat at Joe's";
  });

Angular 2

With Angular 2’s new router, we define routes in an external module. We define the path, name, and associate a component with the route.

// app.routes.ts
import { provideRouter, RouterConfig } from '@angular/router';
import { CoffeeComponent } from './coffee.component';

const routes: RouterConfig = [
  {
    path: 'coffee',
    name: 'Coffee Home'
    component: CoffeeComponent,
  },
  // default route definition
  {
    path: '',
    redirectTo: '/coffee',
    pathMatch: 'full'
  },
];
export const APP_ROUTER_PROVIDERS = [
  provideRouter(routes)
];
<!-- index.html -->
<a href="#" [routerLink]="['/coffee', coffee.name]">

Summary

By now it should be pretty obvious that Angular 2 is a completely different and reworked framework. Because of the sheer number of differences, comparing the two is a bit like comparing apples and oranges. Hopefully this article provided some food for thought on the nature of Angular 2, as well as the main differences between the two major versions.

Let’s do a wrap-up:

  • Angular 2 is a completely different framework, rewritten from the ground-up, and is not backwards-compatible with the previous versions of Angular.
  • It supports runtime-independent instances which allow more straightforward integration in mobile and native apps.
  • Angular 2 is written in Typescript and official documentation examples emphasize the use of Typescript, although developers can (and probably will continue to) use ES6, ES5 and Dart.
  • The syntax for structural directives, local variables and event bindings have changed.
  • Angular2 has greater performance (at least 5x, and even more in some corner cases) due to the reimagined update loop (aka Change Detection).
  • A brand new router.
  • No more controllers and directives, but instead a component-based architecture.

The team behind Angular has boldly decided to completely overhaul it. Whether we like it or not, these changes will push us, as adopters, to consider things like Typescript and Web Components more closely, as there’s no denying the gravitational pull of decisions from giants like Google on the modern Web ecosystem.

Comments

Loading comments...

Level Up Your Dev Skills & Income 💰💻

Learn how to sharpen your programming skills, monetize your expertise, and build a future-proof career — through freelancing, SaaS, digital products, or high-paying jobs.

Join 3,000+ developers learning how to earn more, improve their skills, and future-proof their careers.

The Differences Between Angular 1.X and Angular 2 | Devmystify