Skip to main content

Zygos vs Neverthrow: Which Result Type for TypeScript?

Neverthrow popularized the Result pattern in TypeScript: a way to make errors explicit in function signatures instead of relying on try/catch. It's well-designed and widely adopted.

Zygos is a micro-implementation of the same pattern: 100% API compatible with Neverthrow, but 2.6x smaller. It also provides Option, Either, Task, and TaskEither monads for projects that need more than just Result. This page compares both libraries across the dimensions that matter in production.


At a Glance

AspectZygosNeverthrow
Result API100% compatible
ResultAsync API100% compatible
Bundle size~774 B (2.6x smaller)~1.96 kB
Type safetyZero any typesUses any in some places
Additional monadsOption, Either, Task, TaskEitherResult only
fp-ts bridgesYes (fromOption, fromEither, toEither)No
DependenciesZeroZero
Migration effortImport change only

Bundle Size

Zygos Result is 2.6x smaller (~774 B vs ~1.96 kB) than Neverthrow (gzipped). The difference comes from implementation approach: Zygos uses simple object literals ({ _tag: "Ok", value }) while Neverthrow uses class instantiation with more overhead.

For detailed per-module comparisons with auto-generated data, see the Zygos bundle size comparison.

// Zygos: Result + ResultAsync
import { ok, err, Result } from "pithos/zygos/result/result";
import { ResultAsync } from "pithos/zygos/result/result-async";

// Neverthrow: importing any function pulls the full library
import { ok, err, Result, ResultAsync } from "neverthrow";

Performance

Zygos is 2-4x faster on object creation and chained operations. Simple property checks (isOk, isErr, unwrapOr) perform identically in both libraries.

For detailed benchmark results with auto-generated data, see the Zygos performance benchmarks.

Key findings:

  • Object creation (ok(), err()): Zygos is 2-3x faster (object literals vs class instantiation)
  • Chained operations (andThen): Zygos is 2-4x faster
  • Simple checks (isOk, unwrapOr): equivalent, both are property access

100% API Compatibility

Zygos is a drop-in replacement. Every Result and ResultAsync method works identically:

// Just swap the import, zero code changes
import { ok, err, Result, safeTry } from "pithos/zygos/result/result";
import { ResultAsync, okAsync, errAsync } from "pithos/zygos/result/result-async";

// All Neverthrow patterns work as-is
const result = ok(5)
.map(x => x * 2)
.mapErr(e => `Error: ${e}`)
.andThen(x => x > 0 ? ok(x) : err("negative"));

const asyncResult = ResultAsync.fromPromise(
fetch("/api/data"),
() => "Network error"
);

const combined = Result.combine([ok(1), ok(2), ok(3)]); // Ok([1, 2, 3])

For the complete compatibility matrix, see the Zygos ↔ Neverthrow interoperability page.


What Zygos Adds Beyond Neverthrow

fp-ts Bridges

Convert between Result and fp-ts types without manual mapping:

import { fromOption, fromEither, toEither } from "pithos/zygos/result/result";

// Option → Result
const fromSome = fromOption(() => "No value")(someOption); // Ok(42)

// Either → Result
const fromRight = fromEither(rightEither); // Ok(42)

// Result → Either
const either = toEither(ok(42)); // { _tag: "Right", right: 42 }

Additional Monads

Zygos provides Option, Either, Task, and TaskEither, lightweight implementations compatible with fp-ts:

// Option: explicit absence (no null/undefined)
import { some, none, fromNullable } from "pithos/zygos/option";

// Either, Task, TaskEither: fp-ts compatible
import * as E from "pithos/zygos/either";
import * as T from "pithos/zygos/task";
import * as TE from "pithos/zygos/task-either";

Zero any Types

Neverthrow uses any in some internal types. Zygos uses unknown throughout, providing stricter type safety and catching more errors at compile time.

safeAsyncTry

Simplified async error handling without generators:

import { safeAsyncTry } from "pithos/zygos/result/result";

const result = await safeAsyncTry(() => fetch("/api/users/123").then(r => r.json()));

Migration Guide

Ready to migrate? The complete step-by-step migration guide is in the Zygos module documentation: install, swap imports, and start using additional features. Go to migration guide →

Not sure which library fits your use case? See the comparison overview.


Further Reading