Skip to content

API reference

Every export of every entry point, with signatures, options, defaults, return shapes, errors and trace events. Defaults and behaviour here are checked against src/ and the tests; where the code does something surprising, this reference says so rather than describing what it was meant to do. Types live in src/types.d.ts (and src/core.d.ts for ./core). The guide pages are the tutorial; this is the reference.

Import File Exports
@johnhenry/mport src/index.mjs everything in ./core, plus the v1 functions mport (also the default export), MPort, MPortURL
@johnhenry/mport/firefox src/firefox.mjs the same names as @johnhenry/mport. No file it loads contains a two-argument import(), which older Firefox rejects at parse time. See Firefox.
@johnhenry/mport/core src/core.mjs the router, providers, strategies, registry, import-map, lockfile, runtime and semver exports, without the v1 functions
@johnhenry/mport/vite src/vite.mjs mportVite (also the default export). Node-side build tooling.
@johnhenry/mport/rollup src/rollup.mjs mportRollup (also the default export). Node-side build tooling.
@johnhenry/mport/node src/node.mjs installedRegistry: a registry client that reads installed packages from disk. Node only; it is the one entry point that imports node: modules, which is why it is not in ./core.
mport (bin) bin/mport.mjs the CLI

The module entry points are ES modules with no dependencies. The package is plain JavaScript that runs in browsers, Deno and Node; the router’s defaults (fetch, import()) are the host’s.

The ./core exports, grouped:

Group Exports
Router createRouter, route
Specifiers parseSpecifier, keyOf, isRoutable
Providers provider, esmSh, jsDelivr, unpkg, jspm, jsr, github, local, custom, origin, DEFAULT_ORIGINS
Strategies fallback, race, adaptive, weighted, prefer, verified, cache, sri
Health and errors HealthRegistry, RoutingError, SkipError, IntegrityError, ResolutionError
Registry createRegistry, pickVersion, outdated, entryInfo, entryOf, resolveExports
Import maps compileImportMap, mergeImportMaps, renderImportMap, importMapText, importMapHash, cspHash, renderImportMapCsp, modulePreloads, renderModulePreload
Lockfiles createLock, lockKey, parseImports
Browser runtime injectImportMap, injectModulePreload, startup, createImporter
Misc semver, DEFAULT_CACHE_KEY

mport splits every import into two halves.

Resolution is deterministic. The router parses the specifier, matches it to a route, turns a range into one exact version (from the npm or JSR registry, or from the lockfile) and, for providers that serve raw files, looks up the entry file. None of this depends on which CDN is up.

Transport is adaptive. The route’s node (a provider or a strategy that combines providers) chooses which provider serves that exact artifact: in order, by racing, by weight and health, by target, from a cache, with integrity checks.

Every provider declares a build: what it actually serves. jsDelivr and unpkg both serve the files as published to npm (build "npm"); esm.sh and jspm transform packages, so their output is a different artifact even for the same version. Only providers with the same build are mirrors of each other. A lockfile pins the build as well as the version, so failover moves between mirrors and never silently switches to a different build.

The router’s output is a Resolution (one specifier) or an import map plus a lockfile (many specifiers). The browser never needs mport at runtime unless you want failover after the page has loaded, which only router.import() gives.

Every export, from @johnhenry/mport (all of them), @johnhenry/mport/firefox (the same names) and @johnhenry/mport/core (all but the v1 functions). Each links to its full entry in this reference.

Export Signature What it does
createRouter (routes, options?) → Router Build a router. Options: probe, lock, resolveVersions, circuitBreaker, health, target, capabilities, fetch, importer, registries, registry, onEvent, now, allowCommonJS, name
router.resolve (specifier, options?) → Promise<Resolution | null> Resolve one specifier. Options: signal, exclude, build, integrity, target, capabilities, relock, onEvent
router.import (specifier, options?) → Promise<module> Resolve and import, failing over when the import fails
router.build (specifiers, { scopes?, conflicts?, graph?, dependencies?, dependencyDepth?, signal? }?) → Promise<{ importMap, lock, conflicts, dependencies?, graph? }> Resolve many and compile an import map and lockfile; conflicts: "scope" scopes conflicting versions per dependent; graph hashes every file of each module’s import graph; dependencies adds raw-CDN packages’ manifest dependencies
router.health, router.lock, router.name The router’s HealthRegistry, its in-memory lock, its name
route (match, use) → { match, use } One array-form route
esmSh, jsDelivr, unpkg, jspm, jsr, github, local (options?) → Provider Built-in providers
custom (template, options?) → Provider A base URL or a {name}/{version}/{path}/{entry}/{scope}/{bare} template
provider (definition) → Provider Define your own provider
origin (pathOrOrigin) → Provider A v1 origin as a provider
fallback (...nodes) or ({ providers, circuitBreaker }) In order
race (...nodes) First success wins
adaptive, weighted (...[node, weight]), (node, weight) Ordered by weight and health
prefer ({ [target]: node, default? }) By target
verified (node, { algorithm? }) SRI check against the pinned hash
cache ({ store?, name?, prefix?, ttl? }?) Remembered resolutions
sri (bytes, algorithm?) → Promise<string> Compute an SRI hash
HealthRegistry new ({ failures?, reset?, now? }?) Per-provider health and circuit breaker
RoutingError, SkipError, IntegrityError, ResolutionError classes See the errors table
parseSpecifier, keyOf, isRoutable Specifier parsing, import-map keys, routability
installedRegistry ({ root, fallback? }) Registry client over installed packages (from @johnhenry/mport/node, not in ./core)
createRegistry ({ fetch?, npm?, jsr? }?) Version, entry, info() and manifest() lookups
pickVersion (name, range, info) → string The version registry.version() chooses from registry.info()
outdated (lock, { registry, names?, signal? }) → Promise<{ outdated, skipped }> What mport outdated prints: current, wanted and latest per lockfile entry
entryInfo, entryOf, resolveExports (packageJson, subpath?) Entry-file selection and CommonJS detection
compileImportMap, mergeImportMaps Import maps from resolutions; merging
renderImportMap, renderModulePreload, modulePreloads (importMap, options?) HTML strings (<script type="importmap">, <link rel="modulepreload">) for server rendering
renderImportMapCsp, importMapHash, importMapText, cspHash async (importMap, { algorithm?, nonce? }?) The CSP 'sha256-…' of the inline import map, for static sites that cannot use a nonce
createLock, lockKey Lockfiles (including the files map) and their keys
parseImports (source, { dynamic? }?) → string[] The specifiers a module imports statically; what build({ graph }) uses
mportVite, mportRollup (router, options?) → Plugin Bundler plugins, from @johnhenry/mport/vite and /rollup (not in ./core)
injectImportMap, injectModulePreload, startup, createImporter Browser runtime helpers (startup() rejects on Firefox)
semver namespace parse, valid, compare, satisfies, maxSatisfying
mport (default), MPort, MPortURL The v1 API (not in ./core)
DEFAULT_ORIGINS, DEFAULT_CACHE_KEY v1 defaults

Errors, in one line each: ResolutionError means the package or version can’t exist (or the registry is unreachable) and no CDN is blamed; RoutingError (an AggregateError) means every provider in a fallback or race failed or was skipped; SkipError is a provider declining without trying; IntegrityError is verified() rejecting bytes, or build({ graph }) finding a file that no longer matches the lockfile. Types ship in src/types.d.ts.