Building a SPA with Aurelia on ASP.NET Core using TypeScript and Sass

build a spa with aurelia and core javascript typescript
Build a SPA with Aurelia

Welcome to this blog series that will show you how to write an Aurelia SPA (Single Page Web Application) using TypeScript and Sass. We will also cover serving the SPA with ASP.NET Core as well as writing a Web API on ASP.NET Core.

The planned architecture is to have two ASP.NET Core projects, one that is hosting our SPA with all the front end bits like JavaScript, HTML and CSS. And one ASP.NET Core project hosting our Web API. Also a project hosting our model and a fake repository is needed (this is where the Web API will get it’s data from). So no “real” persistence layer will be used, at least not initially.

The solution will consist of:

  1. One ASP.NET Core Web Project that will host the Aurelia SPA
  2. An ASP.NET Core Web Project for the Web API
  3. A Class library that will hold the data repository, used by the Web API

The “Aurelia SPA built with TypeScript and Sass on .NET Core” Series

These are the parts of this blog post series about building a SPA in Aurelia.

Part I – How to: Build an Aurelia SPA with TypeScript on ASP.NET Core
Part II – How to: Build a Web API on ASP.NET Core for an Aurelia SPA
Part III – How to: Fetching data from a Web API on ASP.NET Core to an Aurelia SPA
Part IV – How to: Creating Aurelia Custom Elements with TypeScript

This post

This first post will contain a little about tooling and list the prerequisites. The we will go thorough the initial setup of the projects in the solution.


I use Visual Studio for creating the Solution, the Web Projects, the Class Library and work with the c# code in the Web API. You can download the Visual Studio Community edition for free and use that if you like. However, if you prefer not to use Visual Studio, or can’t if you’re on an OS that doesn’t support it, you can always use Yeoman to scaffold out the ASP.NET Core projects and use a different editor.

DOT.NET Core is needed, so install the DOT.NET Core tooling and SDK for using the CLI tools later on.

I personally prefer Visual Studio Code for working with Web Front-end code. Download VS Code for free from their homepage.

For creating the Aurelia SPA, running and debugging it, scaffolding some bits and pieces; we’ll use the Aurelia-CLI. For information on how to install it and the prerequisites for it, see the official documentation.

Node is also needed, if you haven’t got that installed already, check out the the Aurelia CLI pre-reqs where it’s detailed what version is needed.

Project setup

The plan is to have three different projects, one class library holding the data repository, one project hosting the API and one hosting the SPA.
Why having the API in a separate project from the SPA?
In a production scenario, the API shouldn’t be hosted in the same project as the SPA. For learning purposes it is ok to keep it simple, but why not break the projects apart and see if anything unexpected pops up? 🙂

Solution and Project Creation

First let’s create a blank solution to hold all the projects. Then we’ll add a Web Project, a Class Library and a project for our Web API.

  1. Open Visual Studio and select “New Project”
  2. Under Templates > Other Project Types > Visual Studio Solutions we find the Blank Solution option, select it, choose a name for your solution and a location on disc to store it.
  3. Right click the solution in the Solution Explorer window and click Add > New Project…. Select the ASP.NET Core Web Application (.NET Core) project template. Give it a name and click OK.
    Dialogue showing create web project in Visuel Studio 2015
  4. In the following dialogue, choose the Empty template and click OK.
    Dialogue showing second step in create web project in Visual Studio 2015
  5. Time to create the Web API project. Repeat the same steps as in step 3 above but give it a different name. Ending the name with API or WebAPI makes it easy to identify in the solution.
  6. In the next dialogue, choose the Web API project template.
    Dialogue showing create Web API in Visual Studio 2015
  7. Next up, we’re adding the class library that will hold the model and a repository. Right click the solution in the Solution Explorer window and click Add > New Project…. Next select the Class Library (.NET Core) located under the .NET Core projects section, name it and click OK.
    Creating a Class Library project for .NET Core in Visual Studio 2015

Creating the Aurelia App

