Skip to content
zrosenbauerPublic

About

Functional programming utilities for TypeScript. Result types, pattern matching, async pipelines.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

44 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

massaman

Functional programming utilities for TypeScript. Result types, pattern matching, async pipelines. Fully typed.

CI Security npm version License

Features

  • Rust's match in TypeScript: exhaustive pattern matching via re-exported ts-pattern.
  • Rust's Result in TypeScript: compose fallible operations without throws (attempt, attemptAsync, ok, err, isOk, unwrap).
  • Functional programming, fully typed: flow, flowAsync, tap, when, ifElse, and point-free combinators with end-to-end inference.
  • The missing pieces around es-toolkit: variadic-narrowing predicates, async composition, and consistent error normalization alongside its array, object, string, and math utilities.
  • Tree-shakeable: focused subpath exports, ESM-only, sideEffects: false. Import only what you use.

Install

npm install massaman

Usage

From ts-pattern

The match subpath re-exports ts-pattern and adds P.ok and P.err for Massaman results.

import { match, P } from 'massaman/match'

const status = match(action)
  .with({ type: 'load' }, () => 'loading')
  .with({ type: 'success' }, () => 'done')
  .with({ type: 'error', msg: P.string }, ({ msg }) => `failed: ${msg}`)
  .exhaustive()

From es-toolkit

Most of the surface (array, object, string, function, math) is a transparent re-export of es-toolkit. Same names, same behavior, same docs.

import { chunk, groupBy } from 'massaman'

chunk([1, 2, 3, 4, 5], 2)
// [[1, 2], [3, 4], [5]]

groupBy(['apple', 'avocado', 'banana', 'blueberry'], (s) => s[0])
// { a: ['apple', 'avocado'], b: ['banana', 'blueberry'] }

Custom: Result and async composition

Built on top of those re-exports, massaman/control adds Result-style error handling that never throws across a boundary.

import { attemptAsync, isOk } from 'massaman/control'

const result = await attemptAsync(() => fetch('/api/user').then((r) => r.json()))

if (isOk(result)) {
  console.log(result.value)
} else {
  console.error(result.error.message)
}

Why Massaman?

Currying is a core functional programming technique, and its name makes curry-the-food jokes inevitable. Massaman is a delicious Thai curry known for its rich blend of spices. This library continues the pun with its own rich blend of functional patterns.

Two Rust patterns I keep wanting in TypeScript: match for exhaustive branching, and Result for errors that compose without throws.

In Rust:

match action {
    Action::Load => "loading",
    Action::Success => "done",
    Action::Error(msg) => &format!("failed: {}", msg),
}

let parsed: Result<User, Error> = serde_json::from_str(raw);
match parsed {
    Ok(user) => println!("got: {}", user.name),
    Err(err) => eprintln!("failed: {}", err),
}

The equivalent in TypeScript using massaman:

import { match, P } from 'massaman/match'
import { attempt, isOk } from 'massaman/control'

match(action)
  .with({ type: 'load' }, () => 'loading')
  .with({ type: 'success' }, () => 'done')
  .with({ type: 'error', msg: P.string }, ({ msg }) => `failed: ${msg}`)
  .exhaustive()

const parsed = attempt(() => JSON.parse(raw) as User)
if (isOk(parsed)) {
  console.log(`got: ${parsed.value.name}`)
} else {
  console.error(`failed: ${parsed.error.message}`)
}

massaman brings both patterns to TypeScript, layered over es-toolkit and ts-pattern, plus a thin set of utilities filling the gaps: async-aware composition, variadic-narrowing predicates, and consistent error normalization.

More on the philosophy at zrosenbauer.com/gui/blog.

Contributing

See CONTRIBUTING.md for development setup, conventions, and PR process.

License

MIT

About

Functional programming utilities for TypeScript. Result types, pattern matching, async pipelines.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages