npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@unily/angular-sdk

v19.2.3

Published

This SDK provides the tools needed to support Angular Module Federation development within Unily

Downloads

343

Readme

Unily - Angular SDK

This SDK provides the tools needed to support Angular Module Federation development within Unily. It includes a schematics package that automatically sets up the scaffolding for a new micro frontend module build, it generates the essential files and configurations needed to make Angular Module Federation facilities available within the set workspace.

Contents

Prerequisites

This project requires NodeJS and NPM to be installed. To make sure you have them available on your machine, try running the following commands:

npm -v
node -v

Installation

To run the schematics collection, first you'll need to install the following Angular development packages globally on your machine so they will provide you with the schematics command line tools:

npm install -g @angular-devkit/schematics
npm install -g @angular-devkit/schematics-cli

Next, install this SDK globally on your machine:

npm install -g @unily/angular-sdk

Usage

Target the workspace folder you wish to generate the micro frontend module in, then run the new-mfe schematic with the following command:

cd {path}
schematics @unily/angular-sdk:new-mfe

This will prompt you to input some configuration settings for the new project:

  • Project name - This will set the workspace directory name accordingly
  • Angular directive selector prefix - This will enforce a linting rule across the project requiring the set value as a prefix for the 'selector' property
  • Webpack server port number - This will set the port number for the module to run on

After running the schematic, the workspace will be populated with the associated file structure. Package dependencies will also be downloaded and installed automatically to prepare the newly generated module for development.

Configuration

Environment configuration details can be fetched from the CMS.

Running an MFE

To start a module on your local environment, run the following command:

Note - This will serve the module on the configured port number.

npm run start

Deploying an MFE

To deploy a module, run the following commands:

npm run build
npm run deploy

This will prompt you to choose from different deployment options:

  • Lazy Loaded - Choose whether the module should be lazily or eagerly loaded
  • Starts enabled - Choose whether the module should be immediately enabled after being deployed

The module will then be added to the 'Application Federated Modules' page in the CMS once it's been successfully deployed.

Deploy via CI/CD pipelines

Alternative to deploying manually, deploying via CI/CD pipelines can be achieved by calling the deploy-ci script with the required parameters.

To do so, update your pipeline to run the following command.

Note that the parameters passed to the npm script need to be passed to a node script hence the use of -- is very important

npm run deploy-ci -- -h https://myexamplehost-api.unily.com -c myClientId -s myClientSecret

The deploy-ci script accepts the following options. Each option requires a value assigned to it. Options can be used in the short or long version. Both will have the same result.

  • -h, --host - The domain of your api gateway
  • -c, --clientId - Your client ID. Contact customer support to provide you one.
  • -s, --secret - Your secret key. Contact customer support to provide you one.
  • -l, --lazy - Accepts a boolean value. True or false. Defaults to true if unspecified. If true, the module will be configured as lazy loaded. If false, it would be loaded eagerly.
  • -e, --enabled - Accepts a boolean value. True or false. Defaults to true if unspecified. If true, the module will be enabled, otherwise it will not and will never be loaded.

Examples

  • Deploying a module that is enabled, and eagerly loaded
npm run deploy-ci -- -h https://myexamplehost-api.unily.com -c myClientId -s myClientSecret -l false
  • Deploying a module that is lazy loaded but not enabled
npm run deploy-ci -- -h https://myexamplehost-api.unily.com -c myClientId -s myClientSecret -e false
  • Deploying a module that is eagerly loaded but not enabled
npm run deploy-ci -- --host  https://myexamplehost-api.unily.com --clientId myClientId --secret myClientSecret --lazy false --enabled false

Powershell and Node 22

Users working with Powershell and Node 22 might experience an issue when running the deploy-ci script as below. This issue seems to be present only in Node 22+ & Powershell.

PS C:\path\to-my-repo> npm run deploy-ci -- -h https://myexamplehost-api.unily.com -c myClientId -s myClientSecret

Run arbitrary package scripts

Usage:
npm run-script <command> [-- <args>]

Options:
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--if-present] [--ignore-scripts]
[--foreground-scripts] [--script-shell <script-shell>]

aliases: run, rum, urn

Run "npm help run-script" for more info

In such a situation, you should be able to run the command by using -- -- instead of -- to pass on the parameters

npm run deploy-ci -- -- -h https://myexamplehost-api.unily.com -c myClientId -s myClientSecret

Migrating an existing MFE

Starting with v19.2.1, this package ships migration schematics to migrate your existing MFEs to the latest changes. To run a migration schematic run the following command

