DEV Community

Avinash
Avinash

Posted on

guarden: Zero-Dependency TypeScript Runtime Safety (Type Guards, Result/Option Monads)

The Problem with TypeScript Runtime Safety

TypeScript gives you compile-time type checking, but at runtime you have zero protection. API responses come back as unknown, JSON.parse() returns any, and one wrong assumption crashes production.

const data = JSON.parse(rawInput); // any - no safety
const user = data.user; // could be anything
user.name.toUpperCase(); // TypeError: Cannot read property 'toUpperCase' of undefined
Enter fullscreen mode Exit fullscreen mode

Introducing guarden

guarden is a zero-dependency TypeScript-first runtime safety toolkit that closes the gap between compile-time and runtime type safety.

Key Features

1. 60+ Type Guards with Auto-Narrowing

import { isString, isValidEmail, isUUID, isNonEmptyArray, isISO8601Date } from 'guarden';

if (isString(value)) {
  // TypeScript narrows: value is string here
  console.log(value.toUpperCase()); // safe!
}

const emails = data.filter(isValidEmail);
// TypeScript infers: emails is string[]
Enter fullscreen mode Exit fullscreen mode

2. Result and Option Monads

No more try/catch spaghetti. Handle errors as values:

import { Result, Option } from 'guarden';

const result = Result.try(() => JSON.parse(rawInput));

result
  .map(data => data.users)
  .filter(isNonEmptyArray)
  .match({
    ok: (users) => renderUsers(users),
    err: (error) => showError(error.message),
  });
Enter fullscreen mode Exit fullscreen mode

3. Composable Pipelines

import { pipe } from 'guarden';

const processUser = pipe(
  (input: unknown) => Result.try(() => JSON.parse(input as string)),
  (r) => r.map(d => d.user),
  (r) => r.flatMap(u => isString(u.name) ? Result.ok(u) : Result.err('Invalid user'))
);
Enter fullscreen mode Exit fullscreen mode

4. Assertions and Invariants

import { assert, invariant } from 'guarden';

assert(isString(name), 'Name must be a string');
invariant(age >= 0 && age <= 150, `Invalid age: ${age}`);
Enter fullscreen mode Exit fullscreen mode

Stats

  • 313 tests, 100% coverage
  • Zero dependencies
  • Tree-shakeable (only import what you use)
  • Dual ESM/CJS build
  • Node.js, Bun, Deno, Cloudflare Workers

Installation

npm install guarden
bun add guarden
Enter fullscreen mode Exit fullscreen mode

Check out the full docs on GitHub: https://github.com/Avinashvelu03/guarden

Would love your feedback especially on the monad API design!

Top comments (0)