Home

Awesome

ngx-fastboot

bundlephobia Semantic Release Build Status Coverage Status Angular Tsup

ngx-fastboot is a dynamic configuration loader for Angular applications. It optimizes the startup performance by loading configurations in a separate chunk during compilation.

Why Use ngx-fastboot?

Modern web applications often require a multitude of providers, which can increase the initial bundle size and slow down application startup. Splitting code into multiple chunks helps mitigate these issues by:

Features

Installation

with npm:

npm install ngx-fastboot

with pnpm:

pnpm add ngx-fastboot

with yarn:

yarn add ngx-fastboot

Usage

To use ngx-fastboot, import the fast function and call it with your Angular application's bootstrapApplication function, root component, and configuration options.

Example

Before

main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import provideMyDefaultExportFeatures from './default-export-features.config';
import { provideMyOtherFeatures } from './my-other-features.config';
import { fast } from 'ngx-fastboot';

bootstrapApplication(AppComponent, {
  providers: [
    MyProvider,
    provideMyDefaultExportFeatures,
    provideMyOtherFeatures,
  ]
}).then(appRef => {
  console.log('App is bootstrapped');
}).catch(error => {
  console.error('Error bootstrapping the app', error);
});

After

main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import { fast } from 'ngx-fastboot';

fast(bootstrapApplication, AppComponent, {
  providers: [
    MyProvider,
    () => import('./default-export-features.config'), // default export config
    () => import('./my-other-features.config').then((m) => m.provideMyOtherFeatures),
  ]
}).then(appRef => {
  console.log('App is bootstrapped');
}).catch(error => {
  console.error('Error bootstrapping the app', error);
});

Providers

ngx-fastboot provides great flexibility in how providers are loaded. Each element of the providers field can be either a single provider or an array of providers, depending on the needs of your application.

You can specify these providers in three main ways:

Static Import

main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import { MyProvider } from 'providers/my-provider';
import { OtherProvider } from 'providers/other-provider';
import { fast } from 'ngx-fastboot';

fast(bootstrapApplication, AppComponent, {
  providers: [
    MyProvider,
    OtherProvider,
  ]
}).then(appRef => {
  console.log('App is bootstrapped');
}).catch(error => {
  console.error('Error bootstrapping the app', error);
});

Dynamic Named Import

providers/my-provider.ts

export const MyProvider: Provider = ....;

providers/other-provider.ts

export const OtherProvider = [
  provideHttpClient(),
  ReactiveFormsModule,
  provideZoneChangeDetection({ eventCoalescing: true }),
] satisfies Array<Provider | EnvironmentProviders>;

main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import { fast } from 'ngx-fastboot';

fast(bootstrapApplication, AppComponent, {
  providers: [
    () => import('providers/my-provider').then((m) => m.MyProvider), // single
    () => import('providers/other-provider').then((m) => m.OtherProvider), // array
  ]
}).then(appRef => {
  console.log('App is bootstrapped');
}).catch(error => {
  console.error('Error bootstrapping the app', error);
});

Dynamic Default Import

providers/my-provider.ts

const MyProvider: Provider = ....;
export default MyProvider;

providers/other-provider.ts

export default [
  provideHttpClient(),
  ReactiveFormsModule,
  provideZoneChangeDetection({ eventCoalescing: true }),
] satisfies Array<Provider | EnvironmentProviders>;

main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import { fast } from 'ngx-fastboot';

fast(bootstrapApplication, AppComponent, {
  providers: [
    () => import('providers/my-provider'), // single
    () => import('providers/other-provider'), // array
  ]
}).then(appRef => {
  console.log('App is bootstrapped');
}).catch(error => {
  console.error('Error bootstrapping the app', error);
});

Full example

main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import { MyStaticImportedProvider } from './providers/my-static-imported-provider';
import { fast } from 'ngx-fastboot';

