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

try

v1.0.3

Published

A 373-byte Spec-Compliant Runtime-Only Implementation of the ECMAScript Try Operator Proposal Result class

Readme

A 373-byte spec-compliant runtime-only implementation of the Result class from the ECMAScript Try Operator proposal.

import { t } from 'try';

const [ok, error, value] = t(() => JSON.parse('{"foo": "bar"}'));
const [ok, error, value] = await t(axios.get('https://arthur.place'));

This package is a minimal and precise reference implementation of the Result class as described in the Try Operator proposal for JavaScript.

It aims to provide a lightweight and fast runtime utility that reflects exactly how the proposed try operator would behave, and will not evolve independently of the proposal.

If you'd like to suggest changes or improvements to the behavior or API, please open an issue on the proposal repository. Once discussed and approved there, changes will be reflected in this package.

import { Result, ok, error, t } from 'try';

// Synchronous function call
const [ok1, err1, val1] = t(JSON.parse, '{"foo":"bar"}');

// Arrow function context
const [ok2, err2, val2] = t(() => decoder.decode(buffer));

// Promise call
const [ok3, err3, val3] = await t(fetch, 'https://api.example.com');

// Promise-safe call (safely catches both sync and async errors)
const [ok4, err4, val4] = await t(() => readFile('./config.json'));

// Argument passthrough
const [ok5, err5, val5] = t((a, b) => a + b, 2, 3);

// Keep full result object for readability
const result = await t(fetch, 'https://arthur.place');
if (result.ok) console.log(await result.value.text());

// Manual success and error results
const success = ok(42);
const failure = error(new Error('nope'));

// Manual Result creation via class
const successObj = Result.ok('done');
const failureObj = Result.error('fail');

Why This Exists

JavaScript error handling can be verbose and inconsistent. The Try Operator proposal introduces a new pattern that returns structured Result objects instead of throwing exceptions, simplifying async and sync error flows alike.

While the proposal is still in the works, this package provides a way to experiment with the new pattern in a standardized way.

This package provides a drop-in utility: Result.try() (or the shorter t()) to wrap expressions and handle errors in a clean, tuple-like form.

const [ok, error, value] = t(JSON.parse, '{"foo":"bar"}');

if (ok) {
  console.log(value.foo);
} else {
  console.error('Invalid JSON', error);
}

You can destructure the result into [ok, error, value], or access .ok, .error, and .value directly depending on your use case.

Usage

All methods are documented via TSDoc, so your editor will guide you with full type support and autocomplete.

Wrapping a Function Call

Use Result.try() or t() to wrap a potentially failing operation:

const [ok, error, value] = Result.try(() => JSON.parse(request.body));

if (ok) {
  console.log(`Hello ${value.name}`);
} else {
  console.error(`Invalid JSON!`);
}

[!NOTE]
Result.try(() => fn()) is verbose compared to the proposal's future try fn() syntax. Always prefer to use the t() alias for cleaner code.

t() alias

To make code cleaner and more ergonomic while we wait for language-level syntax sugar, this package also exports t, a shortcut for Result.try.

import { readFile } from 'node:fs/promises';
import { readFileSync } from 'node:fs';

// Example (this is void)
const [ok, error, value] = t(readFileSync, './config.json');
// If `this` matters in your context
const [ok, error, value] = t(() => decoder.decode(request.body));
// Promises don't need wrapping
const [ok, error, value] = await t(axios.get('http://example.com'));
// Safer way even for promises (catches sync errors before returning a promise)
const [ok, error, value] = await t(readFile, path);

The t(fn, ...args) form is ideal: it automatically passes arguments to your function, preserves full TypeScript inference, and keeps code short and readable.

function divide(a: number, b: number) {
  return a / b;
}

const [ok, error, value] = t(divide, 10, 2);
// ok: true, value: 5

Prefer Using the Result Object in Multi-Try Scenarios

While destructuring works well for simple use cases, it can lead to awkward variable naming and clutter when handling multiple try results. In these cases, it's recommended to keep the full result object and access .ok, .error, and .value directly for better clarity and readability.

❌ Bad (managing variable names becomes cumbersome):

// error handling omitted for brevity
const [ok1, error1, value1] = Result.try(() => axios.get(...));
const [ok2, error2, value2] = Result.try(() => value1.data.property);

✅ Better (clearer structure and easier to follow):

// error handling omitted for brevity
const response = await Result.try(fetch('https://arthur.place'));
const data = await Result.try(() => response.value.text()));

Using the result object directly avoids unnecessary boilerplate and naming inconsistencies, especially in nested or sequential operations. It's a cleaner, more scalable pattern that mirrors real-world error handling flows.

Works With Promises Too!

You can pass a Promise directly and get a Result-wrapped version:

const [ok, error, value] = await t(
  fs.promises.readFile('./config.json')
);

if (ok) {
  const config = JSON.parse(value.toString());
} else {
  console.error('Failed to read file', error);
}

The return value of t() is automatically await-able if the function returns a promise, no extra handling required.

No Result.bind

This implementation will never provide a Result.bind() (like util.promisify) because the Try Operator follows the Caller’s Approach model.

That means error handling belongs to the calling context, not the function itself. Wrapping a function with bind() would push error encapsulation into the callee, breaking that principle.

In short: the caller chooses to wrap a function call in Result.try, not the function author.

Creating Results Manually

You can also create Result objects directly:

import { Result, ok, error } from 'try';

// With full Result class
const res1 = Result.ok('done');
const res2 = Result.error('fail');

// Shorthand
const okRes = ok(42);
const errRes = error('oops');

This is useful when bridging non-try-based code or mocking results.

Learn More

To learn about the underlying proposal, including syntax goals and motivation, visit:

🔗 https://github.com/arthurfiorette/proposal-try-operator

Acknowledgements

Many thanks to Szymon Wygnański for transferring the try package name on NPM to this project. Versions below 1.0.0 served a different purpose, but with his permission, the project was repurposed to host an implementation of the proposal’s Result class.

License

Both the project and the proposal are licensed under the MIT license.