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 🙏

© 2025 – Pkg Stats / Ryan Hefner

try-results

v0.0.6

Published

A minimal, functional, and tree-shakable Result library for TypeScript that prioritizes simplicity and serialization

Readme

try-results is a minimal, functional, and tree-shakable Result library for TypeScript that prioritizes simplicity and serialization.

  • 🔮 Simple, declarative API: Intuitive array destructuring with full type safety
  • 🍃 Lightweight & Tree Shakable: Function-based design with zero dependencies
  • ⚡ High Performance: Minimal overhead with just a 3-element array
  • 🔍 Easy Serialization: Simple array format perfect for wire transmission
  • 📦 Zero Dependencies: Standalone library ensuring ease of use in various environments
  • 🔧 Functional Helpers: Powerful map, unwrap, and utility functions
  • 🧵 Type Safe: Full TypeScript support with literal types and type guards

🌟 Motivation

Build a minimal, functional Result library that prioritizes simplicity and serialization. While libraries like ts-results and neverthrow offer robust features, they often come with bloated class hierarchies that can't be easily serialized. try-results provides a simpler alternative - combining minimal overhead, easy serialization for APIs and frameworks like React Router, and functional helpers while adhering to the KISS principle.

Key Features:

  • Minimal Core: Just a 3-element array [boolean, E, T] with methods
  • Easy Serialization: Perfect for APIs, Remix loaders, and network requests
  • Array Destructuring: Intuitive [ok, error, value] pattern
  • Tree Shakable: Import only what you need

⚖️ Alternatives

📖 Usage

try-results provides a simple approach to error handling. Here's how to use it:

1. Creating Results

import { Ok, Err } from 'try-results';

const success = Ok(42);
const failure = Err('Something went wrong');

2. Working with Results

// Method-based approach
if (success.isOk()) {
	console.log(success.value); // 42
}

// Array destructuring approach
const [ok, error, value] = success;
if (ok) {
	console.log(value); // 42
}

// Direct unwrapping (throws on error)
const value = success.unwrap(); // 42

3. Safe Value Extraction

import { unwrapOr, unwrapErr } from 'try-results';

// Provide defaults
const value = unwrapOr(failure, 0); // 0

// Extract errors safely
const error = unwrapErr(failure); // 'Something went wrong'

4. Transforming Results

import { mapOk, mapErr } from 'try-results';

// Transform success values
const doubled = mapOk(success, x => x * 2); // Ok(84)

// Transform errors
const wrapped = mapErr(failure, e => `Error: ${e}`); // Err('Error: Something went wrong')

5. Wrapping Functions

import { t, tAsync } from 'try-results';

// Wrap synchronous functions
const result = t(() => JSON.parse('invalid')); // Err(SyntaxError)

// Wrap promises
const asyncResult = await tAsync(fetch('/api/data')); // Ok(Response) or Err(Error)

6. Serialization

import { serialize, deserialize } from 'try-results';

// Convert to wire format
const wireFormat = serialize(success); // [true, 42]

// Reconstruct from wire format
const reconstructed = deserialize(wireFormat); // Back to TResult

📚 API Reference

Core Functions

Ok<T, E>(value: T): OkResult<T, E>

Creates a successful result containing the given value.

const result = Ok(42);
console.log(result.unwrap()); // 42
console.log(result.isOk());   // true

Err<T, E>(error: E): ErrResult<T, E>

Creates an error result containing the given error.

const result = Err('Something went wrong');
console.log(result.isErr());  // true
console.log(result.error);    // 'Something went wrong'

Type Guards

isOk<T, E>(result: TResult<T, E>): result is OkResult<T, E>

Type guard to check if a result is successful.

if (isOk(result)) {
	// TypeScript knows result is OkResult here
	console.log(result.unwrap());
}

isErr<T, E>(result: TResult<T, E>): result is ErrResult<T, E>

Type guard to check if a result is an error.

if (isErr(result)) {
	// TypeScript knows result is ErrResult here
	console.log(result.error);
}

Unwrapping Functions

unwrap<T, E>(result: TResult<T, E>): T

Extracts the value from a result, throwing if it's an error.

try {
	const value = unwrap(success); // 42
} catch (error) {
	// Handle error
}

unwrapOk<T, E>(result: TResult<T, E>): T

Extracts the value from an Ok result, throwing if it's an error.

const value = unwrapOk(success); // 42

unwrapErr<T, E>(result: TResult<T, E>): E

Extracts the error from an Err result, throwing if it's successful.

const error = unwrapErr(failure); // 'Something went wrong'

unwrapOr<T, E>(result: TResult<T, E>, defaultValue: T): T

Extracts the value from a result, returning a default if it's an error.

const value = unwrapOr(failure, 0); // 0

unwrapOrNull<T, E>(result: TResult<T, E>): T | null

Extracts the value from a result, returning null if it's an error.

const value = unwrapOrNull(failure); // null

Transformation Functions

mapOk<T, E, U>(result: TResult<T, E>, mapFn: (value: T) => U): TResult<U, E>

Maps the value inside an Ok result using the provided function.

const doubled = mapOk(Ok(21), x => x * 2); // Ok(42)

mapErr<T, E, F>(result: TResult<T, E>, mapFn: (error: E) => F): TResult<T, F>

Maps the error inside an Err result using the provided function.

const wrapped = mapErr(Err(404), code => `HTTP ${code}`); // Err('HTTP 404')

Function Wrappers

t<T, Args extends any[]>(fn: (...args: Args) => T, ...args: Args): TResult<T, unknown>

Wraps a synchronous function call in a Result.

const result = t(() => JSON.parse('invalid')); // Err(SyntaxError)
const safeDivide = (a: number, b: number) => t(() => a / b, a, b);

tAsync<T>(promise: Promise<T>): Promise<TResult<T, unknown>>

Wraps a Promise in a Result.

const result = await tAsync(fetch('/api/data')); // Ok(Response) or Err(Error)

Serialization Functions

serialize<T, E>(result: TResult<T, E>): [boolean, T | E]

Converts a result to a wire-friendly format.

const wireFormat = serialize(Ok(42)); // [true, 42]

deserialize<T, E>(serialized: [boolean, T | E]): TResult<T, E>

Converts a serialized result back to a TResult.

const result = deserialize([true, 42]); // Ok(42)

💡 Resources / References