We will use the Aurelia CLI to help us create the SPA app. I will use TypeScript and Sass as my prefered language and styling toolchain for this article series.

  1. Open a CLI and navigate into the root of the Web project you created earlier (it’s the same folder where the .xproj file is).
    Start the Aurelia project creation using the cli by typing: au new --here
  2. Select platform – choose option 2, ASP.NET Core
  3. Select transpiler – choose option 2, TypeScript
  4. Select CSS processor – choose option 3, Sass
  5. Configure testing – choose option 1, Yes
  6. If satisfied with the configuration, choose to create the project by pressing selecting option 1, Yes
  7. Install project dependencies by selecting Yes
  8. (Optional) Go get a coffee while waiting for dependencies to download… 🙂

    Using the Aurelia CLI to create the SPA

Verify that the Aurelia SPA works and that it is delivered by ASP.NET Core

  1. Use the cli to build the Aurelia app by typing: au build
  2. Start the ASP.NET Core Web server by typing: dotnet run
    Compile the Aurelia Web app and start the ASP.NET Core web server
  3. Open a browser and go to http://localhost:5000
    Hello World in the browser

Hello World, from ASP.NET Core

The message we’re seeing actually has nothing to do with our Aurelia app, it’s served from the ASP.NET application. If we open the Startup.cs file, we can see the response “Hello World!” being written straight into the context.

            app.Run(async (context) =>
                await context.Response.WriteAsync("Hello World!");

Fixing the Front End Web Project

First off, before we start modifying any code, let’s first add a watcher to the Web Project to give us a smoother development experience. The watcher will keep tabs if any relevant files changes and automatically restart the web server for us.

Then we need to enable the ASP.NET request pipeline to serve the HTML, JavaScript and CSS files produced by our Aurelia SPA.

  1. Open the project.json file. Under the tools section, add:
    "Microsoft.DotNet.Watcher.Tools": "1.0.0-*"
  2. In the CLI, type: dotnet restore to download the packages
  3. Start the app and the watcher by typing:
    dotnet watch run
    Restore packages with dotnet restore and start the web server

Now all setup with the watcher keeping tabs of our changes, we can start modifying the ASP.NET Core web project to deliver our Aurelia files!

What we need to do is to remove the code that wrote a response straight to the context, and tell the pipeline to serve static files (like HMTL, CSS and JavaScript files).
To make things easier we will also tell the pipeline to handle “default files” which will take care of empty routes for us and point it to our initial index.html that starts our SPA.

Modify the Startup.cs file, and modify the Configure method so that it looks like this:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

            if (env.IsDevelopment())


After modifying the file and saving, you can see the that the watcher will trigger on the change we made to Startup.cs and restart the app.
dotnet watch restarting the application after a file is modified

Now serving the Aurelia SPA

Refreshing the browser now, still pointing to http://localhost:5000 will show the same message, but it’s actually our Aurelia SPA we’re seeing! Hint – notice the Aurelia title of the tab.
Hello world from our Aurelia SPA

Using the Aurelia watcher

To make sure the Aurelia watcher works (the Aurelia-CLI already has one installed for us!), we could change the project a little and see what happens.

  1. Start the watcher in a CLI, navigate to the root of the project and type: au run --watch
  2. Update the title in the index.html file located under wwwroot/scripts/, change it from “Aurelia” to “Droid Worx”
  3. Test the data binding in action by modifying the app.ts file located under the src/ folder. Changing the message from “Hello World!” to “More to come!”.

This will give us the following result:
Droid Worx the first message

Not seeing the results?

If you’re not seeing any change after refreshing your window (and have made sure that the watcher actually rebuilt the application?)
It can be the case that the browser is caching the page and hence not reloading it properly. To fix this behavior open F12 Developer Tools to empty the cache or disable it.

How To: Empty the cache in Microsoft Edge

How to clear the cache in Edge

How To: Disable the cache in Chrome

Go to Settings->Preferences-Network and check Disable Cache.
disable cache in chrome dev tools

Next part – Web API!

In the next episode we’ll get the Web API going! Building a repository and some models in the Class Library, we’ll see how we can start serving data to our clients.

Get the Code

The code for this blog series is available on my GitHub repo, you can find it here: DWx-Aurelia-dotNETCore

Until next time,
Happy Coding! 🙂

How to: Build an Aurelia SPA with TypeScript on ASP.NET Core
Tagged on:                                 

15 thoughts on “How to: Build an Aurelia SPA with TypeScript on ASP.NET Core

  • October 19, 2016 at 15:13

    Thanks for this. How would we get auto page reloads with browsersync to work?

    • October 20, 2016 at 00:24

      Hi Jason,

      The way I currently setup the project in the article, it’s not possible as far as I know.
      But I do know there are some people out there playing around with browsersync, hot reloading etc.
      I will have to look into it and get back with another post if I come up with something good 🙂


      • November 7, 2016 at 12:35

        This works for me:

        Replace the “serve” task in “aurelia_project/tasks/run.js” with this:

        let serve = gulp.series(
        done => {
        open: false,
        port: 9000,
        logLevel: ‘silent’,
        proxy: {
        target: ‘localhost:5000’
        }, function(err, bs) {
        let urls = bs.options.get(‘urls’).toJS();
        console.log(`Application Available At: ${urls.local}`);
        console.log(`BrowserSync Available At: ${urls.ui}`);

        • November 7, 2016 at 14:18

          Indeed, after some fiddling I got that to work as well. Awesome 🙂
          I actually tried to get this running during the summer, using the proxy as stated in BrowserSync’s documentation. But at that time I could not get it to work.

          Need to add the BrowserSync port to the CORS policy as well to make the example setup in the article work well. I think I’ll write a short post about the setup later.

          Thank you so much, Daniel!

  • Pingback: How to: Build a Web API on ASP.NET Core for an Aurelia SPA - mobilemancer

  • October 28, 2016 at 21:39

    Did you change the Aurelia default settings build on Port 5000 instead of the default 9000?
    When I run “au run –watch” it builds on on a differnt port so breaks the site.

    • October 29, 2016 at 15:14

      The idea with the project setup is to use ASP.NET Core as the host, and that project defaults to serving the app on localhost:5000.
      I didn’t really want to dive into the build concept in the article, but for the purpose of this series it’s quite ok to remove the browsersync dependency from the build scripts.

      If you want remove the startup of browsersync after watch/build, just modify the end of aurelia_project/tasks/run.ts:
      if (CLIOptions.hasFlag('watch')) {
      // run = gulp.series(
      // serve,
      // watch
      // );
      run = gulp.series(
      } else {
      // run = serve;
      run = build;

  • Pingback: How to: Fetch data from Web API on ASP.NET Core to an Aurelia SPA - mobilemancer

  • Pingback: How to: Creating Aurelia Custom Elements with TypeScript - mobilemancer

  • Pingback: Using TypeScript's async/await in Aurelia - mobilemancer

  • Pingback: How To: Configure and Use the Router in an Aurelia SPA - mobilemancer

  • Pingback: How To: Style an Aurelia SPA with Sass - mobilemancer

  • Pingback: Unit Testing and E2E Testing an Aurelia SPA (CLI) - mobilemancer

  • February 24, 2017 at 22:39

    While the following might not be the appropriate approach, I had issues serving the app-bundle.js and vendor-bundle.js given the directory structure (wwwroot and scripts) being on the same level. Had to add the following lines to my Startup.cs (as per the core docs on Static Files).


    app.UseFileServer(new FileServerOptions()
    FileProvider = new PhysicalFileProvider(
    Path.Combine(Directory.GetCurrentDirectory(), @”scripts”)),
    RequestPath = new PathString(“/scripts”),
    EnableDirectoryBrowsing = false

    Was then able to see ‘Hello World’ from the Aurelia project. DWx.Webb in the above examples.

    This alongside app.UseStaticFiles and app.UseDefaultFiles required additional includes. Only issue I am having as of the moment is the ability to be able to run the project from Visual Studio through IIE Express. “tsc” exiting with 1. So CLI it is.

    • February 25, 2017 at 01:03

      Hey Bill,

      Sorry to tell you, but the version of the CLI you are using has has a bug 🙁
      The bundles should not end up in /scripts, they should be transpiled in to the wwwroot/scripts folder in ASP.NET Core based projects.
      I recommend you get another version of the CLI and setup the project again. Or check the aurelia.json file in my GitHub repo to see how the build target should be defined.

      Although, adding a file provider, like you did, is the solution when serving files outside of wwwroot 🙂 But for a basic project, it just shouldn’t be necessary.

      As for running the project form Visual Studio you need to turn off the automatic TypeScript compilation. If you do that you should be able to serve the project from IISExpress, if that is your preferred workflow.

      Good luck,


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.