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

@emmett-community/emmett-expressjs-with-openapi

v0.5.0

Published

Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core

Readme

@emmett-community/emmett-expressjs-with-openapi

Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core. This package wires express-openapi-validator into the Emmett application builder so you can validate requests, responses, security handlers, file uploads, and formats from a single OpenAPI document.

npm version License: MIT Build and test

Features

  • OpenAPI 3.x validation - Validate requests, responses, security, and file uploads.
  • Operation handlers - Auto-wire handlers from operationId or x-eov-operation-handler.
  • Problem Details middleware - RFC 7807 error responses out of the box.
  • ETag helpers - Built-in optimistic concurrency utilities.
  • Testing helpers - ApiSpecification and ApiE2ESpecification for tests.
  • Optional add-ons - Firebase Auth security handlers and Pino HTTP logging.

Why this package?

  • Built as a standalone module extracted from the original @event-driven-io/emmett repo so it can evolve independently.
  • Keeps the OpenAPI document as the single source of truth across manual routers, validation, and operationHandlers.
  • Ships with batteries included: problem-details error handling, helpers for tests, and examples for real-world setups.

Installation

npm install @emmett-community/emmett-expressjs-with-openapi
npm install express-openapi-validator            # optional: OpenAPI validation
npm install pino-http                            # optional: HTTP logging
npm install @my-f-startup/firebase-auth-express  # optional: Firebase Auth handlers

Peer Dependencies

Required:

  • @event-driven-io/emmett ^0.39.1
  • express ^4.19.2
  • express-async-errors ^3.1.1
  • http-problem-details ^0.1.5

TypeScript types:

  • @types/express ^4.17.21
  • @types/supertest ^6.0.2 (if using testing helpers)

Optional (feature-gated):

  • express-openapi-validator ^5.3.7 (OpenAPI validation)
  • pino-http ^9.0.0 (HTTP logging)
  • @my-f-startup/firebase-auth-express 0.1.0 (Firebase Auth handlers)
  • supertest ^7.0.0 (required by testing helpers)

Versions follow what is listed in package.json.

Quick start

import {
  getApplication,
  createOpenApiValidatorOptions,
  startAPI,
} from '@emmett-community/emmett-expressjs-with-openapi';

const app = await getApplication({
  apis: [myApi],
  openApiValidator: createOpenApiValidatorOptions('./openapi.yaml', {
    validateRequests: true,
    validateResponses: process.env.NODE_ENV === 'development',
  }),
});

startAPI(app, { port: 3000 });

Configuration

OpenAPI validation

const app = await getApplication({
  apis: [myApi],
  openApiValidator: createOpenApiValidatorOptions('./openapi.yaml', {
    validateRequests: true,
    validateResponses: true,
    operationHandlers: './handlers',
  }),
});

Prefer to parse the spec once and share it? Load the .yml document manually and reuse it for routing, validation, and automatic operationHandlers.

import path from 'node:path';
import { readFileSync } from 'node:fs';
import { parse } from 'yaml';

const spec = parse(
  readFileSync(new URL('./openapi.yml', import.meta.url), 'utf-8'),
);

const app = await getApplication({
  apis: [usersApi],
  openApiValidator: createOpenApiValidatorOptions(spec, {
    operationHandlers: path.join(path.dirname(import.meta.url), './handlers'),
  }),
});

Highlights:

  • Enable/disable request or response validation, including per-field tweaks (coercion, unknown query params, removing additional fields, etc.).
  • Register custom security handlers with validateSecurity.handlers.
  • Serve the parsed spec via serveSpec, configure file upload limits, ignore health-check routes, or validate the spec itself.
  • Reuse $ref parsing, custom formats, and file upload middleware exactly as in the upstream validator.

Logging (optional)

Install the optional peer to enable HTTP request/response logging:

npm install pino-http
const app = await getApplication({
  pinoHttp: true, // defaults
  // or:
  pinoHttp: { autoLogging: false },
});

See the full options in the pino-http docs.

Firebase Auth (optional)

If you use Firebase Authentication, install the optional peer and plug it into OpenAPI security handlers:

npm install @my-f-startup/firebase-auth-express
import admin from 'firebase-admin';
import {
  createFirebaseAuthSecurityHandlers,
  createOpenApiValidatorOptions,
  getApplication,
} from '@emmett-community/emmett-expressjs-with-openapi';

admin.initializeApp();

const app = await getApplication({
  apis: [myApi],
  openApiValidator: createOpenApiValidatorOptions('./openapi.yaml', {
    validateSecurity: {
      handlers: createFirebaseAuthSecurityHandlers(),
    },
  }),
});

