Announcing Native Federation 1.0

Native Federation is a **framework- and tooling-agnostic** implementation of Module Federation.

TLDR; Native Federation is a framework- and tooling-agnostic implementation of Module Federation. Hence, we don't depend on webpack. This is important in the mid- and long-term to prevent a vender-lockin. In the short term, this allows to get started with modern technologies like esbuild or vite.

What is Module Federation?

Module Federation makes the implementation of Micro Frontends and other plugin-based systems much easier. It allows to load EcmaScript modules from separately compiled and deployed applications:

Module Federation allows for runtime integration

However, it is currently - more or less - tied to webpack. This isn't a big problem in the short term or perhaps even in the medium term, because webpack is extremely popular.

On the other hand, we know that technologies come and go. For example, the Angular team is currently working on CLI support for esbuild, which is very promising in terms of build performance.

This raises the question of how to implement the tried-and-tested mental model of Module Federation independently of webpack in order to future-proof your Micro Frontend architecture.

Our answer to this question is Native Federation.

What is Native Federation?

Native Federation is a browser-native implementation that can be used independently of build tools and frameworks. Browser-native means that we rely on modern and future browser technologies such as EcmaScript Modules and Import Maps.

Our examples use the modern esbuid bundler, which is known for its awesome build performance. Some examples also use vite. Other build tools can also be integrated via a simple adapter concept.

Layered Architecture

Native Federation consists of two layers:

Stack

The lower layer, @softarc/native-federation or also called "Native Federation Core", is framework and build tool agnostic and can therefore be used in all possible environments. In order to simplify the use of Native Federation, the layer above offers integration into existing ecosystems. For example, we offer an out-of-the-box integration into the Angular CLI with @angular-architects/native-federation. Also, there is a plugin for vite called @gioboa/vite-module-federation. Further integrations are possible.

Frameworks such as React or Vue, in particular, do not require deeper integration for the time being. In these cases it is very easy to work directly with Native Federation Core.

Compatibility with Module Federation

Since Native Federation implements the mental model of Module Federation, one can also draw on the existing knowledge of Module Federation. In addition, a Native Federation configuration looks like what we know from Module Federation:

// federation.config.js

const {
  withNativeFederation,
  shareAll,
} = require("@softarc/native-federation/build");

module.exports = withNativeFederation({
  name: "remote",

  exposes: {
    "./module": "remote/src/is-long-weekend.ts",
    "./react-remote": "remote/src/react-app.tsx",
  },

  shared: {
    ...shareAll({
      singleton: true,
      strictVersion: true,
      requiredVersion: "auto",
      includeSecondaries: false,
    }),
  },

});

Native Federation Core

For introducing Native Federation Core, you just need to augment your build process with three helper methods:

import * as esbuild from 'esbuild';
import * as path from 'path';
import * as fs from 'fs';
import { esBuildAdapter } from '@softarc/native-federation-esbuild';
import { federationBuilder } from '@softarc/native-federation/build';

const projectName = 'shell';
const tsConfig = 'tsconfig.json';
const outputPath = dist/${projectName};

/*
 *  Step 1: Initialize Native Federation
*/

await federationBuilder.init({
    options: {
        workspaceRoot: path.join(__dirname, '..'),
        outputPath,
        tsConfig,
        federationConfig: ${projectName}/federation.config.js,
        verbose: false,
    },

    /*
        * As this core lib is tooling-agnostic, you
        * need a simple adapter for your bundler.
        * It's just a matter of one function.
    */
    adapter: esBuildAdapter
});

/*
  * Step 2: Trigger your build process
  *
  * You can use any tool for this. Here, we go 
  * with a very simple esbuild-based build.
  * 
  * Just respect the externals in 
  * federationBuilder.externals.
*/

[...]

await esbuild.build({
    [...]
    external: federationBuilder.externals,
    [...]
});

[...]

/*
  * Step 3: Let the build method do the additional tasks
  *   for supporting Native Federation
*/

await federationBuilder.build();

The method federationBuilder.build bundles the shared and exposed parts of your app.

The esBuildAdapter shown in the example allows to use ebuild for Native Federation-internal tasks. For tasks that are currently not possible with esbuild, it delegates to rollup. You find this implementation in our @softarc/native-federation-esbuild package.

If you want to go with another build tool, you can write your own adapter for it. Writing an adapter is just a matter of providing one function that aligns with our BuildAdapter type.

We are happy to announce that Version 1.0 of @softarc/native-federation is now available.

Please find further details on Native Federation here including an VanillaJS example and an React-based one.

Native Federation for Angular

The @angular-architects/native-federation package provides seamless integration with the Angular CLI. It uses an esbuild-based builder and offers schematics to automate repetitive tasks.

To get started, all you have to do is to install the package and initialize it with the init schematic:

npm i @angular-architects/native-federation -D

ng g @angular-architects/native-federation:init --project shell --type host

The rest is like with our Module Federation plugin.

If you want to try out Native Federation for Angular today, you can find detailed information including an example here.

Try it out now!

If you are interested, feel free to try Native Federation out now. Have a look to the following resources and play around with the examples linked there. Your feedback is more than welcome. If you run into any issues, feel free to report them via our GitHub page.

Resources

The readmes of our packages guide you through using Native Federation. Also, they point to some examples:

Examples

Credits

Big thanks to:

  • Zack Jackson for originally coming up with the great idea of Module Federation and its successful mental model
  • Tobias Koppers for helping to make Module Federation a first class citizen of webpack
  • Florian Rappl for an good discussion about these topics during a speakers dinner in Nuremberg
  • The Nx Team, esp. Colum Ferry, who seamlessly integrated webpack Module Federation into Nx and hence helped to spread the word about it (Nx + Module Federation === ❤️)
  • Michael Egger-Zikes for contributing to our Module Federation efforts and brining in valuable feedback
  • The Angular CLI-Team, esp. Alan Agius and Charles Lyding, for working on the experimental esbuild builder for Angular
  • Giorgio Boa for implementing the awesome vite plugin for module federation.