Introducing Flip: A TypeScript library that makes error handling less painful

11/17/2025

By Reach Team

Introducing Flip: A TypeScript library that makes error handling less painful

TL;DR

No more try catch hell: Introducing Flip

Flip

Because nobody likes try-catch blocks that look like a pyramid scheme. Instead of throwing tantrums (I mean exceptions), functions return a Flip.R<T, E> that's either "Yay, it worked!" or "Oops, something went sideways."

Give it a star โค๏ธ :

https://github.com/Reach-Design/flip

Installation

npm install @reachdesign/flip

Usage

import { Flip } from '@reachdesign/flip';

function countSlices(pizzas: number): Flip.R<number, string> {
  if (pizzas === 0) return Flip.err("No pizza, no life! ๐Ÿ˜ญ");
  return Flip.ok(pizzas * 8);
}

const result = countSlices(0);
console.log(Flip.isErr(result) ? Flip.e(result) : Flip.v(result));
// "No pizza, no life! ๐Ÿ˜ญ"

Cat Mood ๐Ÿ˜ธ

function checkCat(treats: number): Flip.R<boolean, string> {
  if (treats < 3) return Flip.err("Cat is plotting revenge ๐Ÿ˜พ");
  return Flip.ok(true);
}

const result = checkCat(2);
console.log(Flip.isOk(result) ? "Happy cat!" : Flip.e(result));
// "Cat is plotting revenge ๐Ÿ˜พ"

Async Coffee โ˜•

async function brewCoffee(beans: number): Promise<Flip.R<string, Error>> {
  if (beans === 0) return Flip.err(new Error("Zombie mode ON ๐ŸงŸโ€โ™‚๏ธ"));
  return Flip.ok("โ˜• Ready!");
}

const result = await brewCoffee(0);
console.log(Flip.isOk(result) ? Flip.v(result) : Flip.e(result).message);
// "Zombie mode ON ๐ŸงŸโ€โ™‚๏ธ"

API Reference

Types

  • Flip.R<T, E>: A result type that's either { ok: true, value: T } (success) or { ok: false, error: E } (error)

Functions

  • Flip.ok<T>(value: T): Creates a successful result (like finding money in your old jeans)
  • Flip.err<E>(error: E): Creates an error result (like realizing it was just a receipt)
  • Flip.v<T, E>(result: Flip.R<T, E>): Extracts the value from success (throws if error - handle with care!)
  • Flip.e<T, E>(result: Flip.R<T, E>): Extracts the error from failure (throws if success - also handle with care!)
  • Flip.isOk<T, E>(result: Flip.R<T, E>): Checks if result is successful (type-safe way to check)
  • Flip.isErr<T, E>(result: Flip.R<T, E>): Checks if result is an error (for when things go sideways)
  • Flip.isOk<T, E>(result: Promise<Flip.R<T, E>>): Async version for promise results
  • Flip.isErr<T, E>(result: Promise<Flip.R<T, E>>): Async version for promise results

Benefits

  • ๐Ÿšซ No more exceptions: Handle errors like a responsible adult
  • ๐Ÿ”’ Type-safe: TypeScript will hold your hand and guide you
  • ๐ŸŽฏ Explicit: No surprises, no hidden exceptions jumping out
  • ๐Ÿ“ฆ Lightweight: Smaller than your morning coffee
  • ๐Ÿงช Testable: Testing error scenarios is now fun (or at least bearable)

Why "Flip"?

Because sometimes your code works, sometimes it doesn't - it's like flipping a coin, but now you can handle both outcomes gracefully! ๐Ÿช™

License

MIT - Use it, abuse it, just don't blame us if your cat still gives you the death stare.

Contributing

Found a bug? Have a funny example? PRs welcome! Just remember: with great power comes great responsibility to write good error messages.