# @rimbu/common

> Common types and objects used in many other Rimbu packages

Latest version **2.0.7** (published 2026-01-19) · MIT license · 0 weekly downloads

## Install

```sh
npm install @rimbu/common
pnpm add @rimbu/common
yarn add @rimbu/common
bun add @rimbu/common
```

## Health

**Score 70/100 (B)** — status: stable.

Positive: has types; esm support; no vulnerabilities; has provenance; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.0.7 |
| Published | 2026-01-19 |
| First published | 2021-05-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 259.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 144 |
| Author | Arvid Nicolaas |
| Maintainers | vitoke |
| Keywords | common, range, reducer, immutable, rimbu, typescript |

## Links

- npm: https://www.npmjs.com/package/@rimbu/common
- Repository: https://github.com/rimbu-org/rimbu
- Homepage: https://rimbu.org
- Issues: https://github.com/rimbu-org/rimbu/issues
- Funding: https://github.com/sponsors/vitoke
- npm.io page: https://npm.io/package/@rimbu/common

## Dependencies (1)

- [tslib](https://npm.io/package/tslib.md) ^2.8.1

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 2.0.7 (latest) — 2026-01-19
- 0.5.0 (v0.5.beta.0) — 2021-05-20
- 2.0.6 — 2026-01-15
- 2.0.5 — 2025-11-28
- 2.0.4 — 2025-11-25
- 2.0.3 — 2025-11-23
- 2.0.2 — 2025-05-16
- 2.0.1 — 2024-03-05
- 2.0.0 — 2024-01-26
- 1.1.0 — 2023-07-29
- 1.0.0 — 2023-07-03
- 1.0.0-alpha.2 — 2023-07-02
- 1.0.0-alpha.1 — 2023-07-02
- 0.12.3 — 2023-04-26
- 0.12.2 — 2023-04-25
- … 29 more at https://npm.io/package/@rimbu/common/versions

## README

<p align="center">
  <img src="https://github.com/rimbu-org/rimbu/raw/main/assets/rimbu_logo.svg" height="96" alt="Rimbu Logo" />
</p>

<div align="center">

[![npm version](https://badge.fury.io/js/@rimbu%2Fcommon.svg)](https://www.npmjs.com/package/@rimbu/common)
![License](https://img.shields.io/github/license/rimbu-org/rimbu)
![Types Included](https://img.shields.io/badge/TypeScript-ready-blue)
![Node](https://img.shields.io/badge/Node-18+-6DA55F?logo=node.js&logoColor=white)
![Bun](https://img.shields.io/badge/Bun-%23000000.svg)
![ESM + CJS](https://img.shields.io/badge/modules-ESM%20%2B%20CJS-informational)

</div>

# `@rimbu/common`

**Shared utility types and helpers for the Rimbu ecosystem.**

`@rimbu/common` provides the low-level **building blocks** used throughout Rimbu:

- **Equality & comparison** helpers (`Eq`, `Comp`) for consistent value semantics.
- **Range & index utilities** (`Range`, `IndexRange`) for working with slices and windows.
- **Lazy values & updates** (`OptLazy`, `OptLazyOr`, `AsyncOptLazy`, `Update`) for ergonomic APIs.
- **Traversal helpers** (`CollectFun`, `TraverseState`) for efficient collection operations.
- **Type-level utilities** (`SuperOf`, `SubOf`, `RelatedTo`, `ArrayNonEmpty`, `StringNonEmpty`, `ToJSON`) for stronger TypeScript modelling.

Use this package directly in your own code, or consume it indirectly when using other Rimbu packages.

---

## Table of Contents

1. [Why `@rimbu/common`?](#why-rimbucommon)
2. [Feature Highlights](#feature-highlights)
3. [Quick Start](#quick-start)
4. [Core Concepts & Types](#core-concepts--types)
5. [Working with Equality & Comparison](#working-with-equality--comparison)
6. [Lazy Values, Updates & Async](#lazy-values-updates--async)
7. [Ranges & Indices](#ranges--indices)
8. [Type Utilities](#type-utilities)
9. [Installation](#installation)
10. [Ecosystem & Links](#ecosystem--links)
11. [Contributing](#contributing)
12. [License](#license)

---

## Why `@rimbu/common`?

Many Rimbu collections (and your own APIs) need **consistent behaviour** for:

- Comparing values (e.g. custom sort orders, structural vs reference equality).
- Handling optional or deferred values (lazy evaluation, async computations).
- Working with index or value ranges in a uniform way.
- Expressing richer type relationships in TypeScript.

Instead of re‑implementing these patterns, `@rimbu/common` provides:

- **Well-tested primitives** shared across all Rimbu packages.
- **Reusable utilities** you can depend on directly in your own libraries and apps.
- **Type-safe building blocks** that integrate smoothly with the rest of the Rimbu ecosystem.

---

## Feature Highlights

- **Pluggable equality & comparison** – `Eq` and `Comp` instances for primitives, objects, iterables, JSON, case-insensitive strings, and more.
- **Lazy & async helpers** – `OptLazy`, `OptLazyOr`, `AsyncOptLazy`, `MaybePromise` to keep APIs flexible without sacrificing clarity.
- **Declarative ranges** – `Range<T>` and `IndexRange` to describe open/closed and offset-based ranges in a single, typed shape.
- **Traversal utilities** – `CollectFun` and `TraverseState` for customizable, short‑circuitable traversals.
- **Type-level helpers** – utilities like `ArrayNonEmpty`, `StringNonEmpty`, and `ToJSON` to express invariants and serializable shapes.

---

## Quick Start

```ts
import { Eq, Comp, OptLazy, Update } from '@rimbu/common';

// Equality: deep structural comparison
const eq = Eq.anyDeepEq<Record<string, unknown>>();
console.log(eq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true

// Comparison: natural number ordering
const numComp = Comp.numberComp();
console.log(numComp.compare(3, 5) < 0);
// => true

// Lazy values: compute only when needed
const lazyValue = OptLazy(() => 1 + 2);
console.log(lazyValue); // 3

// Updates: accept either a value or an updater function
const next = Update(1, (v) => v + 1);
console.log(next); // 2
```

Try Rimbu (including `@rimbu/common`) live in the browser using the
[Rimbu Sandbox on CodeSandbox](https://codesandbox.io/s/github/vitoke/rimbu-sandbox/tree/main?previewwindow=console&view=split&editorsize=65&moduleview=1&module=/src/index.ts).

---

## Core Concepts & Types

### Exported Types & Utilities

| Name               | Description                                                                                        |
| ------------------ | -------------------------------------------------------------------------------------------------- |
| `CollectFun`       | Types used by `collect`-style functions to map/filter in a single pass with skip & halt support.   |
| `AsyncCollectFun`  | Asynchronous version of `CollectFun`, returning `MaybePromise` of a collected value or skip token. |
| `Comp`             | Interface and implementations for comparing values (ordering / sorting).                           |
| `Eq`               | Interface and implementations for checking value equality.                                         |
| `Err`, `ErrBase`   | Helpers to throw consistent custom errors from fallback handlers.                                  |
| `IndexRange`       | Range specification for numeric indices (e.g. slicing arrays or collections).                      |
| `Range<T>`         | Range specification for ordered values of type `T`.                                                |
| `OptLazy`          | A value or a function returning a value (lazy).                                                    |
| `OptLazyOr`        | Like `OptLazy`, but can return a provided default value instead.                                   |
| `AsyncOptLazy`     | Potentially lazy and/or async values built on `OptLazy` + `MaybePromise`.                          |
| `MaybePromise<T>`  | A value of type `T` or a `Promise<T>`.                                                             |
| `TraverseState`    | Object to track progress & early termination in traversals.                                        |
| `Update`           | Value or updater function used to derive a new value from the old one.                             |
| `SuperOf`, `SubOf` | Type utilities for expressing upper/lower bounds between types.                                    |
| `RelatedTo`        | Type utility accepting related types where one extends the other.                                  |
| `ArrayNonEmpty`    | Tuple type representing non-empty arrays.                                                          |
| `StringNonEmpty`   | Type representing non-empty string types.                                                          |
| `ToJSON`           | Helper interface for JSON-serializable wrapper objects.                                            |

See the full [Common API reference](https://rimbu.org/api/rimbu/common) for all members and overloads.

---

## Working with Equality & Comparison

### Equality with `Eq`

```ts
import { Eq } from '@rimbu/common';

// Deep structural equality
const deepEq = Eq.anyDeepEq<Record<string, unknown>>();
console.log(deepEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true

// Shallow equality: one level into objects / iterables
const shallowEq = Eq.anyShallowEq<Record<string, unknown>>();
console.log(shallowEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true

// Flat equality: composed values compared using Object.is
const flatEq = Eq.anyFlatEq<Record<string, unknown>>();
console.log(flatEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => false

// Case-insensitive string equality
const ci = Eq.stringCaseInsentitiveEq();
console.log(ci('AbC', 'aBc'));
// => true
```

### Comparison with `Comp`

```ts
import { Comp } from '@rimbu/common';

// Numbers: natural ordering with special handling for NaN and infinities
const numberComp = Comp.numberComp();
numberComp.compare(3, 5); // < 0

// Strings: locale-aware comparison
const stringComp = Comp.stringComp('en');
stringComp.compare('a', 'b'); // < 0

// Deep comparison of arbitrary values
const anyDeepComp = Comp.anyDeepComp<unknown>();
anyDeepComp.compare({ a: 1 }, { a: 1 }); // 0

// Convert a comparison into an equality function
const objectEq = Comp.toEq(Comp.objectComp());
console.log(objectEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true
```

---

## Lazy Values, Updates & Async

### `OptLazy` and `OptLazyOr`

```ts
import { OptLazy, OptLazyOr } from '@rimbu/common';

// Eager or lazy values
OptLazy(1); // => 1
OptLazy(() => 1); // => 1

// With a default "other" value
OptLazyOr(1, 'a'); // => 1
OptLazyOr(() => 1, 'a'); // => 1
OptLazyOr((none) => none, 'a'); // => 'a'
```

### `Update`

```ts
import { Update } from '@rimbu/common';

Update(1, 2); // => 2
Update(1, () => 10); // => 10
Update(1, (v) => v + 1); // => 2
```

### `AsyncOptLazy` and `MaybePromise`

```ts
import { AsyncOptLazy } from '@rimbu/common';

// Get a value or promised value
await AsyncOptLazy.toPromise(1); // Promise(1)
await AsyncOptLazy.toPromise(() => 1); // Promise(1)
await AsyncOptLazy.toPromise(async () => 1); // Promise(1)
await AsyncOptLazy.toPromise(Promise.resolve(1)); // Promise(1)
```

---

## Ranges & Indices

### `Range<T>`

```ts
import { Range } from '@rimbu/common';

// Inclusive start, exclusive end
const r1: Range<number> = { start: [0, true], end: [10, false] };

// Only end (inclusive by default)
const r2: Range<number> = { end: 5 };

// Normalize for easier handling
const normalized = Range.getNormalizedRange(r1);
// => { start: [0, true], end: [10, false] }
```

### `IndexRange`

```ts
import { IndexRange } from '@rimbu/common';

const ir: IndexRange = { start: [0, true], amount: 3 };

// Extract concrete indices for a given length
IndexRange.getIndicesFor(ir, 10); // [0, 2]
```

---

## Type Utilities

```ts
import type {
  SuperOf,
  SubOf,
  RelatedTo,
  ArrayNonEmpty,
  StringNonEmpty,
  ToJSON,
} from '@rimbu/common';

type A = SuperOf<string, 'a' | 'b'>; // string
type B = SubOf<'a' | 'b', string>; // 'a' | 'b'
type R = RelatedTo<'a', string>; // 'a' | string

type NonEmptyNumbers = ArrayNonEmpty<number>; // [number, ...number[]]
type NonEmptyString = StringNonEmpty<'a' | ''>; // 'a'

interface UserJSON extends ToJSON<{ id: number }, 'User'> {}
```

---

## Installation

### Node / Bun / npm / Yarn

```sh
npm install @rimbu/common
# or
yarn add @rimbu/common
# or
bun add @rimbu/common
# or
deno add npm:@rimbu/common
```

Then:

```ts
import { Eq } from '@rimbu/common/mod.ts';
```

### Browser / ESM

`@rimbu/common` ships both **ESM** and **CJS** builds. Use it with any modern bundler
(Vite, Webpack, esbuild, Bun, etc.) or directly in Node ESM projects.

---

## Ecosystem & Links

- Part of the broader **Rimbu** collection ecosystem – interoperates with `@rimbu/collection-types`,
  `@rimbu/hashed`, `@rimbu/ordered`, `@rimbu/stream`, and more.
- Main documentation: [rimbu.org](https://rimbu.org)
- Package docs: [Common docs](https://rimbu.org/docs/common/overview)
- API reference: [Common API](https://rimbu.org/api/rimbu/common)

---

## Contributing

We welcome contributions! See the
[Contributing guide](https://github.com/rimbu-org/rimbu/blob/main/CONTRIBUTING.md) for details.

<img src="https://contrib.rocks/image?repo=rimbu-org/rimbu" alt="Contributors" />

_Made with [contributors-img](https://contrib.rocks)._

---

## License

MIT © Rimbu contributors. See [LICENSE](./LICENSE) for details.

---

## Attributions

Created and maintained by [Arvid Nicolaas](https://github.com/vitoke). Logo © Rimbu.

---
_Source: https://npm.io/package/@rimbu/common · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
