npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@rimbu/table

v2.1.5

Published

Immutable spreadsheet-like data structures containing row keys, column keys, and cell values

Readme

npm version License Types Included Node Bun ESM + CJS

@rimbu/table

Immutable, spreadsheet‑like tables for TypeScript & JavaScript.

@rimbu/table provides efficient, type‑safe Table collections: immutable 2‑dimensional maps indexed by row keys and column keys, where each (row, column) pair has at most one value. It also ships concrete variants backed by hashed or sorted maps for both rows and columns.

Use it whenever you need grid‑like data, 2D indexing, or want to avoid juggling nested maps manually.


Table of Contents

  1. Why @rimbu/table?
  2. Feature Highlights
  3. Quick Start
  4. Core Concepts & Types
  5. Working with Hash & Sorted Tables
  6. Performance Notes
  7. Installation
  8. FAQ
  9. Ecosystem & Integration
  10. Contributing
  11. License

Why @rimbu/table?

Plain maps give you key → value lookups, but some datasets are naturally 2‑dimensional:

  • Spreadsheets and matrices – cells addressed by (row, column) keys.
  • Time‑series gridsuserId × day, metric × timeBucket, etc.
  • Indexing external data – look up a value by two dimensions without nested maps.

@rimbu/table focuses on:

  • Row/column semantics – explicit 2D API instead of nested Map<Map<…>>.
  • Immutable operations – updates return new instances with structural sharing.
  • Configurable backing maps – choose hash or sorted maps for rows and columns.
  • Rich traversal utilities – stream by entries, rows, or values.

If you find yourself nesting maps or objects to simulate a grid, a Table is usually a better fit.


Feature Highlights

  • 2D lookups – efficient (row, column) → value access.
  • Row‑level operations – get, filter, or remove entire rows at once.
  • Hash or sorted variants – choose between hashed or ordered semantics for rows and columns.
  • Immutable & persistent – structural sharing for fast copies and diffs.
  • Configurable contexts – use Table.createContext or concrete table variants to control underlying map types.
  • Builder support – mutable builders for efficient bulk construction.

Quick Start

import { HashTableHashColumn } from '@rimbu/table/hash-row';

// Create a hash-based table: hashed rows, hashed columns
const table = HashTableHashColumn.of<[number, string, boolean]>(
  [1, 'a', true],
  [1, 'b', false],
  [2, 'a', false]
);

// Look up a single cell
console.log(table.get(1, 'a')); // true

// Check presence
table.hasRowKey(2); // true
table.hasValueAt(1, 'c'); // false

// Immutable updates
const updated = table.set(2, 'b', true);
console.log(updated.get(2, 'b')); // true

You can also work with the generic Table interface via a custom context:

import { HashMap } from '@rimbu/hashed';
import { Table } from '@rimbu/table';

// Create a generic Table context using hash maps for rows and columns
const ctx = Table.createContext<number, string>({
  rowContext: HashMap.defaultContext<number>(),
  columnContext: HashMap.defaultContext<string>(),
});

const t = ctx.of<[number, string, boolean]>([1, 'a', true], [2, 'b', false]);

console.log(t.get(2, 'b')); // false
console.log(t.amountRows); // 2

Try Rimbu (including @rimbu/table) live in the browser using the Rimbu Sandbox on CodeSandbox.


Core Concepts & Types

Exported Types (main package)

From @rimbu/table:

| Name | Description | | -------------------------------- | -------------------------------------------------------------------------------------------------------------- | | Table<R, C, V> | Type‑invariant immutable table of row key type R, column key type C, and value type V. | | Table.NonEmpty<R, C, V> | Non‑empty refinement of Table<R, C, V> with stronger guarantees. | | Table.Context<UR, UC> | Factory/context for creating Table instances for upper row type UR and upper column type UC. | | Table.Builder<R, C, V> | Mutable builder for efficiently constructing or mutating a Table before freezing it into an immutable value. | | VariantTable<R, C, V> | Type‑variant view over a table; allows safe type‑widening of keys/values without mutation operations. | | VariantTable.NonEmpty<R, C, V> | Non‑empty refinement of VariantTable<R, C, V>. |

See the full Table docs and API reference for all operations.


Working with Hash & Sorted Tables

The package also exports specialized table types from sub‑packages:

  • @rimbu/table/hash-row
    • HashTableHashColumn<R, C, V>hashed rows, hashed columns.
    • HashTableSortedColumn<R, C, V>hashed rows, sorted columns.
  • @rimbu/table/sorted-row
    • SortedTableHashColumn<R, C, V>sorted rows, hashed columns.
    • SortedTableSortedColumn<R, C, V>sorted rows, sorted columns.

Each of these types exports:

  • *.NonEmpty<R, C, V> – non‑empty refinements.
  • *.Context<UR, UC> – context types.
  • *.Builder<R, C, V> – table builders.

And each has a corresponding creators object:

import {
  HashTableHashColumn,
  HashTableSortedColumn,
} from '@rimbu/table/hash-row';
import {
  SortedTableHashColumn,
  SortedTableSortedColumn,
} from '@rimbu/table/sorted-row';

// Hash rows + hash columns
const hh = HashTableHashColumn.empty<number, string, boolean>();

// Hash rows + sorted columns
const hs = HashTableSortedColumn.of<[number, string, number]>(
  [1, 'a', 1],
  [1, 'b', 2]
);

// Sorted rows + hash columns
const sh = SortedTableHashColumn.from([
  [1, 'a', true],
  [2, 'b', false],
]);

// Sorted rows + sorted columns
const ss = SortedTableSortedColumn.builder<number, string, number>();

Choose the variant based on whether you need ordering for rows and/or columns (use sorted) or just fast hash‑based lookup (use hashed).


Performance Notes

  • Tables in Rimbu are built on persistent data structures – updates are typically \(O(\log n)\) and share most of their structure.
  • Row and column operations are designed to behave similarly to their underlying map implementations (HashMap / SortedMap).
  • Many bulk operations accept generic StreamSource inputs, letting you construct and transform tables efficiently from arrays, iterables, or streams.

For detailed performance characteristics and benchmarks, see the main Rimbu documentation at rimbu.org.


Installation

Node / Bun / npm / Yarn

npm install @rimbu/table
# or
yarn add @rimbu/table
# or
bun add @rimbu/table
# or
deno add npm:@rimbu/table

Browser / ESM

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


FAQ

Q: How is a Table different from a nested Map<Map<…>>?
A Table gives you a dedicated 2D API (get, set, getRow, removeRow, etc.), row/column semantics, and consistent immutability guarantees, while still exposing row/column maps when needed.

Q: What happens if I set a value at an existing (row, column)?
The new value replaces the previous one and returns a new table instance; the original is unchanged.

Q: Is the structure mutable?
No. All updates return new table instances; existing ones remain unchanged and can be safely shared across your application.

Q: Can I iterate rows or values separately?
Yes. Use methods like stream, streamRows, streamValues, forEach, or convert to arrays/maps via toArray / rowMap.


Ecosystem & Integration

  • Part of the broader Rimbu collection ecosystem – interoperates with @rimbu/hashed, @rimbu/sorted, @rimbu/collection-types, and @rimbu/stream.
  • Ideal for modelling grids, cross‑product indices, availability matrices, and more.
  • Works seamlessly with other Rimbu collections and utilities for building rich, immutable data models.

Explore more at the Rimbu documentation and the Table API docs.


Contributing

We welcome contributions! See the Contributing guide for details.

Made with contributors-img.


License

MIT © Rimbu contributors. See LICENSE for details.


Attributions

Created and maintained by Arvid Nicolaas. Logo © Rimbu.