@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
buildorchestrates; phases compose.build(config)runs the full pipeline, whilerunBundlePhase,runPackagePhase, andrunBinPhaseremain individually callable against a sharedBuildContextfromcreateBuildContext.- 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-buildCLI — 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
| Export | Description |
|---|---|
build |
Run the full pipeline (bundle → package → bin) from a BuildConfig. |
createBuildContext |
Derive the shared BuildContext used by the individual phases. |
runBundlePhase |
Emit per-entry bundles and declarations for the configured formats. |
runPackagePhase |
Synthesize the output package.json, assets, and license file. |
runBinPhase |
Synthesize JavaScript bins and Node SEA native binaries. |
createMemoryMonitor / recover |
Observe build memory pressure and recover from soft limits. |
byNames / byPrefix |
Preset 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.
| Environment | Supported |
|---|---|
| Node.js >= 18 | ✅ |
| npm >= 8 | ✅ |
| TypeScript >= 5.9 | ✅ |
| Browser | ❌ |
License
API Reference§
Module Structure
21 modules · 237 total exports
@hyperfrontend/builder
Composable, vendor-neutral build toolkit for TypeScript libraries, JS bins, and Node SEA native binaries.
@hyperfrontend/builder/bin
JS bin synthesis, composed via runBinPhase.
@hyperfrontend/builder/bin/native
Node SEA native binary primitives: config generation, blob prep, host resolution, postject injection, and macOS code-sign cleanup.
@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.
@hyperfrontend/builder/bin/script
JS bin synthesis primitives: rollup-driven bundling with shebang + bootstrap footer + chmod.
@hyperfrontend/builder/bundle
Bundle phase orchestrator: entry discovery, externals, Rollup, and declaration emission, run in order via runBundlePhase.
@hyperfrontend/builder/bundle/declarations
tsc-driven `.d.ts` emission, path flattening, the bundled-dep d.ts pre-pass, per-entry inlining, and sibling-subpath dedup.
@hyperfrontend/builder/bundle/dedupe
Additive post-emit pass that hoists first-party modules inlined into multiple per-entry bundles into shared chunks. See hoistSharedFirstParty.
@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.
@hyperfrontend/builder/bundle/dependencies/worker
Forked-worker entry script that runs a single dependency pre-pass via runPrePassWorkerJob.
@hyperfrontend/builder/bundle/entries
Entry-point discovery, resolution, and platform filtering primitives.
@hyperfrontend/builder/bundle/externals
Externals resolution primitives: package.json scanning and globals validation for IIFE / UMD bundles.
@hyperfrontend/builder/bundle/rollup
Rollup driver: per-format descriptor builders and the per-entry forked-worker dispatcher.
@hyperfrontend/builder/bundle/rollup/worker
Forked-worker entry script that runs a single per-entry rollup pass via runRollupWorkerJob.
@hyperfrontend/builder/memory
Opt-in memory monitor and the always-on `recover()` event-loop yield.
@hyperfrontend/builder/models
Type definitions for builder configuration, context, and results.
@hyperfrontend/builder/package
Package phase: package.json synthesis, asset copy, and license collection composed via runPackagePhase.
@hyperfrontend/builder/package/assets
Generic, data-driven asset-copy primitive consumed by the package phase. See copyAssets.
@hyperfrontend/builder/package/json
package.json synthesis primitives: read, inherit, filter, generate exports/CDN paths, and write the dist manifest.
@hyperfrontend/builder/package/licenses
Opt-in third-party license collection that writes `THIRD_PARTY_LICENSES.md` to the dist root.
@hyperfrontend/builder/presets
Predicate factories for the IsWorkspacePackagePredicate slot on BuildConfig, opting a build into workspace-aware behavior.