@hyperfrontend/features
SDK, CLI, and dev server for building, embedding, and orchestrating hyperfrontend micro-frontend features.
What is @hyperfrontend/features?
Embedding another team's app inside your page usually means an iframe, a pile of postMessage conventions nobody wrote down, and a frame that never quite fits the space you gave it. @hyperfrontend/features turns that into a contract: the feature app declares what it sends, what it accepts, and which display modes it supports; the host picks a mode and gets a typed handle back. The messaging protocol underneath is @hyperfrontend/nexus, and this package adds everything around it: iframe management, display modes and sizing, the open/close lifecycle, and a CLI that packages a feature app into an installable shell.
// In the feature app, from '@hyperfrontend/features/hostee'
const feature = createFeature({ name: 'checkout', contract })
await feature.ready()
feature.send('order-placed', { id: 'A-1094' })
// In the host app, from '@hyperfrontend/features/host'
const checkout = createShell({ modes: { dialog: mountDialog }, url: 'https://checkout.example.com' })
checkout.on('order-placed', (order) => showReceipt(order))
checkout.open({ displayMode: DisplayMode.Dialog })
It is organized into independent subpath entry points so consumers import only the surface they need.
Key Features
- Host SDK (
/host) - Embed features with a shell factory, display modes (embedded, dialog, popup, standalone), and open/close lifecycle. - Hostee SDK (
/hostee) - Initialize a feature app, declare its contract, and manage its lifecycle. - CLI (
/cli) -init,build, anddevcommands driven byfeature.config.*, plusservefor production static hosting. - Dev server (
/server) - Static file server plus a debug UI for inspecting host/hostee message traffic; the same core backs thehf serveproduction server. - Zero-config bundling - Direct dependencies are bundled by
@hyperfrontend/builder, so generated shells stay self-contained.
Architecture Highlights
The package separates the host and hostee surfaces behind independent subpath exports and builds them on top of the Nexus messaging layer. The architecture guide diagrams the host/hostee handshake, the display modes, and how a shell is generated.
Why Use @hyperfrontend/features?
You get typed host and hostee SDKs, a CLI, and a dev server for composing micro-frontend features, and it works with any framework (React, Vue, Angular, vanilla JS) and build tool. Features build into self-contained shell packages with their dependencies bundled in, so a host installs one package and inherits no transitive install burden.
Installation
npm install @hyperfrontend/features
Quick Start
In a feature app (the hostee), declare a contract and connect to whatever host embeds it:
import { createFeature } from '@hyperfrontend/features/hostee'
const feature = createFeature({
name: 'clock',
contract: { emitted: [{ type: 'tick' }], accepted: [{ type: 'set-timezone' }] },
})
await feature.ready()
feature.on('set-timezone', ({ tz }) => render(tz))
setInterval(() => feature.send('tick', Date.now()), 1000)
In a host app, build a shell and surface the feature in any display mode:
import { builtInDisplayModes, createShell, DisplayMode } from '@hyperfrontend/features/host'
const shell = createShell({
modes: builtInDisplayModes,
url: 'https://features.example.com/clock',
container: '#clock-slot',
displayMode: DisplayMode.Embedded,
})
shell.on('tick', (time) => console.log('feature said', time))
shell.open()
shell.send('set-timezone', { tz: 'UTC' })
Presentation is host-controlled and contract-preconfigured: a feature declares the display modes it supports (display.modes in feature.config.*, plus per-mode defaults like fixed embedded dimensions or the dialog box footprint and position), the generated shell builds in exactly those modes, and the host picks one per open. The SDK measures the host-side space and reports it to the feature as exact pixels (the initial size travels with the mode announcement itself), and frames stay hidden until the session opens. In dialog mode the feature draws its own dialog box inside a transparent full-viewport pane and backdrop/Escape dismissal is coordinated for you. The host SDK docs cover the modes one by one.
Contract actions may carry a required: true flag on accepted entries, which denies the connection unless the counterpart emits that type. Unflagged actions never gate the connection, so adding actions to a contract stays backward compatible.
The SDK's own traffic — the heartbeat, the presentation announcements, dismiss signals, dirty state, and the request/response envelopes — rides the same channel under a reserved __hf: prefix and is filtered out before your handlers run. Your contract must not declare action types beginning with __hf:; everything the plane carries is listed in the architecture guide.
Both sides can opt into an encrypted envelope: pass protocol: 'v1', or protocol: 'v2' together with a sharedKey, to createShell and createFeature, and the two sides negotiate it during the connection handshake. Handshake frames stay plaintext while product messages (including sends queued before the handshake) travel encrypted. The sharedKey belongs to v2 alone: selecting v2 without a non-empty key throws immediately, while v1 takes no key.
A contract may carry a semver version, or createFeature can receive a version option that takes precedence over contract.version. Each side presents its version during the handshake, and incompatible cuts (a different major, or a different minor below 1.0.0) are denied before the channel opens, surfacing as an error on both handles. A side without a version always passes the check, so unversioned peers keep connecting.
Contract entries with a schema are enforced on both ends: send validates the payload against the sender's own emitted schema and throws in the sender's frame before anything crosses the wire, while incoming messages are validated against the receiver's own accepted schema. An invalid payload is dropped and surfaced as an error event shaped { reason: 'invalid-payload', type, errors }. Schema-less actions pass through unchanged.
What each of these controls is actually worth, and which parts of an integration's security remain the operator's job rather than the SDK's, is stated once, in the Security Model.
From the command line, scaffold, build, and serve features with the bundled hf CLI:
npx @hyperfrontend/features init # scaffold the hostee glue into an app
npx @hyperfrontend/features build --protocol v2 # generate + bundle a publishable shell package
npx @hyperfrontend/features dev # serve apps with the debug UI
npx @hyperfrontend/features serve --root dist # serve a built site for production
API Overview
| Entry point | Purpose |
|---|---|
@hyperfrontend/features | Shared types, contract validation, defineConfig |
@hyperfrontend/features/host | Host-side SDK (shell, display modes, lifecycle) |
@hyperfrontend/features/hostee | Hostee-side SDK (feature init, lifecycle) |
@hyperfrontend/features/cli | CLI (init, build, dev, serve) and hf bin |
@hyperfrontend/features/server | Dev server, debug UI, and production static server |
Using Nx?
nx add @hyperfrontend/featuresinstalls the package and runs itsinitgenerator to declare the dependency. The package also shipsinit/featuregenerators andbuild/serveexecutors, importable from the@hyperfrontend/features/nx/generatorsand@hyperfrontend/features/nx/executorsentry points, that use the consumer workspace's@nx/devkitfor formatting and installs when present, falling back to built-in equivalents.
Compatibility
| Environment | Supported |
|---|---|
| Node.js >= 18 | ✅ |
| Modern Browsers | ✅ |
| Tree Shakeable | ✅ |
License
Guides using @hyperfrontend/features
How to compose independently shipped features on one page
I need several independently built, independently deployed apps working together on one page, coordinating with each other, without merging codebases and without one failure taking down the rest.
How to detect and handle an unresponsive feature
An embedded feature can hang, crash, or lose its tab throttling fight; I need the host to notice within seconds, tell the user honestly, and recover when it returns.
How to embed a feature someone else shipped
Another team shipped their app as a feature package; I need it running inside my page, alive and observable, without learning their stack.
API Reference§
Module Structure
12 modules · 186 total exports
@hyperfrontend/features
SDK, CLI, and dev server for building and embedding hyperfrontend micro-frontend features.
@hyperfrontend/features/cli
Programmatic entry point for the hyperfrontend features CLI (`init`, `build`, `dev`, `serve`). Exposes the argv dispatcher consumed by the `hf` bin plus the individual command runners, the tiered config loader, and the build-config resolver so the surface can be driven in-process and unit-tested.
@hyperfrontend/features/generators
Pure generators that turn a resolved config + contract into staged output.
@hyperfrontend/features/host
Host-side SDK for embedding hyperfrontend features (shell factory, display modes, lifecycle).
@hyperfrontend/features/hostee
Hostee-side SDK for feature apps (feature initialization and lifecycle).
@hyperfrontend/features/nx/executors
Nx executors entry point: the `build` and `serve` executors plus their option shapes, for programmatic invocation and typed composition.
@hyperfrontend/features/nx/executors/build
Nx `build` executor entry point.
@hyperfrontend/features/nx/executors/serve
Nx `serve` executor entry point.
@hyperfrontend/features/nx/generators
Nx generators entry point: the `init` and `feature` generators plus their option shapes, for programmatic invocation and typed composition.
@hyperfrontend/features/nx/generators/feature
Nx `feature` generator entry point.
@hyperfrontend/features/nx/generators/init
Nx `init` generator entry point.
@hyperfrontend/features/server
Dev server, debug UI, and production static server for feature apps. Serves each app's compiled output on its own port and hosts the in-browser debug UI (display-mode, resize, message-log, and security controls) at the root of a control server. The same static core also powers `hf serve`, the production server with compression, conditional requests, and header rules, whose pipeline is open for custom steps.