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

@zfig/bootstrap

v0.9.15

Published

Server bootstrap helper for zfig configuration library

Readme

@zfig/bootstrap

npm version

Server lifecycle management with graceful shutdown for zfig.

Install

npm install zfig @zfig/bootstrap

Basic Usage

Create vs Run

Create - returns server without starting:

import { schema, field } from "zfig";
import { bootstrap } from "@zfig/bootstrap";
import { z } from "zod";

const configSchema = schema({
  port: field({ type: z.number(), env: "PORT", default: 3000 }),
});

const service = bootstrap(configSchema, (config) => {
  // Return your server instance
  return createServer(config);
});

// Get server without listening
const { server, config } = await service.create();

Run - starts server with graceful shutdown:

// Starts listening and handles SIGTERM/SIGINT
await service.run();

Autorun

Automatically run when file is executed directly (not imported).

ESM

import { schema, field } from "zfig";
import { bootstrap } from "@zfig/bootstrap";
import { z } from "zod";
import express from "express";

const configSchema = schema({
  port: field({ type: z.number(), env: "PORT", default: 3000 }),
});

export default bootstrap(
  configSchema,
  { autorun: { enabled: true, meta: import.meta } },
  (config) => {
    const app = express();
    app.get("/health", (req, res) => res.send("ok"));
    return app;
  }
);

// node app.ts → auto-runs server
// import from app.ts → just exports service

CommonJS

const { schema, field } = require("zfig");
const { bootstrap } = require("@zfig/bootstrap");
const { z } = require("zod");

const configSchema = schema({
  port: field({ type: z.number(), env: "PORT", default: 3000 }),
});

module.exports = bootstrap(
  configSchema,
  { autorun: { enabled: true, module: module } },
  (config) => createServer(config)
);

Run Options

await service.run({
  port: 8080,              // Override config port
  host: "0.0.0.0",         // Bind to specific host
  onReady: () => {         // Called after listen succeeds
    console.log("Server ready");
  },
  onShutdown: () => {      // Called after server closes
    console.log("Server stopped");
  },
  configOverride: {        // Override config values
    debug: true,
  },
});

| Option | Type | Description | |--------|------|-------------| | port | number | Override port (default: from config or 3000) | | host | string | Bind to specific host | | onReady | () => void | Called after listen succeeds | | onShutdown | () => void | Called after server closes | | configOverride | object | Override config values |

Dynamic Run Options

Use a function to access resolved config:

export default bootstrap(
  configSchema,
  {
    autorun: {
      enabled: true,
      meta: import.meta,
      runOptions: (config) => ({
        port: config.serverPort || 3000,
        host: config.serverHost || "localhost",
      }),
    },
  },
  (config) => createServer(config)
);

Or static options:

autorun: {
  enabled: true,
  meta: import.meta,
  runOptions: { port: 3000, host: "localhost" },
}

Graceful Shutdown

Bootstrap handles graceful shutdown automatically:

  1. Listens for SIGTERM and SIGINT signals
  2. Calls server.close() to stop accepting new connections
  3. Waits for existing connections to complete
  4. Invokes onShutdown callback
  5. Resolves the run() promise
await service.run({
  onShutdown: () => {
    console.log("Cleanup complete");
  },
});
// Promise resolves after shutdown

Testing

Use create() to get the server without starting it:

import service from "./app";
import request from "supertest";

describe("app", () => {
  it("responds to health check", async () => {
    const { server } = await service.create({
      override: { port: 0 },
    });

    const response = await request(server).get("/health");
    expect(response.status).toBe(200);
  });
});

Create options:

await service.create({
  configPath: "./test-config.json",
  env: { PORT: "4000" },
  override: { debug: true },
});

API Reference

bootstrap(schema, factory)

Minimal signature without options.

const service = bootstrap(configSchema, (config) => server);

bootstrap(schema, options, factory)

Full signature with startup options.

const service = bootstrap(
  configSchema,
  {
    autorun: { enabled: true, meta: import.meta },
    configPath: "./config.json",
    onError: (error) => {
      console.error("Startup failed:", error);
    },
  },
  (config) => server
);

Startup Options

| Option | Type | Description | |--------|------|-------------| | autorun | AutorunOptions | Auto-run configuration | | configPath | string | Path to config file | | env | Record<string, string> | Environment variables | | secretsPath | string | Base path for secrets | | initialValues | object | Base config values | | override | object | Override all sources | | onError | (error: Error) => void | Called on config or factory errors |

Error Handling

The onError callback receives all errors during startup. For config errors, diagnostics are attached:

import { ConfigError } from "zfig";

bootstrap(
  configSchema,
  {
    onError: (error) => {
      if (error instanceof ConfigError && error.diagnostics) {
        console.error("Config resolution trace:", error.diagnostics);
      }
    },
  },
  (config) => server
);

service.create(options?)

Returns server and config without starting.

const { server, config } = await service.create({
  initialValues?: object,
  configPath?: string,
  env?: Record<string, string>,
  secretsPath?: string,
  override?: object,
});

service.run(options?)

Starts server and handles graceful shutdown.

await service.run({
  port?: number,
  host?: string,
  onReady?: () => void,
  onShutdown?: () => void,
  configOverride?: object,
});

Examples

Express

import { schema, field } from "zfig";
import { bootstrap } from "@zfig/bootstrap";
import { z } from "zod";
import express from "express";

const configSchema = schema({
  port: field({ type: z.number(), env: "PORT", default: 3000 }),
  name: field({ type: z.string(), default: "my-app" }),
});

export default bootstrap(
  configSchema,
  { autorun: { enabled: true, meta: import.meta } },
  (config) => {
    const app = express();
    app.get("/", (req, res) => res.json({ name: config.name }));
    return app;
  }
);

Fastify

import { schema, field } from "zfig";
import { bootstrap } from "@zfig/bootstrap";
import { z } from "zod";
import Fastify from "fastify";

const configSchema = schema({
  port: field({ type: z.number(), env: "PORT", default: 3000 }),
});

export default bootstrap(
  configSchema,
  { autorun: { enabled: true, meta: import.meta } },
  (config) => {
    const app = Fastify();
    app.get("/health", async () => ({ status: "ok" }));
    return app;
  }
);

Fastify's Promise-based listen() is supported automatically.

License

MIT