@hyperfrontend/builder

Composable, vendor-neutral build toolkit for TypeScript libraries, JS bins, and Node SEA native binaries.

What is @hyperfrontend/builder?

@hyperfrontend/builder is a build-time Node.js toolkit that turns a TypeScript source tree into a publishable npm package. From a single declarative config it discovers entry points, resolves externals, bundles each entry in isolation, emits type declarations, synthesizes the output package.json, copies assets, and, optionally, produces JavaScript bins and standalone Node SEA native binaries.

It is vendor-neutral: nothing about a consumer's workspace (package naming, which deps are first-party, hoist policy) is hard-coded. You inject those opinions through predicates and config, so the same toolkit drives a leaf utility library and a multi-entry framework alike.

Key Features

  • Multi-format output: emit ESM, CJS, IIFE, and UMD bundles from one config; omit a format to skip it.
  • Bins & native binaries: synthesize JavaScript bins and cross-platform Node SEA native executables.
  • Per-entry isolation: each entry point bundles independently, keeping peak memory bounded on large graphs.
  • Predicate-driven extensibility: classify workspace packages, externals, and assets with plain functions instead of config DSLs.
  • Self-contained packages: bundle first-party and third-party dependencies, with an additive post-emit pass that dedups shared internals into _shared/ chunks.
  • Composable phases: run the bundle, package, and bin phases together via build, or drive each phase on its own.

Architecture Highlights

  • build orchestrates; phases compose. build(config) runs the full pipeline, while runBundlePhase, runPackagePhase, and runBinPhase remain individually callable against a shared BuildContext from createBuildContext.
  • Predicate extension model. Externals, workspace membership, and asset conditions are expressed as predicates (byNames, byPrefix, or your own), keeping the core free of workspace-specific assumptions.
  • Memory-aware by design. Per-entry bundling plus an opt-in memory monitor (createMemoryMonitor, recover) keep large builds inside constrained environments.

Why Use @hyperfrontend/builder?

Most library bundlers assume one entry point, one format, and a fixed notion of what is "external." @hyperfrontend/builder is built for monorepos that publish many packages with shared internals and varied output needs:

  • You need ESM and CJS and CDN-ready bundles from the same source.
  • You ship CLIs and want native binaries without standing up a separate SEA pipeline.
  • You want bundled, self-contained packages without forcing transitive installs on consumers.
  • You want to script the build programmatically (or hand it to the hf-build CLI) without adopting a heavyweight, opinionated framework.

Installation

npm install --save-dev @hyperfrontend/builder

typescript is a required peer dependency: the builder drives declaration emit through your project's TypeScript and is built against TypeScript >= 5.9. Install it alongside the builder if your project does not already depend on it:

npm install --save-dev "typescript@>=5.9"

Quick Start

Drive the full pipeline programmatically with build:

import { build, byPrefix } from '@hyperfrontend/builder'

const result = await build({
  projectRoot: '/abs/path/to/libs/my-lib',
  workspaceRoot: '/abs/path/to/workspace',
  // Treat sibling workspace packages as first-party (bundled), everything else external.
  isWorkspacePackage: byPrefix('@my-scope/'),
  esm: { bundleWorkspaceDeps: true },
  cjs: { bundleWorkspaceDeps: true },
})

console.log(result)

Or build straight from a JSON config with the bundled CLI:

# Reads ./builder.config.json by default
hf-build --config ./builder.config.json --verbose

Need finer control? Compose the phases yourself:

import { createBuildContext, runBundlePhase, runPackagePhase } from '@hyperfrontend/builder'

const ctx = createBuildContext(config)
await runBundlePhase(ctx, config)
await runPackagePhase(ctx, config, /* formats */ [])

API Overview

ExportDescription
buildRun the full pipeline (bundle → package → bin) from a BuildConfig.
createBuildContextDerive the shared BuildContext used by the individual phases.
runBundlePhaseEmit per-entry bundles and declarations for the configured formats.
runPackagePhaseSynthesize the output package.json, assets, and license file.
runBinPhaseSynthesize JavaScript bins and Node SEA native binaries.
createMemoryMonitor / recoverObserve build memory pressure and recover from soft limits.
byNames / byPrefixPreset predicate factories for classifying packages and externals.