schematics @unily/angular-sdk:migrate@<version>

The current migration versions available are

  • 18.1.5
  • 19
  • 19.1

To have a smooth experience, each migration is expected to run on a version of the repository prior to the one being executed. For example, to run the migration for v18.1.5, it is advised that the repository contains the changes from v18.1.4. To run migration for v19, it is advised to have the changes done in v18.1.5, and so on and so forth.

A migration can be partially run if the necessary criteria for a migration are not met.

Example

To migrate an MFE to v19 of the SDK run the following command

schematics @unily/angular-sdk:migrate@19

Module loading

These are the capabilities of loading a remote module:

  • Can be side-loaded through CMS config ✔
  • Can be imported ✔
  • Can be lazy loaded ✔
  • Can be deployed to a blob ✔
  • Requires environment redeployment on change ❌
  • Can side-load modules through CMS config ❌

Note: Remote modules do not import side-loaded modules explicitly, but inherit any side-loaded module configurations. When running stand-alone, the side-loaded modules will not be available to the remote module.

Dynamically importing modules

A remote module can import myFederatedModules, applicationFederatedModules and unilyFederatedModules modules. Each remote module is configured separately and can import other modules' type definitions when their name is added inside module-federation/mf.config.ts file:

mf.config.ts

export const mfConfig = {
    projectName: 'my-first-mfe',
    dependencies: {
        // Load types for MFEs which have been deployed to the Client's Unily instance
        applicationFederatedModules: [
            'my-second-mfe'
        ],
        // Load types from MFEs available to all Unily instances
        unilyFederatedModules: [
            /* 
                'unily-ui-library'
                ...
            */
        ],
        // Load types AND remote modules from the local environment. 
        // This is useful for testing and development without having to side-load modules and configure them in the Unily platform.
        myFederatedModules: [
            /*
                'my-local-mfe',
            */
        ]
    },
    /**
     *  Authentication token is needed to load types for `applicationFederatedModules` and `unilyFederatedModules`
     *  OR to deploy the current module.
     *  
     * Fetch your endpoint and auth token from
     * 'My Federated Modules' or 'Application Federated Modules' pages in CMS
     * by clicking on 'Get PAT Token' and copying the values provided
     * in the overlay.
     */ 
    endpoint: '',
    authToken: '',
    /**
     * Optional proxy configuration for environments behind corporate firewalls.
     * Uncomment and configure if needed.
     */
    // proxy: {
    //     host: 'your-proxy-host.com',
    //     port: 8080,
    //     auth: {
    //         username: 'proxy-username',
    //         password: 'proxy-password'
    //     }
    // }
};

Proxy configuration

If you're working behind a corporate firewall or proxy server, you can configure proxy settings in mf.config.ts file:

mf.config.ts

export const mfConfig = {
    // ... other configurations
    proxy: {
        // The hostname or IP address of your corporate proxy server
        host: 'your-proxy-host.com',        
        // The port number that your proxy server is listening on
        port: 8080,        
        // Authentication credentials for proxy servers that require login
        auth: {
            // Your proxy server username
            username: 'proxy-username',            
            // Your proxy server password
            password: 'proxy-password'
        }
    }
};

The proxy configuration will be automatically applied to all HTTP requests made during module federation operations, including manifest fetching and module deployment.


Lazy loading a Service and Component from a remote module in Angular

Lazy loading defers the loading of a module until it is actually required. This is ideal for optimizing performance, especially in large applications where not all functionality is needed up front. Angular supports lazy loading via dynamic imports, which enable you to load and access services or components from a remote module only when they are first used.

The example below demonstrates how to configure a remote module to expose both a component (standalone or not) and a service, enabling them to be lazy loaded by a consuming MFE.

Note: Components which should not be publicly available for consumption should not be added to the exports array as noted below.

Step-by-Step example: Exposing Services and Components via public.export.ts

In your MFE, use the public.module.metadata.ts file to declare what should be exposed for lazy loading.

Key Points

  • Standalone Components (Angular 16+): Should be added to both imports and exports arrays.
  • Traditional (non Standalone components) Should be added to both the declerations and exports arrays.
  • Services: Should be listed in the providers array, ideally using a string token to decouple the service from direct class references, making the service available to be retrieved via the getService(...) function defined within the public.module.ts file.
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { HelloWorldComponent } from '../app/hello-world/hello-world.component';
import { MyComponent } from '../app/my/my.component';
import { LoggingService } from '../app/core/services/logging.service';
import PublicModule from './@internal/public.module';

