Getting Started with npm in Visual Studio

npm and Visual Studio Header
Derived from photo by Markus Spiske /, CC-BY

The defacto package manager for JavaScript frameworks and tooling has become npm (node package manager). If you are a Visual Studio developer using Nuget through the years, this may be news to you. Likely, though, you understand there is a much bigger web development world outside of ASP.NET and Visual Studio – and this world uses npm. So why shouldn't you?

Go ahead, continue to get your .NET libraries from Nuget, but get your web frameworks from npm. This post teaches you the npm basics from a Visual Studio perspective. And while the command line is still currently the best place to use npm, there are some nice tricks to learn in Visual Studio as well.

This post assumes you are using Visual Studio 2015. Furthermore, web developers should install Mads Kristensen's prolific Web Extension Pack to get the most current web tooling for Visual Studio. If you don't see some of the described features below in your own installation, it's most likely because you don't have these tools installed.

Good Old Command Line

As much as Visual Studio developers love having a UI for their tools, npm is still most easily used at the command line. There are GUI tools such as Web Essentials Package Installer, but you may find these tools too simple to install packages the way you want.

Beyond installing packages, there are other advantages to using the command line. First, any new npm features debut in the CLI (command line interface) version of the tool so you can more easily take advantage of productivity enhancements. Second, your CLI skills are portable to other web development platforms, IDEs (integreated development environments), or text editors.

One extension in particular, Open Command Line, is a must for any command line work in Visual Studio. It is included in Web Extension Pack or as an individual download here. You can also get these extensions directly from within Visual Studio in the Extensions and Updates Manager. Open Command Line enables you to open the command line (Windows Command Prompt or PowerShell) from anywhere in Visual Studio with keyboard shortcuts or from a right-click in Solution Explorer.

Open Command Line Extension

Even better, when you use these shortcuts, the command line initializes to the directory from which you called the extension. So if you are writing code in C:\git\billion-dollar-idea\FlamingTomatoes\Web\index.html and decide you need a new npm package, press AltSpace and you get this:

Command Prompt


The npm Command Line Basics

So you know how to get to the command line quickly from Visual Studio, now what? First, install NodeJS on your machine. Being that you are using this for development purposes, go head and install the current version instead of the LTS version.

Once installed, npm is available at the command line. Navigate to the directory of your project either manually or with the Open Command Line tool. This is the most basic installation of the Angular 1.x library:

npm install angular

This command makes a request to the public npm registry and downloads the latest version of the Angular package and installs it at the current directory in a folder called node_modules. Furthermore, npm also downloads any dependencies for Angular. You can read more about how npm structures the dependencies here.

The previous example installed the package to a local node_modules folder within the current directory. Some packages, such as those operating as command line tools, require global installation. These packages are not stored in a local node_modules folder but in a centralized location (e.g. C:\Users\<you>\AppData\Roaming\npm). Install packages globally using the -g parameter:

npm install typescript -g

What if you want a specific version of a package? When you want a specific version, append the version to the end of the package name. This installs Angular version 1.4.14:

npm install angular@1.4.14

The npm documentation has a great topic listing the various ways to specify package versions during installation.

Create a package.json File

Ideally, you want to keep a record of which packages you have installed in your project. This record is kept in a file called package.json. This file stores metadata for your application including a listing of packages that can be restored at a later time.

One import reason to keep this listing is source control. It's not ideal to store the contents of every package in source control. By storing the package.json file in source control, you don't have to keep the packages themselves in source control and each individual developer can restore these packages from the npm registry. If you are familiar with how Nuget uses packages.config, the concept is similar.

Visual Studio provides a template for creating a new package.json file making this process familiar to Visual Studio users. Right-click on your web project and select Add -> New File to display the Add New Item dialog. Then under the Web section, select the option for npm Configuration File.

Add New package.json

