neverthrow
TypeScript library implementing the Result type pattern from Rust/ML languages. Instead of throwing exceptions, functions return Result<T, E> which is either Ok(value) or Err(error) — forcing callers to explicitly handle both success and failure. Provides a lightweight (< 5KB) alternative to Effect for typed error handling. Includes ResultAsync for Promise-based code. Eliminates try/catch and makes error types visible in function signatures.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Local library — no network access. Zero dependencies. MIT licensed. <5KB bundle impact.
⚡ Reliability
Best When
You want typed error handling in TypeScript without the full complexity of Effect — a minimal Result type that makes all error cases explicit.
Avoid When
You need advanced features like structured concurrency, dependency injection, or streams — use Effect instead.
Use Cases
- • Replace try/catch error handling with typed Results in TypeScript to make all failure cases explicit in function signatures
- • Build agent tool functions that return Result<ToolOutput, ToolError> forcing agents to handle failures explicitly rather than catching untyped exceptions
- • Create railway-oriented programming pipelines using andThen/mapErr for chaining operations that can fail at any step
- • Convert Promise-based async operations to ResultAsync for typed async error handling without try/catch
- • Document all possible failure modes of a function in its return type — making the function's error contract visible to callers
Not For
- • Applications requiring comprehensive error recovery, retry logic, and dependency injection — use Effect for full functional programming
- • Teams without TypeScript — neverthrow's value is entirely in TypeScript's type system
- • Simple scripts where try/catch is adequate — neverthrow adds ceremony for simple operations
Interface
Authentication
Local library — no authentication.
Pricing
neverthrow is MIT open source. Free for personal and commercial use.
Agent Metadata
Known Gotchas
- ⚠ Calling .value on an Err result throws at runtime — always call .isOk() or match() before accessing .value; TypeScript types help prevent this but unannotated code can bypass checks
- ⚠ ResultAsync wraps Promise<Result<T,E>> — forgetting to await ResultAsync before chaining leads to type errors about Promise not having .andThen method
- ⚠ combining/collecting multiple Results uses combine() or combineWithAllErrors() — forgetting these helpers leads to verbose manual Result unwrapping in array operations
- ⚠ neverthrow does NOT automatically catch thrown exceptions — if a function inside .andThen throws, it propagates as an exception, not as an Err; use ResultAsync.fromPromise() to safely wrap throwing code
- ⚠ The .match() method is recommended for handling both cases — using if/else with .isOk() works but TypeScript's narrowing doesn't refine the error type as cleanly
- ⚠ Interop with APIs that throw (most Node.js and browser APIs) requires wrapping in Result.fromThrowable() or ResultAsync.fromPromise() — not all third-party code can be cleanly wrapped
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for neverthrow.
Scores are editorial opinions as of 2026-03-06.