Most notably, a new "projects" directory was created, with "tvmaze" folder inside. This new project is referenced in our angular.json configuration too.

2. Define and provide some interfaces

An api request will look like this: https://api.tvmaze.com/shows/336 .

If you follow the link you will notice that the returned json is pretty complex — it would be a good idea to define a reusable set of interfaces and provide them to our library’s users. You can use a wonderful jsontots.com tool to do the former:

Just copy the api’s response, paste it in to field on jsontots.com site and voila! You have the interfaces! Btw. for more similar tips follow my @sulco twitter account :-)

Let’s create a projects/tvmaze/src/lib/tvmaze.models.ts file with all the interfaces. There’s bunch of them and they are all pretty closely related so it really doesn’t make sense to create a separate file for every one of them.

To allow developers using this library to have an access to our interfaces, we need to provide them as a public api of the tvmaze library. Edit the generated in the 1st step projects/tvmaze/src/public_api.ts file so it looks like this:

3. Create a service in the library

Our newly created tvmaze has its own package.json , tsconfig.json , tslint.json and karma.conf.js since it makes sense that it may need a different setup than the main application. Is also has a sample component, module and a service generated for us. We can also add additional ones, which we will do in a moment.

For now let’s add some logic to the projects/tvmaze/src/lib/tvmaze.service.ts :

There is nothing unusual in this service other than the provideIn: root configuration in the @Injectable decorator. It’s actually a new setting added in Angular 6.

"provideIn: root" allows to provide a service without explicitly registering it in any NgModule.

Why is that useful? It enables such service to be tree-shaken (removed form the production bundle if not used), which is a common scenario in case of services defined in libraries.

4. Create a component in the library

Our library will allow to display a poster of given show. As with a typical Angular project, you don’t have to create a component by hand — it’s what the CLI is for:

ng generate component poster --project=tvmaze

We just needed to tell the CLI to create the poster inside our tvmaze library.

To make the component available outside the lib’s tvmaze.module , we need to add it to the exports section. Make sure your projects/tvmaze/src/lib/tvmaze.module.ts looks like this:

I’ve also added HttpClientModule dependency, since we needed HttpClient in TvMazeService , and CommonModule because it is where async pipe and ngIf directive (that the poster component uses) are defined.

5. Build time!

Before we can use our library, we need to build it. Again, Angular CLI helps with that. We can now tell it to build a specific project:

ng build tvmaze

6. Use the library

To try our library out, we need to do what we always would with 3rd party extension — define as a dependency in the imports section of the app’s NgModule:

The thing to note here is that we don’t import the class by a relative path to the tvmaze directory, but do it as if it was already in node_modules . It it actually there? Nope.

So how does this work?

When we’ve generated the library ( ng generate library tvmaze ) Angular CLI modified the tsconfig.json in the root of our project by adding tvmaze to the paths entry.

This means that whenever in your TypeScript code you import something from "tvmaze" it is actually being imported from the dist/tvmaze directory, where the build of our library has been saved.

That is really convenient, because once you publish the library to the actual npm repository and want to start using that version, you won’t have to change any imports in the source of the application — only remove that paths entry.

Now let’s display something.

Let’s modify the default src/app/app.component.ts to look like this: