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

stderr-lib

v2.1.0

Published

Normalize unknown error values to a standard format with cause chain support.

Readme

stderr-lib

Type-safe, standardized error handling for TypeScript/JavaScript

npm version License: MIT

Clean, opinionated error handling with explicit Result pattern and structured error normalization.


Overview

stderr-lib gives you two focused tools:

  1. stderr() – normalize any error-like value into a standard StdError
  2. tryCatch() – wrap sync/async code in a type-safe Result union

Use it when you want:

  • Consistent, serializable errors (including cause chains and nested errors)
  • Explicit, type-checked error handling instead of ad-hoc try/catch
  • Built‑in defenses against runaway structures (max depth, properties, array length)

Advanced patterns (timeouts, limit tuning, security, performance, testing) live in docs/BestPractices.md.


Installation

npm install stderr-lib
pnpm add stderr-lib
yarn add stderr-lib

Quick Start

Normalize Any Error for Logging

import { stderr } from 'stderr-lib';

try {
    await riskyOperation();
} catch (error: unknown) {
    const err = stderr(error);

    console.log(err.toString());
    // Includes message, stack (if present), cause chain, custom properties, everything!

    logger.error('Operation failed', err); // Works with typical loggers
}

Type-Safe Error Handling with Result Pattern

import { tryCatch, type Result } from 'stderr-lib';

interface UserDto {
    id: string;
    name: string;
}

// You can pass an async function - type is inferred as Promise<Result<UserDto>>
const result = await tryCatch<UserDto>(async () => {
    const response = await fetch('/api/user/123');
    if (!response.ok) {
        throw new Error(`Request failed - ${response.status}`); // will be converted to StdError
    }
    return response.json() as Promise<UserDto>;
});

if (!result.ok) {
    // You are forced to handle the error explicitly
    console.error('Request failed:', result.error.toString());
    return null;
}

// In the success branch, value is non-null and correctly typed as UserDto
console.log('User name:', result.value.name);

Core API (Surface)

stderr(input, options?)

Normalize any value into a StdError instance.

stderr(input: unknown, options?: NormalizeOptions): StdError;

Key points:

  • Accepts anything: native Error, strings, objects, null/undefined, arrays, third‑party errors
  • Preserves:
    • name, message, stack (if present)
    • cause, errors (AggregateError / validation errors)
    • Custom properties (e.g., code, statusCode, metadata)
  • Adds safe defaults to avoid DoS:
    • maxDepth (default 8, range 1–1000)
    • maxProperties (default 1000, range 1–100000)
    • maxArrayLength (default 10000, range 1–1000000)

See Best Practices – Normalization & Limits for detailed guidance and examples.

StdError

All stderr() results are instances of StdError.

Important properties (non‑exhaustive):

  • name?: string
  • message?: string
  • stack?: string
  • cause?: unknown
  • errors?: unknown (arrays or maps of nested errors)
  • [key: string]: unknown – arbitrary extra metadata

Important methods:

  • toString(): string – human‑readable, multi‑line representation with cause chain and nested errors
  • toJSON(): object – JSON‑safe representation suitable for logging systems and transports

Deep dives:

tryCatch(fn, mapError?)

Wrap a function, async function, or Promise and always get a Result instead of thrown exceptions.

// Sync function -> Result
tryCatch<T>(fn: () => T): Result<T, StdError>;

// Async function or Promise -> Promise<Result>
tryCatch<T>(fn: Promise<T> | (() => Promise<T>)): Promise<Result<T, StdError>>;

// Sync function with custom error -> Result
tryCatch<T, E>(fn: () => T, mapError: (err: StdError) => E): Result<T, E>;

// Async function or Promise with custom error -> Promise<Result>
tryCatch<T, E>(fn: Promise<T> | (() => Promise<T>), mapError: (err: StdError) => E): Promise<Result<T, E>>;

Key features:

  • Accepts Promises directly: Pass fetch(url) or () => fetch(url) – both work
  • Automatic sync/async detection: Returns Result<T> for sync, Promise<Result<T>> for async
  • Optional error transformation: Use mapError to convert StdError to your custom error type

Result<T, E> is:

type Result<T, E = StdError> = { ok: true; value: T; error: null } | { ok: false; value: null; error: E };

This forces you to handle both branches explicitly in TypeScript.

More patterns:


Global Configuration (Limits)

You can tune normalization limits globally via properties on stderr:

import { stderr } from 'stderr-lib';

stderr.maxDepth = 10; // Default: 8, range: 1–1000
stderr.maxProperties = 500; // Default: 1000, range: 1–100000
stderr.maxArrayLength = 5000; // Default: 10000, range: 1–1000000

Invalid values throw TypeError/RangeError instead of silently misconfiguring:

stderr.maxDepth = 0; // RangeError
stderr.maxDepth = 3.5; // TypeError
stderr.maxProperties = 200000; // RangeError
stderr.maxArrayLength = 2000000; // RangeError

For environment‑specific tuning, see Best Practices – Security & DoS Protection and Performance Tips.


When to Use stderr-lib

A Good Fit

  • Web apps (frontend and backend)
  • Node.js services and APIs
  • Business, financial, or e‑commerce systems
  • Logging / monitoring / error‑reporting services
  • Codebases that prefer explicit Result‑style error handling

Not a Good Fit

  • Hard real‑time or safety‑critical systems (avionics, life‑critical medical devices, automotive safety, etc.)
  • Environments that require certified runtimes or deterministic timing

(These environments generally should not use JavaScript/TypeScript at all.)


Further Reading

  • BestPractices.md – deep dive:
    • Promise handling patterns and timeouts
    • Exception usage, mutation, and error immutability
    • Security/sanitization and DoS protections
    • Performance tuning and environment‑specific limits
    • Testing strategies and property‑based tests
    • Custom error classes vs StdError, common patterns, and anti‑patterns
  • ADR.md – architectural decisions
  • TypeScript Coding Standard – broader Result‑pattern guidance

Contributing

Contributions are welcome. Please:

  1. Follow existing code style and patterns
  2. Add tests for new behavior
  3. Update documentation where relevant
  4. Run linting and tests before submitting (see package.json scripts)

License

MIT © Michael L. Hobbs