Create your Standalone Angular Library in 10 minutes
Learn how to create an Angular library with NgCLI and produce an Npm package. It's a step by step guide with tips and Angular application link demo.

Create your Standalone Angular Library in 10 minutes
Learn how to create an Angular library with NgCLI and produce an Npm package. It's a step by step guide with tips and Angular application link demo.


When companies projects become large it ends up splitting into several sub-projects. It's a bit like micro frontends, the trendy word for microservices in the browser.
In both cases, you got many projects and want to share some common behaviour. That's why you begin to create libraries to share common things such as logging and API services.
In this article, you'll learn how to create a library with Angular. The Angular documentation is complete about how to create a library. Yet, it's hard to grasp if you're not confident with some basics. While creating your library, you'll also learn about dependencies linking and peer dependencies.
Create your libraryLink to this section
Let's use ng-cli, it's made for this. That's the tool which can generate, build, run and deploy Angular projects.
<>Copy$ npm install --global @angular/cli $ ng new my-lib --create-application=false $ cd my-lib $ ng generate library my-lib $ ng build
By default ng new
creates an app. If you create a library after hand both the app and the library will share the same repository. This isn't convenient if you publish the library on an npm registry. When other teams want to change the library, it'll be hard for them to find out the right repository.
For this reason, the first step is to generate a workspace without any project. Then, you generate the library with a second command. If you're curious about created files, take a look at Workspace and project file structure documentation.
Adding dependenciesLink to this section
Now, you have your library. Let's say you need to use lodash concat function. I know JavaScript arrays have a concat method. The truth is others lodash dependencies were already installed with Angular.
Be careful, the workspace directory contains a package.json
. It helps to share dependencies across workspace projects. I don't recommend using this one. Prefer declaring your library dependencies into your library package.json
.
<>Copy$ cd ./projects/my-lib $ npm install lodash.concat
Go ahead and add lodash.concat. Now import and use it in my-lib.service
and build the library.
<>Copyimport concat from 'lodash.concat'; @Injectable({ providedIn: 'root' }) export class MyLibService { doSomething() { // Make sure tree shaking won't remove the lib during the build console.log(concat([1], 2)) } }
Angular doesn't agree, it shows a warning. Ignore the error message, whitelisting isn't a good practice.


Prefer to declare lodash.concat as a peer dependency instead, this is the warning piece of advice. But why is that? What's a peer dependency?
Actually a peer dependency is like saying: "I need this, be sure it'll be available when needed". Think about it, the library can't run on its own, it runs within an app which uses it.
This is the app job to provide the dependencies its libraries needs. The main reason is to avoid having the same package in the app and in the library with a different version. It'll for sure bring some Heisenbug and incompatibilities.
<>Copy{ "name": "my-lib", "version": "0.0.1", "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0", "lodash.concat": "^4.5.0" } }
Let's declare lodash.concat as a peer dependency instead. Open the library package.json
and move it from dependencies to peerDependencies section. Also, delete node_modules/lodash.concat
because the app will provide it for us. What? The build is failing because lodash.concat module can't be find?
Get back to the Angular documentation, the part about peer dependencies will help us. Here is what it explains:
While developing a library, you must install all peer dependencies through devDependencies
to ensure that the library compiles properly
Fine, add lodash.concat in dev dependencies and try to compile again. It's working, everything is green! That's it, library dependencies must be in both dev and peer dependency at the same time.
<>Copy$ npm install lodash.concat --save-dev $ ng build $ ng test
Publish your libraryLink to this section
Look at the terminal when building the library. It details the Angular package is build from your source code to a dist directory.


Inspect the package.json
in the build output. The version is 0.0.1, it's the library version. It means it's the library package.json
, not the one in the workspace with version 0.0.0. Also note, the dev dependencies part is missing, only peer dependencies are important.
To publish your package on a registry, run npm publish
. Be sure you configured npm to use your company registry if needed. This command creates a tarball from your compiled library (like npm pack). Then, it uploads this tarball to the configured registry.
The key is to publish from your compiled library directory (dist). Don't publish from your library codebase in projects/my-lib. The last step to use your library is to run npm install my-lib
in an Angular application. The name of the library is the one defined in the package.json
.
Create an app using your libraryLink to this section
Don't add the app in the library workspace. Instead, create the app in a new separate workspace. Again, let ng-cli
do the job:
<>Copy$ ng new my-app $ cd my-app $ ng build
Well done, the app can build. The next step is to use our library. Not the copy from the registry (run npm install my-lib
) but the local one. It's useful you need to update the library and if it works well in your app.
There is a command for this: link. Like publish, you must run it from your library dist directory. It'll create a symlink in npm local registry pointing to your compiled library.
<>Copy$ cd ./dist/my-lib $ npm link $ cd my-app $ npm link my-lib
The last step is to make your app using the npm local registry for your library. Run npm link again but specify your library name. Check the node_modules for your app. You must see my-link which a symlink pointing to your library dist directory.
Let's use our library in the app component.
<>Copyimport { MyLibService } from 'my-lib'; @Component({ /* ... */ }) export class AppComponent { constructor(myLibService: MyLibService) { myLibService.doSomething(); } }
When building the app it should show some errors. It can't resolve lodash.concat in some file from my-lib.
Does it remind you something? Yes, lodash.concat is the peer dependency, we declared in the library. As explained before, it's the app job to provide libraries peer dependencies.
<>Copy$ npm install lodash.concat
Still not working? It works when the library isn't linked. To make it work for the link as well, let's dig again in Angular documentation.
Use TypeScript path mapping to tell TypeScript that it should load some modules from a specific location. List all the peer dependencies that your library uses in the workspace TypeScript configuration file./tsconfig.json
, and point them at the local copy in the app'snode_modules
folder.
The paragraph before describes our situation: link a library having peer dependencies in an app. Let's edit this tsconfig file to ensure the library is using dependencies provided by the app.
<>Copy{ "compilerOptions": { "paths": { "lodash.concat": [ "./node_modules/lodash.concat" ] } }, "angularCompilerOptions": { "preserveSymlinks": true } }
You may also need preserveSymlinks
option. Not mentioned in the documentation but necessary in some cases. Run ng serve
to check if the console.log using our library is working. Congratulation, you did a good job!
At this point, you should be able to remove the node_modules in my-lib. This way you're sure the library uses app dependencies. Don't do it, read the last part before, it contains a small trick you want to try.
Bonus
Here is a bonus for you, we'll use a small tip included at the very end of the Angular documentation.
The goal is to edit the library source and see the live result in the app using a watcher. No need to build again the library and link/unlink it in the library dist and the app.
<>Copy$ cd my-lib $ ng build --watch $ cd my-app $ ng serve $ firefox http://localhost:4200
Stop your app server before running ng build
with watch option. You can't do it in dist directory, use the workspace root for instance. Run again your app server and change code in your library service. It rebuilds your lib and the app recompile because it detected changes in its node_modules.
Wrapping upLink to this section
Thanks for reading! I hope it helped you to create an Angular library and make it work in your app. There were already much information in Angular documentation. Yet, it was hard form me to use it well at first.
The documentation will evolve with future angular version. Now you have the basics to understand it on your own. I hope it helped you, thanks for reading!
Don't hesitate to share your experience in the community section.
Comments (0)
Be the first to leave a comment
About the author

Avid learner about web development and writer for sharing tips and tricks, Full-Stack Developer @SmartAdserver

About the author
Jérémy Bardon
Avid learner about web development and writer for sharing tips and tricks, Full-Stack Developer @SmartAdserver
About the author

Avid learner about web development and writer for sharing tips and tricks, Full-Stack Developer @SmartAdserver