Advanced primitives are available under sub-path entries: for example @hyperfrontend/builder/presets, @hyperfrontend/builder/bundle, @hyperfrontend/builder/package, and @hyperfrontend/builder/bin. See the documentation for the full surface.

Compatibility

@hyperfrontend/builder is a build-time tool that runs on Node.js. It is not intended for browser, Web Worker, or CDN runtimes.

EnvironmentSupported
Node.js >= 18
npm >= 8
TypeScript >= 5.9
Browser

License

MIT

API Reference§

View:
Organized by entry point

Module Structure

|

21 modules · 246 total exports

@hyperfrontend/builder

Composable, vendor-neutral build toolkit for TypeScript libraries, JS bins, and Node SEA native binaries.

9 fn30 int9 type

@hyperfrontend/builder/bin

JS bin synthesis, composed via runBinPhase.

1 fn

@hyperfrontend/builder/bin/native

Node SEA native binary primitives: config generation, blob prep, host resolution, postject injection, and macOS code-sign cleanup.

11 fn14 int3 var

@hyperfrontend/builder/bin/native/worker

Forked-worker entry script that runs a single postject inject via runInjectWorkerJob, isolating its ~138 MB buffer from the parent RSS.

1 fn2 int

@hyperfrontend/builder/bin/script

JS bin synthesis primitives: rollup-driven bundling with shebang + bootstrap footer + chmod.

2 fn1 int

@hyperfrontend/builder/bundle

Bundle phase orchestrator: entry discovery, externals, Rollup, and declaration emission, run in order via runBundlePhase.

1 fn1 int

@hyperfrontend/builder/bundle/declarations

tsc-driven `.d.ts` emission, path flattening, the bundled-dep d.ts pre-pass, per-entry inlining, sibling-subpath dedup, and the emitted-type-surface check.

14 fn5 int

@hyperfrontend/builder/bundle/dedupe

Additive post-emit pass that hoists first-party modules inlined into multiple per-entry bundles into shared chunks. See hoistSharedFirstParty.

12 fn14 int1 type

@hyperfrontend/builder/bundle/dependencies

Per-format pre-pass and externalize plugin that bundle each third-party (and workspace) dep once, then reroute every entry's import to it.

9 fn10 int3 type

@hyperfrontend/builder/bundle/dependencies/worker

Forked-worker entry script that runs a single dependency pre-pass via runPrePassWorkerJob.

1 fn2 int

@hyperfrontend/builder/bundle/entries

Entry-point discovery, resolution, and platform filtering primitives.

4 fn

@hyperfrontend/builder/bundle/externals

Externals resolution primitives: package.json scanning and globals validation for IIFE / UMD bundles.

2 fn1 int

@hyperfrontend/builder/bundle/rollup

Rollup driver: per-format descriptor builders and the per-entry forked-worker dispatcher.

8 fn6 int1 type

@hyperfrontend/builder/bundle/rollup/worker

Forked-worker entry script that runs a single per-entry rollup pass via runRollupWorkerJob.

1 fn4 int1 type

@hyperfrontend/builder/memory

Opt-in memory monitor and the always-on `recover()` event-loop yield.

2 fn2 int

@hyperfrontend/builder/models

Type definitions for builder configuration, context, and results.

28 int9 type

@hyperfrontend/builder/package

Package phase: package.json synthesis, asset copy, and license collection composed via runPackagePhase.

2 fn

@hyperfrontend/builder/package/assets

Generic, data-driven asset-copy primitive consumed by the package phase. See copyAssets.

1 fn

@hyperfrontend/builder/package/json

package.json synthesis primitives: read, inherit, filter, generate exports/CDN paths, and write the dist manifest.

9 fn3 int

@hyperfrontend/builder/package/licenses

Opt-in third-party license collection that writes `THIRD_PARTY_LICENSES.md` to the dist root.

3 fn1 type

@hyperfrontend/builder/presets

Predicate factories for the IsWorkspacePackagePredicate slot on BuildConfig, opting a build into workspace-aware behavior.

2 fn

Related