Skip to content

Avinashvelu03/guarden

Repository files navigation

πŸ›‘οΈ Guarden

TypeScript-First Runtime Safety Toolkit

npm version license tests coverage TypeScript zero deps

Guard your runtime. Harden your types.

Blazing-fast, tree-shakeable utilities for bridging TypeScript’s compile-time safety with real-world runtime guarantees. Type guards, assertions, Result/Option monads, data pipelines, and environment validation β€” all in one lightweight, zero-dependency package.

Getting Started Β· API Reference Β· Why Guarden? Β· Contributing


✨ Highlights

  • πŸ”’ 60+ type guards with automatic TypeScript narrowing
  • ⚑ Zero dependencies β€” nothing to audit, nothing to break
  • 🌳 Tree-shakeable β€” import only what you use
  • πŸ“¦ Dual ESM/CJS β€” works everywhere
  • πŸ§ͺ 313 tests with 100% coverage (statements, branches, functions, lines)
  • 🎯 TypeScript-first β€” written in TypeScript, for TypeScript
  • πŸ—οΈ 5 modules β€” Guards, Assert, Result/Option, Transform, Env

πŸ“¦ Getting Started

Installation

npm install guarden
yarn add guarden
pnpm add guarden

Quick Example

import {
  isString, isNumber, shape,    // Guards
  assert, invariant,             // Assertions
  Ok, Err, type Result,          // Result monad
  pipe, slugify, escapeHtml,     // Transform
  createEnv, envString, envNumber // Env validation
} from 'guarden';

// πŸ›‘οΈ Type Guards β€” automatic narrowing
const input: unknown = getApiResponse();
if (isString(input)) {
  input.toUpperCase(); // βœ… TypeScript knows it's a string
}

// πŸ—οΈ Object Shape Validation
const isUser = shape({ name: isString, age: isNumber });
if (isUser(data)) {
  console.log(data.name); // βœ… Fully typed
}

// ⚑ Result Monad β€” no more try/catch
function divide(a: number, b: number): Result<number, string> {
  if (b === 0) return Err('Division by zero');
  return Ok(a / b);
}

divide(10, 2).match({
  ok: (value) => console.log(`Result: ${value}`),
  err: (error) => console.error(`Error: ${error}`),
});

// πŸ”„ Data Pipelines
const slug = pipe('  Hello, World! 🌍  ', (s) => s.trim(), slugify);
// β†’ "hello-world"

πŸ”Œ Modular Imports

import { isString, shape, arrayOf } from 'guarden/guards';
import { assert, invariant } from 'guarden/assert';
import { Ok, Err, Some, None } from 'guarden/result';
import { pipe, slugify, escapeHtml } from 'guarden/transform';
import { createEnv, envString } from 'guarden/env';

πŸ“– API Reference

πŸ›‘οΈ Guards

// Primitives
isString(v) | isNumber(v) | isBoolean(v) | isNull(v) | isUndefined(v)
isNullish(v) | isNonNullish(v) | isFunction(v) | isPrimitive(v)

// Structures
isArray(v) | isObject(v) | isPlainObject(v) | isDate(v) | isValidDate(v)
isMap(v) | isSet(v) | isRegExp(v) | isError(v) | isPromise(v)

// Advanced
isEmail(v) | isURL(v) | isUUID(v) | isISO8601(v) | isHexColor(v)
isPositiveNumber(v) | isInteger(v) | isNonEmptyArray(v)

// Factories
isInRange(0, 100)(v) | isOneOf(['a','b'] as const)(v)
isMinLength(3)(v) | isInstanceOf(TypeError)(v)

// Combinators
const guard = and(isInteger, isPositiveNumber);
const isUser = shape({ name: isString, age: isNumber });
const isStringArray = arrayOf(isString);

βœ… Assert

assert(condition, 'msg');
assertDefined(value);       // narrows away undefined
assertNonNull(value);       // narrows away null | undefined
assertType(value, isString);
invariant(items.length > 0, 'bug!');
unreachable(dir);           // exhaustive switch checking

🎯 Result & Option

const result = Ok(42);
result.map(v => v * 2);
result.unwrapOr(0);
result.match({ ok: v => v, err: e => e });

const parsed = ResultUtils.from(() => JSON.parse(input));
const data = await ResultAsync.from(fetch('/api')).map(r => r.json()).unwrapOr(null);

const all = ResultUtils.all([Ok(1), Ok(2)]); // Ok([1, 2])

πŸ”„ Transform

pipe('  Hello World  ', trim, lowercase, slugify); // "hello-world"
const processTitle = flow(trim, capitalize, (s) => truncate(s, 50));

toNumber('42')           // Ok(42)
escapeHtml('<script>')   // "&lt;script&gt;"
camelCase('hello world') // "helloWorld"
slugify('Hello! 🌍')    // "hello"

🌍 Env

export const env = createEnv({
  DATABASE_URL: envString().url().required(),
  PORT: envNumber().port().default(3000),
  DEBUG: envBoolean().default(false),
  NODE_ENV: envEnum(['development', 'production', 'test'] as const),
});

env.DATABASE_URL  // string
env.PORT          // number
env.DEBUG         // boolean

πŸ€” Why Guarden?

Feature Guarden Zod neverthrow ts-pattern
Type Guards βœ… 60+ ❌ ❌ ❌
Assertions βœ… ❌ ❌ ❌
Result/Option βœ… ❌ βœ… ❌
Data Transform βœ… βœ… (parse) ❌ ❌
Env Validation βœ… πŸ”Ά (manual) ❌ ❌
Zero Dependencies βœ… βœ… βœ… βœ…
Bundle Size ~3KB ~14KB ~5KB ~3KB

πŸ”§ Requirements

  • Node.js >= 18.0.0
  • TypeScript >= 5.0

πŸ“„ License

MIT Β© Avinashvelu03


Guard the Dev β€” Support Guarden

  β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“
  β–“  β–„β–„β–„     β–„β–„β–„  β–„β–„β–„ β–„   β–„ β–„β–„β–„β–„β–„  β–„β–„β–„β–„  β–„β–„β–„  β–“
  β–“ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–“
  β–“ β–ˆβ–ˆβ–ˆ     β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ    β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–“
  β–“ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ    β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–“
  β–“ β–ˆβ–ˆβ–ˆ     β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ    β–ˆβ–ˆβ–ˆ    β–ˆβ–ˆβ–ˆ β–“
  β–“ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ    β–ˆβ–ˆβ–ˆ β–“
  β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“

Guarden guards your runtime for free. A star, a sponsor, or a share keeps it alive and growing.

Ko-fi GitHub Sponsors

Free ways to support:

Built with ❀️ by Avinash Velu

About

πŸ›‘οΈ Blazing-fast, zero-dependency TypeScript runtime safety toolkit. 60+ type guards with auto-narrowing, Result/Option monads, assertions, invariants, data pipelines (pipe/flow), string sanitization, and env validation. Tree-shakeable. Dual ESM/CJS. 313 tests. 100% coverage. Guard your runtime, harden your types.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors