Orchestrator 4.8.0: one build per package, no more stitching.Read the announcement and share your feedback →

Builder

Reference for runEsBuildBuilder and EsBuildBuilderOptions — the Native Federation esbuild adapter's high-level entry point.

runEsBuildBuilder is the high-level entry point most projects use. It loads federation.config.js, registers the esbuild adapter with the core, runs the initial build, and — when watch is on — keeps a file watcher and rebuild queue running until you call close().

Signature

import { runEsBuildBuilder } from '@softarc/native-federation-esbuild';

const federation = await runEsBuildBuilder(
  federationConfigPath: string,
  options: EsBuildBuilderOptions,
): Promise<EsBuildBuilder>;

Minimal Call

const federation = await runEsBuildBuilder('federation.config.js', {
  outputPath: 'dist',
  entryPoints: ['src/bootstrap.tsx'],
});
await federation.close();

Everything else has a sensible default. The only required field is outputPath — the adapter throws [esbuild-builder] outputPath is required if it is missing.

EsBuildBuilderOptions

OptionTypeDefaultNotes
outputPathstringrequiredDirectory that receives remoteEntry.json and the bundled artifacts.
workspaceRootstringprocess.cwd()Resolved against cwd(). esbuild runs from this directory, and relative tsConfig, cachePath, outputPath and fileReplacements paths resolve against it. Useful when the build script runs from a monorepo root.
tsConfigstring<workspaceRoot>/tsconfig.json if it existsResolved against workspaceRoot. Forwarded to esbuild's tsconfig option for the source-code bundle, and the core reads its paths for shared mappings. Without one, esbuild finds the nearest tsconfig.json per file. Point it at tsconfig.base.json when your paths only live there.
cachePathstringcore defaultA relative path is resolved against workspaceRoot; an absolute path is used as-is. Otherwise the core's getDefaultCachePath is used. See Caching.
projectNamestring—Forwarded to the core; used for logging and cache scoping in multi-project workspaces.
entryPointsstring[]—Source entries for the federation build. Usually the files referenced by exposes in federation.config.js.
packageJsonstring—Path to the project's package.json. Override when it is not next to the federation config.
devbooleanfalseEnables sourcemaps and disables minification in both the source-code and node-modules esbuild contexts. Also flips the process.env.NODE_ENV define to "development".
watchbooleanfalseStarts the file watcher and rebuild queue. The returned federation object stays live until you call close().
watchLinkedDepsbooleanfalseIn watch mode, also polls shared packages that are npm linked into a checkout outside node_modules, so rebuilding the library rebuilds this app. See Watch Mode.
watcherWatchPort['watch']Node's fs.watchSwaps in another watching implementation.
verbosebooleanfalseSets the adapter's log level to verbose. Rebuild cancellations, watcher events and full error stacks are logged.
rebuildDelaynumber50 (ms)Debounce before a rebuild fires after a file change. Clamped to a minimum of 10 ms internally.
cacheExternalArtifactsbooleantrueSet false to force the core to re-bundle shared node-modules on every build. Only useful when debugging cache issues.
adapterConfigEsBuildAdapterConfig{ plugins: [] }esbuild-specific extension points. See Adapter Configuration.

Return Value — EsBuildBuilder

interface EsBuildBuilder {
  federationInfo: FederationInfo;
  externals: string[];
  options: NormalizedEsBuildBuilderOptions;
  close(): Promise<void>;
}

Watch Mode

When watch: true, the adapter:

  1. Creates an NF file watcher that observes every source file the initial build touched, plus the source directories of your shared mappings — so a file added to a mapped library after the last build is picked up too.
  2. Queues a rebuild on change. Rebuilds are debounced by rebuildDelay and serialized through a RebuildQueue — a new change mid-build cancels the in-flight rebuild via AbortSignal rather than racing it. The changes of a cancelled or failed rebuild carry over into the next one.
  3. Calls rebuildForFederation on the core, which only re-bundles the entry points whose inputs changed.

A shared package you are developing through npm link sits outside the watched sources. Set watchLinkedDeps: true to have the watcher poll its real directory as well. See Watching npm-linked shared dependencies.

Rebuild outcomes:

Lower-Level API — createEsBuildAdapter

If you drive buildForFederation / rebuildForFederation yourself (e.g. integrating with a custom dev server or another build tool's lifecycle), skip runEsBuildBuilder and construct just the adapter:

import { createEsBuildAdapter } from '@softarc/native-federation-esbuild';
import { setBuildAdapter, buildForFederation } from '@softarc/native-federation';

const adapter = createEsBuildAdapter({ plugins: [] }, { workspaceRoot: process.cwd() });
setBuildAdapter(adapter);

await buildForFederation(config, normalizedOptions, externals);
await adapter.dispose();

The first argument is the EsBuildAdapterConfig. The optional second argument takes workspaceRoot, the directory esbuild runs from; it defaults to the working directory. runEsBuildBuilder passes its own workspaceRoot here.

createEsBuildAdapter returns an NFBuildAdapter with three methods and an externalsCacheKey (see Shared Packages and the Cache):

For 99% of projects, runEsBuildBuilder is the right call. Reach for createEsBuildAdapter only when the core's built-in build loop doesn't fit your workflow.