The contents of the file is incredibly minimal to the point where you may see the npm CLI show warnings. For your purposes of simply obtaining and recording npm packages, this package.json confriguration is sufficient and these warnings are unimportant.

    "version": "1.0.0",
    "name": "",
    "private": true,
    "devDependencies": {

Of course, you can create the package.json file from the command line as well. Use the command:

npm init -f

Using the -f parameter creates the package.json file with default values that you can later edit. Otherwise, the init command prompts for a value for each field. The resulting file looks like this:

    "name": "folder",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {

For the purposes of obtaining and using npm packages, the section you are most concerned about in package.json is "dependencies". When time to publish your project, make sure to learn more about the information listed in the package.json file.

Note: If you know that you do not want your project published online, consider setting "private": true. This setting helps to protect your project from accidentally being published because the npm registry refuses to publish projects with this flag enabled.

Install Packages to package.json

The npm tool allows you to save the packages you install to the package.json file by using parameters at the command line. For instance, to save Angular to your package.json file, use:

npm install angular -S

Using the parameter -S, npm saves the package in your existing package.json file and serializes the package listing in the "dependencies" configuration property.

    "dependencies": {
        "angular": "^1.5.8"

Note: The caret ^ before the version number indicates that when npm attempts to re-install this package, it downloads this version or a later version compatible with this version. Read more about semantic versioning with npm.

Not all packages in npm are used for the same purpose. Some of the packages are frameworks used in the appliation, like Angular. Some of the packages are used during development like compilers and linters. These frameworks constitute developer tooling rather than application frameworks. npm makes this distinction in the package.json file by listing development dependencies in the "devDependencies" section.

    "devDependencies": {
        "typescript": "^2.0.3"

Most of your needs are met using "dependencies" and "devDependencies". However, npm also has "peerDependencies" and "optionalDependencies" to register packages with your application. Find out more in the package.json documentation.

Also in Visual Studio, you have the option to type these packages directly in your package.json file with full IntelliSense support:

npm package.json IntelliSense support in Visual Studio

Restore Packages from package.json

As long as you have all of the packages listed in your package.json file, you can safely delete and restore your node_modules folder at any time. In fact, you probably should after installing a new dependency. Because npm resolves dependencies based on the order in which packages are installed, the only way to ensure that dependencies are installed in a consistent manner across machines is to install them from the same package.json file.

To install/restore packages, use the install command by itself at the directory containing an existing package.json file.

npm install

Alternatively, Visual Studio has a handy shortcut in Solution Explorer. Right-click on a package.json file and select the option to Restore Packages:

Visual Studio package.json Restore Packages

Looking Forward

In this tooling tour, you have seen how to install npm packages in various ways using the command line and using Visual Studio. This is still early days. Expect to see more tooling options from Visual Studio in the future.

Do you use npm packages in Visual Studio? What are your favorite tricks for working with them? Please leave a comment and let everyone know.

Using EcmaScript 2015 Modules in TypeScript with SystemJS

TypeScript and SystemJS header

There are two powerful tools for Angular developers in TypeScript and SystemJS. They are both in the Angular 2 quick start and they work just as well with AngularJS 1.x for building maintainable Angular applications.

However, getting started using these tools can be tricky. You need to align both tools' configurations so they work together and having a basic understanding of what happens under the hood can save you hours of confusion and frustration. Once you understand the core concepts and setup the configuration, this workflow helps to make your code more decoupled and maintainable – and maybe even more fun.

This post walks through the basics of using SystemJS and TypeScript in Visual Studio for development. You learn the minimum configuration that matters, how it interacts with the rest of the system, and what to expect when compiling and running your application.

Before You Begin

If you want to skip right to the code, it is all on GitHub. The example is in Visual Studio 2015 (there's a free community edition) and is designed to run with minimal dependencies.

The example project is a component called ListMaker which allows the user to make a list by typing in a textbox and pressing ENTER. This component is made up of two child components AddItemTextbox and List, and includes basic CSS styles. The main script bootstraps the ListMaker component and everything is brought together in index.html.

Application structure

SystemJS is the only library used in the example. Adding dependencies with TypeScript and SystemJS, including Angular, is another level of complexity that is omitted here intentionally. There are enough pieces to understand using SystemJS and TypeScript together so watch for more posts on this topic.

Required Tools and Frameworks

This walkthrough uses the following tools and frameworks:

Visual Studio

The demo is built using Visual Studio 2015 Community. Visual Studio provides a seamless experience to compile and run your application on a development server. It also has first class support for TypeScript.

TypeScript Add-In for Visual Studio

This add-in enables TypeScript support in Visual Studio. The demo uses TypeScript 1.8.36. Install the add-in through Visual Studio's Extensions and Updates manager or from the web.


SystemJS is the JavaScript module loader. It's included in the project on GitHub. You can also obtain it from your favorite JavaScript package manager or as a release download from GitHub.

If you don't use Visual Studio, don't fret. You can port the code to another web project as there are no Visual Studio-specific dependencies. Be sure you know how to setup a development server and TypeScript support in your environment of choice.

Workflow Overview

When using these tools together, your workflow requires a compilation step. The Visual Studio TypeScript add-in automatically handles the compilation when you build or run your project. If you aren't in the habit of using front-end compilation tools such as TypeScript, this may be new to you. Here is an overview:

Diagram of TypeScript with SystemJS workflow

TypeScript Configuration

While the default TypeScript configuration in Visual Studio works, there are a couple options to discuss. First, you should consider adding a tsconfig.json file to your project. By default, you find the TypeScript properties in the Visual Studio project properties, however using a tsconfig.json file has advantages.

Most importantly, the project properties do not show all of the options that are available in tsconfig.json so if at some point you want to set other options, you will be limited by the tooling in the project properties. Also, the tsconfig.json file is a standard configuration for every editor and compiler that supports TypeScript. Therfore if someone joins your team that knows TypeScript, they will know where to look for the configuration no matter which tools they use.

Note: you should install the latest update of Visual Studio 2015. Earlier versions did not properly recognize the tsconfig.json file.

The first related configuration option is compilerOption.module. This option sets which module loader format the TypeScript compiler emits. Because SystemJS understands all of them, it's hard to pick the wrong one. Ultimately your choice here may depend on the other tooling you use for building your JavaScript. For now, choose "system" as it is the native format of the loader but you may find that "amd" provides greater compatibility with other compilation tools.

The other option is This option sets which version of the ECMAScript® standard to target when generating JavaScript from your TypeScript files. This value largely depends on which browsers you are targeting. The default value is "es3" which gives you the broadest range of browser support. It's worth noting that should you eventually want to emit native ECMAScript module syntax, this option will need to be set to "es2015".

Your tsconfig.json file should at least have:

Implement ECMAScript 2015 Module Syntax

Take a look at the ListMaker component without the ECMAScript 2015 module syntax:

The first thing to note is that ListMaker is in the global scope as it is meant to be re-used within a given application. The ListMaker implementation, however, is not in global scope and is instead wrapped in an immediately invoked function expression (IIFE). If you look closely, you also see that ListMaker depends on two other constructor functions not defined in this code: AddItemTextBox and List. These constructors are also defined in global scope and furthermore you have to ensure that AddItemTextBox and List are loaded in the browser before trying to create a ListMaker.

The fundamental mechanism for modules are import and export statements. The import statements define the module's dependencies and the export statements define the objects that are available to other modules. Take a look at how the ListMaker code changes when using ECMAScript modules:

The module's dependencies are clearly defined in the import statment and you can easily determine where to obtain the source code for these objects looking at its URL. Also, because module scope is separated from global scope by default, the use of an IIFE is unnecessary leading to less code and more readable code.

Finally notice the export statement and the use of the default keyword. While ECMAScript modules can define multiple exports, only one object is defined as the default export. Similarly, the import statements for this module are explicitly importing the default export from the target modules.

This post doesn't go into all the ways you can write your import and export statements. TypeScript supports various options for writing these definitions so read more about them here.

SystemJS Configuration and Reconciling Import URLs

This is likely the most important part configuring SystemJS and TypeScript to work together. Both SystemJS and TypeScript evaluate the import statements. When TypeScript looks at the import statement, it is looking for a TypeScript file so that the compiler can use the types defined in that file. Using import './Foo', TypeScript looks in the current directory for Foo.ts and then uses the information contained in that file for compilation and type checking.

SystemJS on the other hand looks at import './Foo' and then attempts to make a request to the server for <current-directory>/Foo and without any special configuration, this request will produce a 404 resource not found error. What SystemJS needs to request instead is <current-directory>/Foo.js.

Luckily, SystemJS has a configuration option to append a file extension to requests. You configure this by setting up a specific path in your application using the packages option. In the demo, all of the TypeScript files are in the components folder and SystemJS needs to add a .js extension to these requests.

Create a systemjs.config.js file in your application and add the following configuration:

You can optionally configure this behavior for the whole application by using an empty string '' to set the root of your application as the path. Also remember this configuration only applies to requests made by SystemJS and other requests still require explicit file extensions. There are many useful options in the SystemJS configuration so be sure to read up on its capabilities.

Bootstrap the Application

There is bootstrapping logic for the application in main.ts. The browser requests this file first and the script's purpose is to access the Document Object Model (DOM) and render the root component which in this case is ListMaker. It's important to understand using module loaders that the first module retrieved is the last one to execute its contents. For example, even though main.ts is the entry point of the application, all of the other dependent scripts execute prior to main.ts executing.

Once you determine the main script, you bring the configuration and bootstrapping together on the root HTML page. Reference SystemJS, followed by the SystemJS configuration, and then use the System.import syntax from SystemJS to load the post-compiled version of main, 'scripts/main'. Remember that even though the extension is not present, you have configured SystemJS to add the extension and request scripts/main.js.

Once main.js is loaded, all of the other import statements are evaluated and the target modules are loaded as well to compose the application. This diagram illustrates the dependencies and the order of execution when loading.

Diagram illustrating bootstrap process

At this point, you have configured enough for your application to run. Remember to compile the TypeScript first and all of the modules will run and execute in the correct order. Be sure to check out the complete project for all of the details.

Only the Beginning

This is the first step using ECMAScript 2015 modules with SystemJS and TypeScript and this workflow works quite well as a development workflow. Once you understand the configuration and basics of using the tools, you can get up and running rather quickly.

But you need more. As an Angular developer, you need to bring in third-party libraries and seamlessly integrate with your application code. This is the topic of the next post in this series.

At some point, you will want to bundle these scripts together into one request. You may even want to create several bundles that are loaded dynamically via a route change or a certain screen size. The good news is that by separating your code into modules that have explicit dependency references, you have made this configuration much easier to attain.

Finally, the documentation for both of these tools is well done. Be sure to read the TypeScript documentation and the SystemJS documentation for more information.

Stay tuned for more on this topic. If there is anything else you want to know about these tools or if you also have experience with them, please share in the comments below.