fast(bootstrapApplication, AppComponent, {
  providers: [
    MyStaticImportedProvider,
    () => import('providers/my-provider').then((m) => m.MyProvider),
    () => import('providers/other-provider'),
  ]
}).then(appRef => {
  console.log('App is bootstrapped');
}).catch(error => {
  console.error('Error bootstrapping the app', error);
});

RootComponent

Similar to providers, you can manage the root component of the application both statically and dynamically. Dynamically loading the root component can help reduce the initial bundle size.

Static Import

The classic method to bootstrap the root component involves a static import:

fast(bootstrapApplication, AppComponent, {
  providers: [...]
});

Dynamic Named Import

To optimize bundle size, the root component can be loaded dynamically with a named import:

fast(
  bootstrapApplication, 
  () => import('./app-component').then((m) => m.AppComponent), {
  providers: [...]
});

Dynamic Default Import

Alternatively, you can use a dynamic default import if the root component is exported as the default from the module:

fast(
  bootstrapApplication, 
  () => import('./app-component'), {
  providers: [...]
});

Sentry Integration Example

This example shows how to integrate Sentry with ngx-fastboot for error monitoring and performance tracing in your Angular application.

src/app/configs/sentry.config.ts

import { APP_INITIALIZER, EnvironmentProviders, ErrorHandler, Provider } from '@angular/core';
import { Router } from '@angular/router';
import {
  createErrorHandler,
  init,
  TraceService,
} from '@sentry/angular-ivy';

export default [
  {
    provide: ErrorHandler,
    useValue: createErrorHandler({
      showDialog: false,
      logErrors: true,
    }),
  },
  {
    provide: TraceService,
    deps: [Router],
  },
  {
    provide: APP_INITIALIZER,
    useFactory: () => () => {},
    deps: [TraceService],
    multi: true,
  },
] satisfies Array<Provider | EnvironmentProviders>;

src/app/configs/sentry.init.ts

import {
  browserTracingIntegration,
  init,
  replayIntegration,
} from '@sentry/angular-ivy';

export function initSentryConfig() {
  init({
    dsn: '<your-dsn>',
    integrations: [browserTracingIntegration(), replayIntegration()],
    ...etc
  });
  console.info('Sentry initialized.');
}

src/main.ts

import { AppComponent } from './app.component';
import { bootstrapApplication } from '@angular/platform-browser';
import { fast } from 'ngx-fastboot';

fast(bootstrapApplication, AppComponent, {
  providers: [
    () => import('./app/configs/sentry.config'),
  ],
})
  .then(() => import('./app/configs/sentry.init')
  .then((init) => init.initSentryConfig()))
  .catch(error => {
    console.error('Error bootstrapping the app', error);
  });

API

fast

Dynamically loads the specified providers in the configuration and bootstraps an Angular application.

Parameters

Returns

A Promise that resolves to an ApplicationRef instance of the bootstrapped application. The bootstrap method is called with the root component and the updated configuration with the resolved providers.

Types

FastApplicationConfig

export type FastApplicationConfig = ApplicationConfig & {
  providers: Array<FastProvider>
}

FastProvider

export type FastProvider = Provider | EnvironmentProviders | LazyModule<Provider | EnvironmentProviders | Array<Provider | EnvironmentProviders>>;

LazyModule

export type LazyModule<T> = () => Promise<T | { default: T }>;

AngularProvider

export type AngularProvider = Provider | EnvironmentProviders;

FastComponent

export type FastComponent = Type<unknown> | LazyComponent;

LazyComponent

export type LazyComponent = LazyModule<Type<unknown>>;

Contributing

We welcome contributions! Please read our Contributing Guide to learn how you can help improve ngx-fastboot.

License

ngx-fastboot is licensed under the MIT License. See the LICENSE file for more information.

Keywords

angular, angular performance, dynamic configuration, lazy loading, angular bootstrap, ngx-fastboot

Contact

For any questions or feedback, please open an issue.