Creating a Next Gen JavaScript Application with Aurelia
Key Takeaways
- Aurelia is a modern JavaScript framework that leverages ES6, Web Components, and modularization, providing a solid foundation for building futureproof applications.
- The setup process for an Aurelia application involves using Node.js, npm, and other tools like Gulp and jspm to manage dependencies and streamline development.
- Aurelia utilizes SystemJS for module loading, allowing dynamic importation of ES6 modules and integration with various module formats and package managers.
- The framework supports advanced JavaScript features out of the box, such as classes, modules, and template literals, which facilitate the development of clean and maintainable code.
- Aurelia’s router enables the creation of single-page applications with multiple views and dynamic navigation, enhancing the user experience and application scalability.
Aureli-who?
Aurelia is a next generation framework that leverages modern concepts like ES6, Web Components, and modularization to help you develop performant, futureproof applications. Aurelia is the natural progression of Durandal, an AngularJS competitor built by Rob Eisenberg. Aurelia’s history involves a number of encounters with the AngularJS team over the years. It’s for this reason that many aspects of the framework might feel familiar to the AngularJS developers among you.New Technologies
As I said, Aurelia is a “next generation” framework and as a consequence the tools it uses may be new to some of you. It runs on Node.js, and uses npm but it relies on a few cool new pieces of tech that we’ll look at briefly below:Gulp
This one isn’t so new but it’s a core part of Aurelia’s setup. We’ll use Gulp to pipe all our files through various tasks to ensure our application is all wired up and ready to go.ES6 Module Loader Polyfill
The ES6 module loader is a pollyfill for theSystem
dynamic module loader that was part of the original ES6 specification. The System
loader is in the process of being written into browser specifications but in the meantime this polyfill provides a futureproof solution that we can use today.
The loader allows us to dynamically load modules defined in the ES6 module syntax using the System.import
method:
System.import('mymodule').then(function(m) { ... });
In addition to loading ES6 modules, the loader allows to load other module syntaxes through the use of hooks.
SystemJS
With its slightly confusing name, SystemJS is essentially a collection of loader hooks for the ES6 module loader that enable us to load modules from npm, jspm, ES6 Modules and more. You can think of it as a feature rich module loader built on the future proof foundation of the ES6 Module Loader Polyfill.jspm
jspm is a package manager, like npm, designed to be used with SystemJS. It allows us to install packages from various sources and exposes those to our app so we can easily import them with SystemJS.Let’s Get Set up
I’m going to assume you’ve already installed Node.js, npm and Git, and that you’re familiar with the use of all of them. We’ll start by cloning the Aurelia example application repository from GitHubgit clone https://github.com/aurelia/skeleton-navigation.git
At this point you might ask: “Why are we cloning their example app rather than starting our own from scratch?” The reason is that Aurelia is still in an early stage, thus there’s no simple
aurelia init
command yet that you can run to get your package.json
file and everything set up.
The repository we cloned acts as a good base for our app. It gives us a directory structure, a package manifest, some testing configuration and more. Hopefully one day there’ll be an installer of sorts or we’ll defer to generators like Yeoman the setup. Since we’re using the repository for its configuration and not for their example app itself, you can go ahead and delete the src/
directory, and the styles/styles.css
and index.html
files. We’ll create our own shortly.
We’ll need to install a few other things in order to install our dependencies and kick start our app:
Install gulp globally so that we have access to the gulp CLI:
npm install -g gulp
Then, install jspm globally for the same reason.
npm install -g jspm
Now open the CLI and move to your app’s root directory. Once done, run the command:
npm install
It’ll install our dependencies (from the package.json
file) that include among other things:
- Aurelia tools
- Gulp plugins
- Karma packages for testing
jspm install -y
This is the bit that actually installs the modules that include Aurelia.
Last but not least, let’s install Bootstrap with jspm:
jspm install bootstrap
It’s worth noting that the Aurelia library (contained within these modules) has a number of dependencies on its own, including SystemJS. These will all be installed through dependency management as a result of installing Aurelia itself. I wanted to highlight this point just in case you’re wondering how we have access to things like SystemJS later on despite not having listed it explicitly here in our dependencies.
Time to build an app
We’ve now got a host of tools to help us build our app. What we need next is anindex.html
page:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="jspm_packages/github/twbs/bootstrap@3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="styles/styles.css">
</head>
<body aurelia-app>
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
System.config({
"paths": {
"*": "dist/*.js"
}
});
System.import('aurelia-bootstrapper');
</script>
</body>
</html>
Let’s step through the contents of <body>
.
As I mentioned before, SystemJS allows us to use the System.import
method. In this code, we use it to import the aurelia-bootsrapper
module which kicks off our Aurelia app. We can reference aurelia-bootstrapper
by name thanks to the config.js
file that jspm built for us when we ran jspm install -y
. It maps the module name, to its versioned source. Pretty nifty stuff.
The System.config
bit sets up the paths for our modules, i.e. where to start looking for files.
Now, create the styles/style.css
file and add this code to it:
body { padding-top: 74px; }
You’ll notice that we’re including Bootstrap which we installed earlier. The version may have changed at the time you read this tutorial, so take note of which one jspm installed.
What does the aurelia-bootstrapper do?
Theaurelia-bootstrapper
module will scan the index.html
file for an aurelia-app
attribute. If such attribute specifies a value, then the bootstrapper will load the view/module with that name; otherwise it’ll load a view and module called app.html
and app.js
(which are the defaults). The view will get loaded into the element that has the aurelia-app
attribute (in this case the <body>
tag). It’ll be wired up to the app.js
file.
Let’s create an app.js
and app.html
file in the src
directory to see this in action:
export class App {
constructor() {
this.name = "Brad";
}
}
<template>
Hello, my name is <strong>${name}</strong>
</template>
The first thing you’ll notice is the use of the new ES6 module syntax and the export
keyword. You’ll also notice the use of the new ES6 class syntax and abbreviated function signatures. Aurelia, thanks to SystemJS, comes with support for many exciting ES6 features straight out of the box.
Here we see that app.js
defines a class whose properties are exposed as variables for use in the app.html
file. This class is known as a view-model, since it’s a data structure that backs our view. We print out the variables in our template using ES6 string interpolation syntax.
As the last note, I want to highlight that all the templates in Aurelia are wrapped in a <template>
tag.
Viewing our application in a browser
To get the app up and running in a browser, all we need to do is execute the command:gulp watch
That’ll do all the magic of compiling ES6, live reload, and so on. You should be able to see your app at http://localhost:9000/
. As we expected, we see the contents of our template rendered inside the <bodygt;
tag and we see the property interpolated into the template.
Our gulpfile
has already setup BrowserSync for us so the page will reload if you make any changes.
Time to build our app
In this section, we’ll build a naive Reddit client that has two pages: “Funny” and “Gifs”. We’ll fetch data for each page from Reddit’s API and display a list on each page. When building any application with multiple pages, the core of the application is the router and Aurelia is no different. Let’s change ourapp.js
file, so that it becomes the core module of our app. It’ll be responsible for defining and configuring routing.
import {Router} from "aurelia-router";
export class App {
static inject() { return [Router]; }
constructor(router) {
this.router = router;
this.router.configure(config => {
config.title = "Reddit";
config.map([
{route: ["", "funny"], moduleId: "funny", nav: true, title: "Funny Subreddit"},
{route: "gifs", moduleId: "gifs", nav: true, title: "Gifs Subreddit"}
]);
});
}
}
So, what have we done here?
The first line (import {Router} from "aurelia_router"
) imports the router itself using ES6 module import syntax.
Then, in the App
class we have a static function called inject
. Those of you familiar with AngularJS and not only will already know about dependency injection. The inject
function is going to determine, via dependency injection, what parameters will be available in our constructor function. In this instance, a single parameter will be provided and that’s our router. You can see we’ve altered the constructor function to accept that new parameter.
Dependency injection is powerful because it allows the loose coupling of modules and hands the control flow up a level meaning we can swap out those dependencies during testing or later on when they’re updated.
Now that we have the router available in the constructor of our class, we can use it to set up the routes.
First and foremost we set the router as a property of the class itself with this.router = router;
. This is an Aurelia convention and is necessary for routing to work. Note that naming is important in this instance.
Secondly, we configure our routes by using the config
object provided to us in the callback of this.router.configure
. We set a title
property that will be used to set the title of our pages. We also pass a list of route definitions to the config.map
function.
Each route definition has the following pattern:
{
route: ["", "foo"], // Activate this route by default or when on /foo
moduleId: "foo", // When active, load foo.js and foo.html (module)
nav: true, // Add this route to the list of navigable routes (used for building UI)
title: "Foo" // Used in the creation of a pages title
}
So, in our instance we’ve got two pages that we can visit at /#/funny
and /#/gifs
, with /#/funny
acting as our default page thanks to the ["", "funny"]
list of two route patterns.
We’ll also need to update app.html
to act as our app’s layout file.
<template>
<a href="/#/funny">Funny</a>
<a href="/#/gifs">Gifs</a>
<router-view>
</router-view>
</template>
Can you see the <router-view></router-view>
custom element? This is another built-in piece of Aurelia’s features. You can think of it like an AngularJS directive or just a web component. The view associated with the current route will automatically be loaded into this element.
Next, we’ll need to define the two modules: funny
and gifs
.
Writing our page modules
The “Funny” module
We’ll start withfunny
and then copy it over as a basis for gifs
.
Create a /src/funny.js
file with the following content:
import {HttpClient} from 'aurelia-http-client';
export class Funny {
// Dependency inject the HttpClient
static inject() { return [HttpClient]; }
constructor(http) {
this.http = http; // Assign the http client for use later
this.posts = [];
this.subreddit_url = "http://reddit.com/r/funny.json";
}
loadPosts() {
// Aurelia's http client provides us with a jsonp method for
// getting around CORS issues. The second param is the callback
// name which reddit requires to be "jsonp"
return this.http.jsonp(this.subreddit_url, "jsonp").then(r => {
// Assign the list of posts from the json response from reddit
this.posts = r.response.data.children;
});
}
// This is called once when the route activates
activate() {
return this.loadPosts();
}
}
Also create /src/funny.html
as follows:
<template>
<ul class="list-group">
<li class="list-group-item" repeat.for="p of posts">
<img src.bind="p.data.thumbnail" />
<a href="http://reddit.com${p.data.permalink}">
${p.data.title}
</a>
</li>
</ul>
</template>
The “Gifs” module
Let’s simply copy ourfunny.js
and funny.html
to src/gifs.js
and src/gifs.html
respectively. We’ll need to tweak the contents of gifs.js
a little.
import {HttpClient} from 'aurelia-http-client';
export class Gifs {
static inject() { return [HttpClient]; }
constructor(http) {
this.http = http;
this.posts = [];
this.subreddit_url = "http://reddit.com/r/gifs.json";
}
loadPosts() {
return this.http.jsonp(this.subreddit_url, "jsonp").then(r => {
this.posts = r.response.data.children;
});
}
activate() {
return this.loadPosts();
}
}
Now you should be able to visit localhost:9000/#/gifs
to see a list of gif posts and their links.
Improvements to our layout
We can make a couple of improvements to our layout template using Aurelia’s router. Remember thenav:true
property we set in our route config earlier? What it does is to add a route to a list that we can iterate over in our view in order to build dynamic navigation. Let’s do that now.
Update the contents of app.html
as follows:
<template>
<div class="container">
<ul class="nav navbar-nav navbar-fixed-top navbar-inverse">
<li repeat.for="navItem of router.navigation" class="${navItem.isActive ? 'active' : ''}">
<a href.bind="navItem.href">
${navItem.title}
</a>
</li>
</ul>
<router-view></router-view>
</div>
</template>
Conclusion
Well there you have it! Your first Aurelia application. I’m pretty excited about the future of Aurelia as I think it’s clean and straightforward. Moreover, by using ES6 it keeps everything in reusable, extendable modules. In future tutorials, I’ll look at how we can abstract the duplication between the Gifs and Funny modules, as well as some other improvements and additions to our Reddit client. I’d love to know how your first attempt at app development with Aurelia goes! The complete application that we’ve built during this article can be found hereFrequently Asked Questions about Creating Next-Generation JavaScript Applications with Aurelia
What makes Aurelia a unique JavaScript framework?
Aurelia stands out from other JavaScript frameworks due to its simplicity, modernity, and focus on web standards. It is designed to be simple to understand and use, with a straightforward syntax that reduces the learning curve for developers. Aurelia is also built with modern JavaScript, which means it takes advantage of the latest language features and APIs. Furthermore, Aurelia adheres to web standards, ensuring compatibility and interoperability with other technologies.
How does Aurelia compare to other JavaScript frameworks like Angular or React?
Aurelia, Angular, and React are all powerful JavaScript frameworks, but they have different strengths and use cases. Aurelia is known for its simplicity and adherence to web standards, which makes it a good choice for projects where these factors are important. Angular is a comprehensive framework that includes a wide range of tools and features, making it suitable for large-scale applications. React, on the other hand, is a library for building user interfaces, and it’s often used in combination with other libraries or frameworks.
Can I use Aurelia with TypeScript?
Yes, Aurelia is designed to work seamlessly with TypeScript. In fact, Aurelia’s own source code is written in TypeScript, which demonstrates the framework’s commitment to this statically typed superset of JavaScript. Using Aurelia with TypeScript can help you catch errors early, improve code readability, and take advantage of advanced language features like decorators and interfaces.
How can I get started with Aurelia?
To get started with Aurelia, you’ll first need to install Node.js and npm on your machine. Then, you can install the Aurelia CLI, which is a command-line tool that helps you create, develop, and test Aurelia applications. Once the CLI is installed, you can create a new Aurelia project with a single command. From there, you can start building your application by adding components, services, and routes.
What is Aurelia’s approach to data binding?
Aurelia supports two-way data binding, which means changes in the model automatically update the view, and vice versa. This makes it easy to keep your user interface in sync with your application state. Aurelia’s data binding system is also flexible and powerful, supporting a variety of binding types and syntaxes. For example, you can bind to properties, events, or even custom attributes.
Can I use Aurelia for mobile app development?
While Aurelia is primarily designed for building web applications, it can also be used for mobile app development in combination with technologies like Cordova or Electron. These tools allow you to package your Aurelia application as a native mobile app, which can be distributed through app stores and installed on mobile devices.
How does Aurelia handle routing and navigation?
Aurelia includes a flexible and powerful router that helps you manage navigation in your application. The router allows you to define routes, navigate between views, and handle parameters and query strings. It also supports child routers, which can be used to create complex navigation structures.
What kind of support and community does Aurelia have?
Aurelia has a vibrant and active community of developers who contribute to the framework, create plugins, and help each other solve problems. There are also numerous resources available for learning Aurelia, including the official documentation, tutorials, and online courses. In addition, the Aurelia team provides professional support and consulting services.
Can I use Aurelia with existing JavaScript libraries or frameworks?
Yes, Aurelia is designed to be friendly to other technologies. You can use it alongside existing JavaScript libraries or frameworks, or even integrate it into an existing project. This makes Aurelia a flexible choice that can adapt to your specific needs and technology stack.
How does Aurelia handle testing?
Aurelia supports unit testing and end-to-end testing out of the box. The framework includes a test runner and utilities for mocking and spying, which make it easy to write and run tests for your application. Aurelia also integrates well with popular testing libraries and frameworks, so you can choose the tools that best fit your testing strategy.
Brad is a front-end developer and designer living in Melbourne and working with the team at SitePoint. He tries to keep on top of the ever changing front-end universe by eating JavaScript/CSS for breakfast.

Published in
·Animation·Canvas & SVG·CSS·Design·Design & UX·HTML & CSS·Illustration·Sketch·Typography·November 15, 2016
Published in
·App Development·Mobile·Mobile Web Development·Responsive Web Design·Tools & Libraries·April 14, 2015
Published in
·Debugging & Deployment·Development Environment·Patterns & Practices·PHP·Programming·July 2, 2014