Building Angular Library: A Comprehensive Tutorial for Creating Reusable Components
Building Angular Library: A Comprehensive Tutorial for Creating Reusable Components

In this post you will learn how to create Angular library and why do we need to do that at all.

For Angular we typically use Angular CLI to generate our project. But sometimes we want to generate a library inside this project. Why do we need a library?

The first case is if you want to develop a library to reuse it in other applications. For example inside your company. Just imagine that a lot of developers are using Angular for different projects inside the company. They want to share some parts between different applications.

The second case is if you want to create an Angular library and publish it on npm for other people.

For both cases we can use Angular CLI which allows us to generate a library in an easy way.

Generating Angular library

I already prepared an empty Angular project. How can we generate a library? We can do it by using Angular CLI.

ng generate library mla-users

We used here mla prefix because we want to make library unique and we can use a prefix of the company for example. It is totally fine to use this command if your Angular CLI is installed globally.

I don't really like global approach as it doesn't allow to switch easily between different versions. We can use npx in order to specify Angular version for the command.

npx -p @angular/cli@15 ng generate library mla-users

As you can see here we provide what Angular version we want to use in order to execute a command.

The structure of the project

Installation

As you can see in your editor we got a new folder which is called /projects/mla-users. This is exactly are folder where all libraries are created. Here we can pack interfaces, services, components and reuse they everywhere.

Most important file here is public-api. Here we specify what exactly we want to export to use outside.

// projects/mla-users/src/public-api.ts
export * from './lib/mla-users.service';
export * from './lib/mla-users.component';
export * from './lib/mla-users.module';

In this case here as you can see we are exporting service, component and a module. Inside our src folder we have all this stuff. Just a standard Angular module, component and service.

import { Component } from '@angular/core';
@Component({
  selector: 'lib-mla-users',
  template: `<p> mla-users works! </p>`,
})
export class MlaUsersComponent {}

Here is our basic component that we are exporting from this library.

Adding own stuff

Now let's create something in library so we can see how it all works together. We really need some types to understand what we implement.

// /lib/types/user.interface.ts
export interface UserInterface {
  id: string;
  name: string;
}

Here we have now a UserInterface so everybody understand what with what data we are working.

Now let's update our service to get some users.

import { Injectable } from '@angular/core';
import { UserInterface } from './types/user.interface';
import { Observable, of } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class MlaUsersService {
  constructor() {}

  getUsers(): Observable<UserInterface[]> {
    return of([
      { id: '1', name: 'Foo' },
      { id: '2', name: 'Bar' },
    ]);
  }
}

Here we created getUsers function which returns an Observable or users array.

Most important thing to remember is that important to files in the library MUST be relative.

Now we must export our new interface in public-api file.

...
export * from './lib/types/user.interface';

Now our interface will be also available outside.

Building a library

What we want to do now is build our library. We can't really use it without building. In order to do that we can write

ng build mla-users
// or
npx -p @angular/cli@15 ng build mla-users

The main point is that it will build our library just once which is not really comfortable for development. This is why we have an option --watch.

ng build mla-users --watch
// or
npx -p @angular/cli@15 ng build mla-users --watch

Now it will rebuild the library with every single change.

Build lib

Using a library

Now it is time to use a library inside our project. First of all let's import our module.

import { MlaUsersModule } from 'mla-users';

@NgModule({
  ...
  imports: [..., MlaUsersModule],
})
export class AppModule {}

As you can see we import it just like any other library from node_modules. And it allows us to render our component in the markup.

<h1>Monsterlessons Academy</h1>
<lib-mla-users></lib-mla-users>
<router-outlet></router-outlet>

Component

As you can see our component was rendered successfully.

Now let's check if we can use a service.

import { MlaUsersService } from 'mla-users';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  usersService = inject(MlaUsersService);

  ngOnInit(): void {
    this.usersService.getUsers().subscribe((res) => console.log(res));
  }
}

Here we injected our MlaUsersService from the library and used getUsers method in order get some data.

Publishing a library

At some point you might want to publish your library to npm. It is extremely easy to do. First you must build a library just like we did previously. Next you need to jump to dist/mla-users and call there npm publish. We already have package.json which is prepared for publishing and it works out of the box.

And actually if you want to improve your Angular knowledge and prepare for the interview I highly recommend you to check my course Angular Interview Questions - Coding Interview 2023.

📚 Source code of what we've done