Skip to main content

Exporting standalone components from Angular libraries

Exporting unrelated standalone components from Angular libraries​

Libraries export standalone components, directives, and pipes directly from their public API, usually an index.ts or public_api.ts file:

libs/our-lib/src/index.ts
export * from "./lib/our-button.component";
export * from "./lib/our-checkbox.component";

Standalone components consuming the library import the components through their imports array:

rocket.component.ts
import { Component } from "@angular/core";
import { OurButtonComponent } from "@our-org/our-lib";

import { RocketService } from "./rocket.service";

@Component({
imports: [OurButtonComponent],
standalone: true,
template: `<our-button (click)="onRocketLaunch()">Launch rocket</our-button>`,
})
export class RocketComponent {
#rocket: RocketService;

constructor(rocket: RocketService) {
this.#rocket = rocket;
}

onRocketLaunch(): void {
this.#rocket.launch();
}
}

Interoperability with NgModules​

Classic components add standalone components they depend on to their declaring NgModule's imports array:

rocket.component.ts
import { Component, NgModule } from "@angular/core";
import { OurButtonComponent } from "@our-org/our-lib";

import { RocketService } from "./rocket.service";

@Component({
template: `<our-button (click)="onRocketLaunch()">Launch rocket</our-button>`,
})
export class RocketComponent {
#rocket: RocketService;

constructor(rocket: RocketService) {
this.#rocket = rocket;
}

onRocketLaunch(): void {
this.#rocket.launch();
}
}

@NgModule({
declarations: [RocketComponent],
exports: [RocketComponent],
imports: [OurButtonComponent],
})
export class RocketModule {}

Exporting cohesive standalone components from Angular libraries​

In case multiple components, directive, and pipes are always used together, we export them in an immutable array from our library's public API:

libs/our-lib/src/index.ts
import { OurTableCellComponent } from "./lib/table/our-table-cell.component";
import { OurTableRowComponent } from "./lib/table/our-table-row.component";
import { OurTableComponent } from "./lib/table/our-table.component";

// (Optionally) export the individual types for selective importing and
// referencing instances for queries and similar purposes
export OurTableCellComponent;
export OurTableRowComponent;
export OurTableComponent;

// Export cohesive standalone declarables for easy importing
export const ourTableDeclarables = [
OurTableCellComponent,
OurTableRowComponent,
OurTableComponent,
] as const;

Standalone components consuming the library import the components through their imports array:

data-grid.component.ts (standalone)
import { AsyncPipe } from "@angular/common";
import { Component } from "@angular/core";
import { ourTableDeclarables } from "@our-org/our-lib";

import { DataGridService } from "./data-grid.service";

@Component({
imports: [AsyncPipe, ourTableDeclarables],
standalone: true,
template: `
<our-table>
<our-table-row *ngFor="let row of rows$ | async">
<our-table-cell *ngFor="let cell of row.cells">
{{ cell.text }}
</our-table-cell>
</our-table>
`,
})
export class DataGridComponent {
rows$ =

constructor(dataGridService: DataGridService) {
this.rows$ = dataGridService.rows$;
}
}

Interoperability with NgModules​

Classic components depending add the exported standalone declarables to their NgModule's imports array:

data-grid.component.ts (classic)
import { AsyncPipe } from "@angular/common";
import { Component, NgModule } from "@angular/core";
import { ourTableDeclarables } from "@our-org/our-lib";

import { DataGridService } from "./data-grid.service";

@Component({
standalone: false,
template: `
<our-table>
<our-table-row *ngFor="let row of rows$ | async">
<our-table-cell *ngFor="let cell of row.cells">
{{ cell.text }}
</our-table-cell>
</our-table>
`,
})
export class DataGridComponent {
rows$ =

constructor(dataGridService: DataGridService) {
this.rows$ = dataGridService.rows$;
}
}

@NgModule({
declarations: [DataGridComponent],
exports: [DataGridComponent],
imports: [AsyncPipe, ourTableDeclarables]
})
export class DataGridModule {}