In this article, I will be sharing my experience of publishing my first Angular library to npm. The example library used in this blog is Ivy Compatible and has been tested against Angular 9 apps. Please note that at this point it is not recommended to publish Ivy libraries to NPM repositories. The original article was published on Medium, but this is an updated version. I've added:

  • step 5 - how to use/test the library in your app and
  • step 6 - working with the library and the app in watch mode

I always thought as how convenient it is to do a npm install <some-library> and boom the module is installed in your project and ready to use. Recently, in my current project I had to implement typeahead at couple of places and I was using Angular Material input and matAutocomplete component and then writing some Typescript code with RxJS to add typeahead functionality. I created a directive module for this and added it to each of these input type so that I do not have to repeat code in different components. It was great!

I thought of publishing this directive to npm. But there was one issue, I had never published a library to npm before! I saw this as opportunity to learn couple of things here:

  1. Learn to write libraries in Angular that is compatible with npm format.
  2. Learn to publish it to npm.

This blog will cover these points in detail. So let’s get started with the first one.

1. Write Library in Angular that is compatible with npm format.#

After working with Angular for almost couple of years now I knew creating and publishing a library for Angular developers has not been a simple task until Angular team released version 6 of the framework. This release introduced many new toolchains that made things easier to work with. One of the new tool that got integrated in the Angular CLI is the Library Support.

Yes, the Angular team has made the library creation process a fairly simple process. You just need to run ng g library <name> command. This command will create a library project within your CLI workspace, and configure it for testing and for building.

As described above, I am going to create a simple Typeahead directive that can be used with Angular Material input and matAutocomplete component or any other autocomplete component. This directive will enhance autocomplete by adding typeahead functionality.

Take a look at code on Github, or check out the library on npm.

If you are going to add a new library to existing project, make sure you have updated it to v6.0.0. Also, if you are going to start on a new project, make sure you have updated Angular CLI to v6.0.0. Read on how to update here.

Step 1: Create a new Angular CLI v6 library app#

I am going to call the app as MatTypeaheadLibrary with prefix mat-ta

Quick Tip: You can run these Angular CLI command with -d ( — dry-run) flag to see what changes will take place without actually writing those changes.
ng new MatTypeaheadLibrary -p mat-ta

This command will create a brand new Angular v6 app. With this version, there is one major change in the configuration file for Angular CLI. You will see angular.json file instead of .angular-cli.json file. The new angular.json file now represents a Angular workspace and support multiple apps and projects. By default you will get MatTypeaheadLibrary and MatTypeaheadLibrary-e2e project.

angular.json screenshot with the two generated project config details collapsed.

Step 2: Now we will add a library to the angular app that we created above#

I am going to call the library as NgxMatTypehead (following standard naming convention for Angular npm libraries 😃 ) with the prefix NgxMat. The prefix defaults to lib.

ng g library NgxMatTypeahead -p NgxMat

Learn more about above command here and here.

The ng g librarycommand did several changes to our app:

  • Added projects directory at the root level with ngx-mat-typeahead directory. This is the place where we will be adding our code for writing the library.
  • In angular.json file it updated the projects object with our new library.
angular.json file with newly added NgxMatTypeahead library under Projects array.
  • It updated package.json by adding dependencies required to build the library like ng-packagr, etc.
  • Added files required to write, build and test an Angular Library under proejcts/ngx-mat-typeahead directory. README.md, CHANGELOG.md and LICENSE files have been manually added.
ngx-mat-typeahead directory with files.
  • The last change this command did was updating the tsconfig.json with paths array. This enables us to import the library by giving absolute path, making it look like we are importing the module from node_modules.
tsconfig.json with paths array.

Step 3: Work on writing the actual code for this NgxMatTypeahead library#

In this step, I will not explain the library code (It’s a very simple directive) but will just over different files and components that I added or made changes to.

  • The src files for the library lives under projects/ngx-mat-typeahead/src/lib directory.
files under lib directory
  • The two major files that contain the code are ngx-mat-typeahead.directive.ts and ngx-mat-typeahead.service.ts. The ngx-mat-typeahead.module.ts is the Angular Module file. You can see the content of these on github.
  • public_api.ts is the file that exports everything from files under lib directory.
public_api.ts
  • I have also written unit tests for public methods using Jasmine and Karma (they are all preconfigured) in respective .spec files. You can run the test using ng test NgxMatTypeahead command.
  • These are the files that I added or made changes to develop this directive. The selector for this directive is NgxMatTypeahead.

Step 4: Running the build for the library#

Once you are done with developing the library/module, the next important part is to build it. Thanks to the latest Angular release, this process is super simple now. Just run below command and add --prod flag for a production build.

ng build <library-name>

  • Once I was done with coding and ready to build I ran: ng build NgxMatTypeahead. This command compiles your library code and dependencies and create bundles and modules following the Angular Package format and writes it under dist directory.
dist directory with bundled library code
  • With the build artifacts under the dist directory, we are almost ready to publish my first module to npm.

Step 5: Use/Test the library#

We do not have to publish our library to npm in order to use/test it. Once we have done the build (ng build NgxMatTypeahead), we can import it into our app. Basically, like any other 3rd party library we need to add it as a dependency in our app’s NgModule as shown below. There are a few points to note about how this import works.

  • Note that NgxMatTypeahead library is still not published and hence not available via npm and in node_modules.
app.module file
  • Let’s pause and think as what updates were made in the app when we had generated the library(ng g library NgxMatTypeahead -p NgxMat). There were few changes and one of the changes was in tsconfig.json file. Angular had added paths property into this file as shown below:
  • The Angular CLI uses the tsconfig paths to tell the build system where to find the library. More on this here.
tsconfig.json with paths array
tsconfig.json with paths array
  • So, when you are importing NgxMatTypeaheadModule , it is actually being imported from dist/ngx-mat-typeahead.

Step 6: Updating Library (working in watch mode)#

Let’s say you did some test and now you want to make some changes to the library code (happens all the time..right!). To suit our scenario, we want the library code (under projects/ngx-mat-typeahead) and our sample app (where we are using this library) to be running in --watch mode. To achieve this we need to perform a few easy steps.

  • First, we need to link the library to our app. Linking a library is 2 step process and is done via npm link command. More on this here.
  • So we cd into dist/ngx-mat-typeahead and run npm link
  • Next, from our project root folder run npm link
  • Now, if we run the library in the watch mode (ng build NgxMatTypeahead — watch) and also run ng serve. We can develop our application and our linked libraries simultaneously, and see the app recompile with each modification to the library’s source code…Yay 👏!!

With the library bundle used, tested and built, let’s move on to the next major step of how to publish your library to npm.

2. Publish library to npm repository.#

With our compiled library sitting under dist directory and almost ready to be published, there are few updates that are still required in this library. The detailed information is provided here, I am just going to highlight a few important ones.

  • Update package.json file with additional details such as author, GitHub link, etc.
updated package.json file with additional details
  • Add README.md and LICENSE file. The README.md will be used as the documentation that will be displayed on your npm package web page. Make sure you include detailed information about your API and other details in the README. Also providing license information is useful.
  • If you want you can rebuild your library and these changes will be copied over to dist directory.
  • Make sure to run the final build with--prod flag.
  • Now dist is ready to be published. But since I have never had any package published on npm, I also didn’t had an account. So I had to create one. This process is simple, as stated on npm website.
To publish, you must be a user on the npm registry. If you aren’t a user, create an account by using npm adduser. If you created a user account on the site, use npm login to access your account from your terminal.
  • Test: Type npm whoami from a terminal to see if you are already logged in.
  • When everything looked good, I cdto the dist/ngx-mat-typeahead directory and ran npm publish
Quick Tip: Before publishing, please make sure your package works and is not broken. As a broken package will do no good.

 npm publish

npm publish output
  • And done, my first Angular module has now been published to npm repository.
  • To verify check here https://npmjs.com/package/<package>
  • Here is the npm link of my published package → ngx-mat-typeahead
  • Also, you can check the finished code on Github.

Do let me know in comments if you have any feedback/suggestions or you find any errors. You can find me on Twitter (@esanjiv).

Keep Learning! Thanks!