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

ts-sparse-set

v1.0.5

Published

A high-performance, TypeScript-native SparseSet implementation for ECS and other ID-based collections. Provides O(1) add, remove, get, and has operations with dense storage and optional object pooling for components.

Downloads

608

Readme

TS SparseSet

NPM version Downloads

TS SparseSet is a high-performance TypeScript data structure implementing a sparse set, providing constant-time operations and cache-friendly dense storage. Ideal for ECS architectures, game engines, simulations, and any ID-indexed data.


Features

  • O(1) Operations: add, remove, has, get, ensure, and index lookups.
  • Dense Storage: Compact arrays for optimal data locality and iteration speed.
  • Swap-Remove Semantics: Maintains dense compactness after deletions without gaps.
  • Full Iteration Support: Native iterators, values(), ids(), entries(), forEach().
  • Zero-GC Hot Path: No intermediate allocations in iteration modes.
  • TypeScript Native: Fully typed, generic, and safe.

Installation

npm install ts-sparse-set

Usage Example

import { SparseSet } from 'ts-sparse-set';

const set = new SparseSet<number>();

set.add(10, 42);
set.add(20, 100);

console.log(set.has(10)); // true
console.log(set.get(20)); // 100

set.add(10, 77);
console.log(set.get(10)); // 77

set.remove(20);
console.log(set.has(20)); // false

// Iteration (dense order)
for (const entry of set) {
  console.log(entry.id, entry.value);
}

// Using ensure(...)
const v = set.ensure(50, () => 123);
console.log(v); // 123

// Utility iteration helpers
console.log([...set.ids()]);    // [10, 50]
console.log([...set.values()]); // [77, 123]
console.log(set.size());        // 2

API Documentation

class SparseSet<V>

Core Methods

| Method | Description | | ---------------------------------- | --------------------------------------------------- | | add(id: number, value: V): V | Inserts a new value or replaces an existing one. | | get(id: number): V \| null | Retrieves a value or returns null if not present. | | has(id: number): boolean | Checks if an element exists. | | remove(id: number): void | Removes the element using O(1) swap-remove logic. | | size(): number | Returns the number of elements stored. | | clear(): void | Removes all elements. |

Iteration Helpers

| Method | Description | | --------------------------------------- | ------------------------------------------------------- | | [Symbol.iterator]() | Iterates over { id, value } entries in dense order. | | ids(): Generator<number> | Iterates over all ids. | | values(): Generator<V> | Iterates over all values. | | entries(): Generator<[number, V]> | Iterates over [id, value] tuples. | | forEach(fn) | Efficient callback-based iteration without allocations. |

Utility Methods

| Method | Description | | --------------------------------------------- | --------------------------------------------------- | | ensure(id: number, factory: () => V): V | Returns existing value or inserts a new one lazily. | | tryGetIndex(id: number): number | Returns dense index or -1 if id does not exist. |


Benchmarks

Tested on:

  • CPU: AMD Ryzen 7 7700 (8-core, up to 5.4 GHz)
  • RAM: 32 GB DDR5-5600
  • OS: Windows 11 Pro
  • Runtime: Node.js v24.11.1 (tsx)
  • Set size: 1,000,000 entities

| Operation | Throughput (ops/sec) | Per-operation latency | |------------------------------|----------------------------|-----------------------| | add() | 30.0 – 31.0 million | ~32–34 ns | | has() | 9.7 – 9.9 million | ~101–103 ns | | get() | 7.6 – 7.7 million | ~130–132 ns | | remove() (swap-remove) | 13.0 – 13.9 million | ~72–77 ns | | ensure(id, factory) | 4.0 million | ~250 ns | | size() | >526 million | ~1.9 ns | | forEach() (1M elements) | 191–193 passes/sec | ~5.2 ms | | ids() / values() | 64–65 passes/sec | ~15.4–15.6 ms | | Generator iteration | 54–55 passes/sec | ~18–19 ms |

When to Use SparseSet

SparseSet excels when:

  • IDs are numeric and bounded.
  • You need fast add/remove with compact dense data.
  • You rely heavily on iteration speed (ECS, physics, grids, pools).
  • You want predictable memory layout and minimal GC pressure.

It is not a general-purpose map or associative container — it is optimized for performance-critical numeric ID use cases.


Contributing

Issues, PRs, and suggestions are welcome. Project repository: https://github.com/yazmeyaa/ts-sparse-set