npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fluojs/runtime

v1.1.1

Published

Application bootstrap and runtime orchestration — module graph compilation, DI wiring, and diagnostics export for Fluo.

Readme

@fluojs/runtime

The assembly layer that compiles a module graph and wires DI and HTTP into a runnable application shell.

Table of Contents

Installation

npm install @fluojs/runtime

When to Use

Use this package when you need to:

  • Bootstrap a fluo application: Convert your modules into a running HTTP server or microservice.
  • Orchestrate DI and Lifecycle: Manage module-graph compilation, provider wiring, and application hooks (onModuleInit, onApplicationBootstrap).
  • Create Standalone Contexts: Run CLI tasks, scripts, or workers that need DI but not an HTTP server.
  • Diagnostic Inspection: Produce machine-readable platform snapshots and diagnostic issues for CLI export while leaving graph viewing and Mermaid presentation to Studio.

Quick Start

Minimal HTTP Application

The fluoFactory is the primary entrypoint for creating applications.

import { Module } from '@fluojs/core';
import { Controller, Get } from '@fluojs/http';
import { fluoFactory } from '@fluojs/runtime';
import { createNodejsAdapter } from '@fluojs/platform-nodejs';

@Controller('/')
class AppController {
  @Get()
  index() {
    return { hello: 'world' };
  }
}

@Module({
  controllers: [AppController],
})
class AppModule {}

// Create and start the application
const app = await fluoFactory.create(AppModule, {
  adapter: createNodejsAdapter({ port: 3000 }),
});

await app.listen();

Common Patterns

Application Context (No HTTP)

For background workers or scripts, use createApplicationContext to skip HTTP setup.

import { fluoFactory } from '@fluojs/runtime';

const context = await fluoFactory.createApplicationContext(AppModule);

// Resolve a service directly from the container
const userService = await context.get(UserService);
await userService.doWork();

await context.close();

Global Exception Filters

Handle cross-cutting errors by registering filters during bootstrap.

import { fluoFactory, type ExceptionFilterHandler } from '@fluojs/runtime';

class GlobalErrorFilter implements ExceptionFilterHandler {
  async catch(error, { response }) {
    console.error('Caught error:', error);
    response.setStatus(500);
    void response.send({ error: 'Internal Server Error' });
    return true; // Mark as handled
  }
}

const app = await fluoFactory.create(AppModule, {
  adapter: createNodejsAdapter({ port: 3000 }),
  filters: [new GlobalErrorFilter()],
});

Module Composition

fluo uses a strict module graph. Modules must explicitly export providers to make them available to importing modules.

@Module({
  providers: [DatabaseService],
  exports: [DatabaseService], // Make it available outside
})
class DatabaseModule {}

@Module({
  imports: [DatabaseModule],
providers: [UsersService], // UsersService can inject DatabaseService
})
class UsersModule {}