@my-f-startup/firebase-auth-express relies on firebase-admin. Make sure the Admin SDK is installed, initialized, and configured for your environment (credentials or emulator).

Observability

This package supports optional logging and tracing.

Logging

Inject a Pino-compatible logger:

import pino from 'pino';

const logger = pino();

const app = await getApplication({
  observability: { logger },
});

startAPI(app, { port: 3000, logger });

No logs are emitted when logger is not provided.

Logger Contract

This package defines the canonical Logger interface for the Emmett ecosystem. Implementations (Pino, Winston, etc.) MUST adapt to this contract.

interface Logger {
  debug(context: Record<string, unknown>, message?: string): void;
  info(context: Record<string, unknown>, message?: string): void;
  warn(context: Record<string, unknown>, message?: string): void;
  error(context: Record<string, unknown>, message?: string): void;
}

Semantic Rules:

  • context (first parameter): Structured data for the log entry
  • message (second parameter): Human-readable message
  • The order is never inverted

Pino implements this contract natively. For other loggers like Winston, you need to create an adapter.

Note: The adapter example below is for demonstration purposes only. It is NOT part of the public API and NOT an official recommendation. Users must implement their own adapters for non-Pino loggers.

import winston from 'winston';
import type { Logger } from '@emmett-community/emmett-expressjs-with-openapi';

const winstonLogger = winston.createLogger({ /* config */ });

const logger: Logger = {
  debug(context, message) {
    winstonLogger.debug(message ?? '', context);
  },
  info(context, message) {
    winstonLogger.info(message ?? '', context);
  },
  warn(context, message) {
    winstonLogger.warn(message ?? '', context);
  },
  error(context, message) {
    winstonLogger.error(message ?? '', context);
  },
};

Tracing

If your application initializes OpenTelemetry, this package will emit spans automatically. Tracing is passive - spans are no-ops when OpenTelemetry is not configured.

import { tracedOn, OK } from '@emmett-community/emmett-expressjs-with-openapi';

router.post('/carts', tracedOn(async (req) => {
  // Your handler logic
  return OK({ body: { success: true } });
}));

This package never initializes OpenTelemetry - configure your tracer provider in your application.

API Reference

Application

  • getApplication(options) - Creates and configures the Express app.
  • startAPI(app, options) - Starts the HTTP server.

OpenAPI

  • createOpenApiValidatorOptions(apiSpec, options) - Helper to assemble OpenAPI validator config.
  • isOpenApiValidatorAvailable() - Type guard for optional validator dependency.
  • createFirebaseAuthSecurityHandlers(options) - Firebase Auth security handlers.
  • registerHandlerModule(handlersPath, module) - Manual registration for operation handlers.

HTTP helpers

  • send, sendCreated, sendAccepted, sendProblem - Standard HTTP responses.

ETag helpers

  • toWeakETag, getETagFromIfMatch, getETagFromIfNotMatch, getETagValueFromIfMatch, setETag.

Testing helpers

  • ApiSpecification, ApiE2ESpecification
  • expect, expectNewEvents, expectResponse, expectError

See docs/openapi-validation.md for the full matrix of options and extended examples.

Testing

The package includes comprehensive test coverage:

  • Unit tests (test/unit/) - Utilities for ETag handling, error mapping
  • Integration tests (test/integration/) - Basic routing, OpenAPI validation, operation handlers, optimistic concurrency
  • E2E tests (test/e2e/) - End-to-end workflows for all features

Running tests

# Unit tests
npm run test:unit

# Integration tests
npm run test:int

# E2E tests
npm run test:e2e

# All tests
npm test

Examples

Working examples live under examples/:

  • examples/shopping-cart – feature-complete Emmett sample (business logic, memory store/publisher, security handlers, OpenAPI file, unit/int/e2e tests, .http scripts).
  • Legacy quick starts:
    • examples/basic – manual routes + validation (minimal scaffolding).
    • examples/with-security – standalone security handler demo.
    • examples/operation-handlers – barebones operationHandlers showcase.
    • examples/firebase-auth – Firebase Auth security handlers with operation handlers.

Documentation

Compatibility

  • Node.js: tested in CI with 24.x
  • Emmett: ^0.39.1
  • Express: ^4.19.2

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

Development

# Install dependencies
npm install

# Build
npm run build

# Type-check
npm run build:ts

# Run tests
npm test

# Run unit tests only
npm run test:unit

# Run integration tests
npm run test:int

# Run E2E tests
npm run test:e2e

License

MIT

Related Packages

Support


Made with ❤️ by the Emmett Community