The Starter App 6.0

This tutorial starts with a bare-bones Angular app. Run the live example (view source) to see the app.

Create the app

Let’s get started. Create a project named angular_tour_of_heroes, using WebStorm or the command line and the angular-examples/quickstart GitHub project. For detailed instructions, see Create a starter project from the Setup for Development page.

Run the app, and keep it running

Run the app from your IDE or the command line, as explained in the Run the app section of the Setup for Development page.

You’ll be making changes to the app throughout this tutorial. When you are ready to view your changes, reload the browser window. This will reload the app. As you save updates to the code, the pub tool detects changes and serves the new app.

Angular app basics

Angular apps are made up of components. A component is the combination of an HTML template and a component class that controls a portion of the screen. The starter app has a component that displays a simple string:


import 'package:ngdart/angular.dart';

  selector: 'my-app',
  template: '<h1>Hello {{name}}</h1>',
class AppComponent {
  var name = 'Angular';

Every component begins with an @Component annotation that describes how the HTML template and component class work together.

The selector property tells Angular to display the component inside a custom <my-app> tag in the index.html.

web/index.html (inside <body>)


The template property defines a message inside an <h1> header. The message starts with “Hello” and ends with {{name}}, which is an Angular interpolation binding expression. At runtime, Angular replaces {{name}} with the value of the component’s name property. Interpolation binding is one of many Angular features you’ll discover in this documentation.

The starter app’s code

The app contains the following core files:

import 'package:ngdart/angular.dart'; @Component( selector: 'my-app', template: '<h1>Hello {{name}}</h1>', ) class AppComponent { var name = 'Angular'; } |@TestOn('browser') | |import 'package:ngtest/ngtest.dart'; |import 'package:angular_tour_of_heroes/app_component.dart'; |import 'package:angular_tour_of_heroes/app_component.template.dart' as ng; |import 'package:test/test.dart'; | |void main() { | final testBed = NgTestBed<AppComponent>(ng.AppComponentNgFactory); | late NgTestFixture<AppComponent> fixture; | | setUp(() async { | fixture = await testBed.create(); | }); | | tearDown(disposeAnyRunningTest); | | test('Default greeting', () { | expect(fixture.text, 'Hello Angular'); | }); | | test('Greet world', () async { | await fixture.update((c) => = 'World'); | expect(fixture.text, 'Hello World'); | }); | | test('Greet world HTML', () { | final html = fixture.rootElement.innerHtml; | expect(html, '<h1>Hello Angular</h1>'); | }); |} import 'package:ngdart/angular.dart'; import 'package:angular_tour_of_heroes/app_component.template.dart' as ng; void main() { runApp(ng.AppComponentNgFactory); } |<!DOCTYPE html> |<html> | |<head> | <script> | // WARNING: DO NOT set the <base href> like this in production! | // Details: | (function () { | var m = document.location.pathname.match(/^(\/[-\w]+)+\/web($|\/)/); | document.write('<base href="' + (m ? m[0] : '/') + '" />'); | }()); | </script> | | <title>Angular Tour of Heroes</title> | <meta charset="utf-8"> | <meta name="viewport" content="width=device-width, initial-scale=1"> | <link rel="stylesheet" href="styles.css"> | <link rel="icon" type="image/png" href="favicon.png"> | | <script defer src="main.dart.js"></script> |</head> | |<body> | <my-app>Loading...</my-app> |</body> | |</html> |@import url(; |@import url(; | |/* Master Styles */ |h1 { | color: #369; | font-family: Arial, Helvetica, sans-serif; | font-size: 250%; |} |h2, h3 { | color: #444; | font-family: Arial, Helvetica, sans-serif; | font-weight: lighter; |} |body { | margin: 2em; |} |name: angular_tour_of_heroes |description: Tour of Heroes |version: 0.0.1 | |environment: | sdk: '>=2.17.0 <3.0.0' | |dependencies: | ngdart: ^7.1.1 | |dev_dependencies: | ngtest: ^4.1.1 | build_runner: ^2.2.0 | build_test: ^2.1.5 | build_web_compilers: ^3.2.4 | test: ^1.21.0

These files are organized as follows:

  • angular_tour_of_heroes
    • lib
      • app_component.dart
    • test
      • app_test.dart
    • web
      • index.html
      • main.dart
      • styles.css
    • analysis_options.yaml
    • pubspec.yaml

All the examples in this documentation have at least these core files. Each file has a distinct purpose and evolves independently as the app grows.

File Purpose

Defines <my-app>, the root component of what will become a tree of nested components as the app evolves.


Defines AppComponent tests. While testing isn’t covered in this tutorial, you can learn how to test the Tour of Heroes app from the Testing page.


Launches the app in the browser.


Contains the <my-app> tag in its <body>. This is where the app lives!


A set of styles used throughout the app.


The analysis options file. For details, see Customize Static Analysis.


The file that describes this Dart package (the app) and its dependencies. For details, see Pubspec Format.

What’s next

In the next tutorial page, you’ll modify the starter app to display more interesting data, and to allow the user to edit that data.