Behavioral Contracts

  • Request body parsing enforces maxBodySize while bytes are still streaming for both Web-standard and Node-backed requests.
  • On @fluojs/runtime/node, Node request body parsing normalizes the primary content-type media type before JSON and multipart detection, so mixed-case JSON and multipart headers preserve the documented parser behavior.
  • Node-backed and Web-standard request wrappers snapshot cheap request metadata before body parsing, then materialize body/rawBody once at the dispatch boundary so userland continues to observe synchronous parsed values.
  • Node-backed cookies/query values and Web-standard headers are snapshotted when the request wrapper is created, then lazily normalized and memoized per request; later upstream object mutations do not change the FrameworkRequest view.
  • Node-backed request context IDs prefer x-request-id and fall back to x-correlation-id when x-request-id is absent, so error responses and request-aware integrations keep the upstream correlation identifier.
  • ApplicationContext.get() and Application.get() memoize only direct root singleton class/factory provider lookups known at bootstrap, while preserving alias, request, transient, post-close, multi-provider, and container.override() resolution semantics.
  • multi: true provider tokens are not context-cache memoized: each get() call delegates to DI so the container can assemble a fresh contribution array while still reusing each contribution according to its own provider scope.
  • When duplicateProviderPolicy is warn or ignore, context-cache eligibility and lifecycle hook execution are based on the effective winning provider selected by bootstrap; stale losing providers do not seed cache entries or lifecycle hooks.
  • If application or context bootstrap fails after runtime resources or lifecycle instances have been created, fluo resets readiness, runs registered runtime cleanup callbacks, invokes shutdown hooks for instances resolved so far with bootstrap-failed, disposes the container, logs cleanup failures, and rethrows the original bootstrap error.
  • Application.listen() and microservice listen() are serialized with shutdown: overlapping startup calls share the same in-flight startup, shutdown waits for in-flight startup to settle, and a startup that races with shutdown cannot transition the shell back to ready after close begins.
  • Shutdown signal registration failures are user-observable: runNodeApplication(...), bootstrapNodeApplication(...), and adapter-owned runtime helpers close the already-started application with bootstrap-failed, log any close failure separately, and reject with the original registration error.
  • Shutdown signal unregistration failures do not skip application close: app.close() always continues through adapter shutdown, lifecycle hooks, runtime cleanup callbacks, and container disposal; if close otherwise succeeds it rejects with the unregistration error, and if close also fails it rejects with an aggregate containing both failures.
  • Connected microservices are owned children of their parent Application: startAllMicroservices() starts them sequentially and rolls back already-started children with bootstrap-failed if a later child fails, while Application.close(signal) closes connected children before parent lifecycle hooks, adapter shutdown, and container disposal.
  • FluoFactory.createMicroservice() preserves the original bootstrap/runtime-resolution error when cleanup fails and logs cleanup failures separately.
  • Bootstrap resolves independent singleton lifecycle providers concurrently, then runs lifecycle hooks in deterministic provider order.
  • Multipart parsing rejects payloads when the cumulative body size exceeds the configured multipart.maxTotalSize; runtime adapters default that limit to maxBodySize unless you override it.
  • createNodeHttpAdapter(...), bootstrapNodeApplication(...), and runNodeApplication(...) accept maxBodySize only as a non-negative integer byte count and fail fast during adapter creation/bootstrap when the value is invalid.
  • Response stream backpressure helpers settle waitForDrain() on drain, close, or error so streaming writers do not hang on dead connections.
  • Runtime health modules report /ready as starting with HTTP 503 until bootstrap marks them ready, and they return to starting as soon as application/context shutdown begins, including failed shutdown attempts.
  • Runtime health module readiness checks receive the current RequestContext, allowing public integrations to resolve runtime-exposed status providers without importing internal runtime tokens.
  • Signal-driven shutdown helpers preserve bounded drain semantics, log timeout/failure conditions, and set process.exitCode when shutdown does not finish cleanly, but they leave final process termination ownership to the surrounding host runtime.
  • Platform snapshot and diagnostic issue production stay in runtime; graph viewing, filtering presentation, and Mermaid rendering are Studio-owned contracts consumed by CLI and automation callers.
  • Platform component snapshots are runtime-owned contract payloads: each component reports readiness, health, dependency ids, telemetry tags, diagnostic issues, and resource ownership through ownership.ownsResources / ownership.externallyManaged. Runtime preserves those ownership flags in shell snapshots so adapters and package integrations can distinguish resources fluo must stop from externally managed resources the host owns.
  • Module graph compile-result caching is opt-in through moduleGraphCache: true; it keys entries by root module identity, runtime providers, validation tokens, core metadata versions, and the compile algorithm version, caches only successful compilations, and returns isolated graph copies so caller mutations cannot poison later bootstraps.

Public API Overview

  • fluoFactory: Lower-camel-case alias for the runtime bootstrap facade used in the package examples.
  • FluoFactory: Class-based runtime bootstrap facade with explicit static access.
  • Application: Extends ApplicationContext with listen(), dispatch(), and state.
  • ApplicationContext: Provides get<T>(token), close(), and access to container, modules, and bootstrap diagnostics.
  • LifecycleHooks: Convenience union covering OnModuleInit, OnApplicationBootstrap, OnModuleDestroy, and OnApplicationShutdown.
  • HealthModule.forRoot(options): Runtime-owned /health and /ready module facade whose readiness marker follows bootstrap and shutdown lifecycle transitions.
  • createHealthModule(options): Deprecated compatibility helper for the same runtime health module contract; prefer HealthModule.forRoot(...) in application-facing module imports.
  • ReadinessCheck: Function type used by runtime health modules. Checks receive the /ready request context and return a boolean or promise.
  • defineModule(cls, metadata): Programmatic module definition helper.
  • bootstrapApplication(options): Lower-level async bootstrap function.
  • bootstrapModule(...): Lower-level module graph bootstrap helper.
  • createBootstrapTimingDiagnostics(...), createRuntimeDiagnosticsGraph(...): Runtime-owned diagnostics snapshot helpers for CLI/support tooling. They produce machine-readable data; Studio owns viewer parsing, graph presentation, and Mermaid rendering.
  • PlatformShell, PlatformComponent, PlatformShellSnapshot, PlatformSnapshot, PlatformDiagnosticIssue, and related platform report types: Public lifecycle diagnostics and resource-ownership contracts used by runtime-aware packages. RuntimePlatformShell preserves component-provided ownership and emits validation/readiness/health diagnostics without requiring consumers to import internal runtime tokens.
  • createRequestAbortContext(...), trackActiveRequestTransaction(...), untrackActiveRequestTransaction(...): Request abort and active transaction helpers used by runtime-aware integrations.