export const metadata = {
    imports: [
        BrowserModule, 
        MyComponent
    ],
    declarations: [
        HelloWorldComponent
    ],
    exports: [
        // Components made available to remote consumers.
        HelloWorldComponent,
        MyComponent
    ],
    providers: [
        // Services exposed to remote modules.
        {
            provide: 'LoggingService',
            useClass: LoggingService
        }
    ],
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
} as NgModule;

afterBootstrap

Use the afterBootstrap function to execute logic immediately after the module is loaded.

export const afterBootstrap = async (instance: PublicModule) => {
    const logService = instance.getService('LoggingService') as LoggingService;
    logService.log('Hello world example has been bootstrapped!');
};

Webpack Configuration for Exposing the Public Folder

To enable lazy loading of components and services from a remote Angular Micro Frontend (MFE), the Public folder is explicitly exposed via the webpack.config.js file. This is essential for making the module accessible to host or shell applications using Module Federation.

Here’s a sample configuration that illustrates how to expose the Public module:

const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
const { FederatedTypesPlugin } = require('@unily/module-federation-typescript');
const { SasPlugin } = require('@unily/sas-plugin');
const path = require('path');
const { getAngularVersion } = require('@unily/utils');

const remoteData = require('./module-federation/remotes');
const remotes = {};
for (const remote of remoteData) {
    remotes[remote.name] = remote.url;
}

const sharedMappings = shareAll({ requiredVersion: 'auto' });
delete sharedMappings['@unily/remote-service'];
sharedMappings['@angular/core'].requiredVersion = getAngularVersion();
sharedMappings['@angular/platform-browser'].requiredVersion = getAngularVersion();

const federationConfig = {
    name: 'my-first-mfe',
    filename: 'remoteEntry.js',
    remotes,
    exposes: {
        './Public': './src/exports/@internal/public.exports.ts'
    },
    shared: {
        // Ensures shared packages are reused and compatible across MFEs
        ...sharedMappings
    }
};

module.exports = withModuleFederationPlugin(federationConfig);
module.exports.plugins.push(
    new FederatedTypesPlugin({ federationConfig }),
    new SasPlugin()
);
module.exports.experiments.topLevelAwait = true;
module.exports.devServer = {
    static: {
        directory: path.join(__dirname, 'dist')
    }
};
module.exports.target = 'web';

By exposing ./Public, all components and services declared in that module become available to be dynamically imported by host applications.

Consuming other MFEs with importRemote

To lazy load other MFEs and consume its services and components, use importRemote from @unily/remote-service npm library. When invoked, it loads the remote module at runtime, makes services accessible via getService(...), and making any component that is exported usable immediately in the DOM (when the CUSTOM_ELEMENTS_SCHEMA schema is used).

In the example below, we have a component in an MFE (my-first-mfe) retrieve and consuming a service (LoggingService) declared in a second MFE (my-second-mfe).

Note: The import path for the typings depend heavily on where the service is placed, and will differ from a real scenario.

import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { importRemote, RemoteNgModule } from '@unily/remote-service';
import { LoggingService } from '@mf-types/my-second-mfe/types';

@Component({
  selector: 'my-component',
  standalone: true,
  template: '<button (click)="loadLoggingService()">Load Remote Module</button>',
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class MyComponent {
  loggingService?: LoggingService;

  async loadLoggingService() {
    this.loggingService = await this.getLoggingService();
    console.log('LoggingService initialized:', this.loggingService);
  }

  private async getLoggingService(): Promise<LoggingService> {
    if (this.loggingService) {
      return this.loggingService;
    }

    // Lazy load the remote module. Services can be fetched via getService, and components become immediately usable in templates.
    const myMFE = await importRemote<RemoteNgModule>('my-second-mfe');
    return myMFE.getService('LoggingService');
  }
}

Key Notes for Consuming a Remote Module

  • Remote Declaration
    The remote module (e.g. 'my-second-mfe') should be declared in your module-federation/mf.config.ts file under the dependencies object. This ensures correct resolution at runtime and enables accurate type inference for services and components.

    In order to be consumed, it must also be configured accordingly within the Unily platform.

  • Accessing Remote Services
    Calling getService('LoggingService') returns the instance of the service exposed in the remote’s public.exports.ts file within the my-second-mfe MFE. This allows you to consume remote business logic just like a local Angular service.

  • Rendering Remote Components
    Remote components can be rendered dynamically in templates as custom elements. This is made possible by including CUSTOM_ELEMENTS_SCHEMA in your component’s schema declaration.