Platform-Specific Subpaths

Use @fluojs/runtime/node and @fluojs/runtime/web for application-facing runtime helpers. The published internal* subpaths are reserved package-integration seams for first-party adapters and runtime-aware packages; they are documented here so package authors can identify the boundary without treating those seams as application-level helper contracts.

| Subpath | Purpose | | :--- | :--- | | @fluojs/runtime/node | Supported Node.js entrypoint for logger factories, Node adapter/bootstrap helpers, and shutdown signal registration. | | @fluojs/runtime/web | Shared Web-standard request/response utilities for Bun, Deno, and Cloudflare Workers, including createWebRequestResponseFactory, dispatchWebRequest, createWebFrameworkRequest, and parseMultipart. | | @fluojs/runtime/internal | Token-only internal seam for package integrations. | | @fluojs/runtime/internal-node | Node-only internal seam for adapter/runtime plumbing; prefer @fluojs/runtime/node in application code. | | @fluojs/runtime/internal/http-adapter | Internal HTTP adapter seam for platform packages. | | @fluojs/runtime/internal/request-response-factory | Internal request/response factory seam for platform packages. |

Node-Specific Subpath (@fluojs/runtime/node)

Logger factories and other supported Node-only helpers are not on the universal root entrypoint. Import them from the ./node subpath:

import {
  bootstrapNodeApplication,
  createConsoleApplicationLogger,
  createJsonApplicationLogger,
  createNodeHttpAdapter,
  runNodeApplication,
} from '@fluojs/runtime/node';
const adapter = createNodeHttpAdapter({
  port: 3000,
  maxBodySize: 1_048_576,
});

For the public Node runtime surface, maxBodySize, retryDelayMs, retryLimit, and shutdownTimeoutMs are number-only non-negative integers. Values such as '1mb', fractional retry counts, or negative shutdown timeouts are rejected immediately during adapter creation instead of being coerced later. Node request context IDs prefer x-request-id; when it is absent, x-correlation-id is used as the request ID fallback for runtime error responses and request-aware integrations.

  • createConsoleApplicationLogger(): Colorized console logger using process.stdout/process.stderr. The default remains the pretty format. Pass { mode: 'minimal' } for concise [fluo] LEVEL [context] message lines, { mode: 'silent' } to suppress runtime logger output, { level: 'warn' } or another threshold to filter lower-severity messages, and { color: false } when you need deterministic non-colored output.
  • createJsonApplicationLogger(): Structured JSON logger using process.stdout/process.stderr.
  • createNodeHttpAdapter(): Raw Node http/https adapter factory for adapter-first runtime setup. The helper normalizes the primary Node request content-type before JSON/multipart detection and accepts maxBodySize, retryDelayMs, retryLimit, and shutdownTimeoutMs only as non-negative integers.
  • bootstrapNodeApplication() / runNodeApplication(): Node-specific bootstrap helpers used by direct Node runtime flows.
  • createNodeShutdownSignalRegistration(), defaultNodeShutdownSignals(), registerShutdownSignals(): Shutdown registration helpers for hosts that need explicit signal wiring.

Runtime app logging is separate from CLI lifecycle reporting. Configure ApplicationLogger when you want to change logs emitted by the application/runtime itself:

import { createConsoleApplicationLogger, createJsonApplicationLogger } from '@fluojs/runtime/node';

const minimalLogger = createConsoleApplicationLogger({ mode: 'minimal', level: 'warn' });
const jsonLogger = createJsonApplicationLogger();

Use CLI reporter flags such as fluo dev --verbose when you need raw child-process output from the development command instead.

Lower-level Node compression internals stay behind the @fluojs/runtime/internal-node seam rather than the public @fluojs/runtime/node contract.

Related Packages

Example Sources