mrkeyoor.com_
Sat 08 Aug 21:00 UTC
npmDataupdated 08 Aug 2026

js-sdsl

js-sdsl is a dependency-free TypeScript collection library modeled after C++'s standard data structures. It supplies Stack, Queue, PriorityQueue, Vector, LinkList, Deque, OrderedSet, OrderedMap, HashSet, and HashMap with typed constructors, STL-style mutable iterators, common size and clear methods, and iterable output. Its main value is access to heaps, red-black-tree ordering, indexed double-ended queues, and linked lists that JavaScript's built-ins do not provide.

Verdict

Worth installing for a measured need for deque, heap, or ordered-tree behavior, especially when translating STL-heavy algorithms. Prefer native collections for ordinary application state, avoid the hash containers for identity-sensitive or frozen keys, and do not follow the currently redirected docs domain.

API stability4/5Version 4 exposes a coherent shared base with length, size(), empty(), and clear(), plus long-established STL-style names across ten containers. Shipped declarations make return types and iterator behavior explicit. The API is broad and some semantics are surprising, especially custom comparator direction, mutable iterators, constructor copy flags, and hash-object tagging, so a major upgrade deserves container-level regression tests.
Docs2/5The README lists every structure, supported environments, package variants, browser and npm imports, testing commands, and links to generated TypeDoc pages. However, js-sdsl.org and the linked API pages currently redirect to an unrelated survey domain. The README lacks enough inline API detail to replace that site, leaving users to inspect bundled .d.ts files and source for iterator, comparator, and hash-key edge cases.
Maintenance3/5The repository is not archived and was pushed April 14, 2026, with CI, unit, browser, performance, and isolated-package test scripts visible in the project. The published 4.4.2 release dates to July 2023, so recent repository work has not produced a new stable package. The uncorrected homepage redirect is a serious maintenance and supply-chain trust signal even though npm itself is not deprecated.
Ecosystem4/5js-sdsl recorded 4,249,867 npm downloads from July 31 through August 6, 2026, has 801 GitHub stars, supports CommonJS, ESM, UMD, TypeScript, browsers, and Node, and publishes ten isolated scoped packages. Its iterable containers work with for...of and Array.from. The non-native naming and semantics limit drop-in interoperability with code written for Map, Set, or standard iterators.

Use it if

  • You need a priority queue, deque, or sorted map or set and do not want to implement and test the underlying heap or red-black tree
  • You are porting an algorithm from C++ and STL-shaped methods such as lowerBound, begin, end, pointer, pushBack, and eraseElementByIterator reduce translation mistakes
  • You need browser and Node builds, bundled TypeScript declarations, no runtime dependencies, and optional one-container scoped packages
  • You have benchmarked a real workload where native Array, Map, or Set is the wrong complexity or memory tradeoff
Skip it if

Setup reality

npm install js-sdsl adds no runtime dependencies, peer dependencies, native builds, configuration files, credentials, or environment variables. Version 4.4.2 publishes CommonJS under dist/cjs, ESM under dist/esm, a UMD build, and declarations from dist/esm/index.d.ts. It marks sideEffects false but has no exports map, so resolution and tree shaking depend on your bundler's support for main and module. Import named containers from js-sdsl, or install a scoped package such as @js-sdsl/deque when only one structure is needed. The complete package measured 8.103 KB gzipped, making scoped packages worth considering in browser code. The API intentionally follows STL more than native JavaScript: size is a method, length is a getter, vectors use pushBack and getElementByPos, maps use setElement and getElementByKey, and find returns a mutable container iterator that must be compared with end(). Calling pointer on an end iterator throws. Tree containers use a default < and > comparator; object keys need a stable total-order comparator, and mutating a field used by that comparator corrupts ordering unless the key is removed and reinserted. PriorityQueue is a max-heap by default; a comparator like (a, b) => a - b makes a min-heap, the opposite of what many developers first guess. Vector and PriorityQueue constructors shallow-copy input arrays unless copy is false. Hash containers do not behave exactly like native Map and Set: object keys are tagged with a symbol and frozen objects can fail, while primitive keys pass through an object property table. The official docs domain currently redirects elsewhere, so use shipped declarations, repository source, and tests instead of following the site links. The last npm release was July 2023 even though the repository was pushed in 2026, so pin 4.4.2 and test your chosen containers rather than assuming unreleased source fixes are installed.

Patterns

Process highest-priority work firstuse-max-priority-queue

import { PriorityQueue } from 'js-sdsl'

type Job = { id: string; priority: number }
const jobs = new PriorityQueue<Job>([], (a, b) => b.priority - a.priority)
jobs.push({ id: 'email', priority: 2 })
jobs.push({ id: 'incident', priority: 10 })

console.log(jobs.pop()?.id) // incident

The built-in default is a max-heap for primitive values. For objects, supply a comparator and test which item reaches top() before relying on it.

Create a min-heap for shortest distanceuse-min-priority-queue

import { PriorityQueue } from 'js-sdsl'

const distances = new PriorityQueue<number>([], (a, b) => a - b)
distances.push(30)
distances.push(5)
distances.push(12)

console.log(distances.top()) // 5
console.log(distances.pop()) // 5

Comparator a - b makes smaller values higher priority in this API. pop() removes and returns the top item, or undefined when empty.

Push and pop at both endsuse-double-ended-queue

import { Deque } from 'js-sdsl'

const deque = new Deque<number>()
deque.pushBack(2)
deque.pushFront(1)
deque.pushBack(3)

console.log(deque.front(), deque.back()) // 1 3
deque.popFront()
deque.popBack()

Deque is the compelling replacement for repeated Array.shift or unshift on large queues. Empty pops return undefined.

Keep map entries sorted by keyuse-ordered-map

import { OrderedMap } from 'js-sdsl'

const scores = new OrderedMap<string, number>([], (a, b) => a.localeCompare(b))
scores.setElement('zoe', 8)
scores.setElement('ada', 10)

console.log(scores.getElementByKey('ada')) // 10
console.log([...scores]) // [['ada', 10], ['zoe', 8]]

The comparator defines key identity as well as order. It must return zero exactly when keys should be treated as the same entry.

Find the first sorted key at or above a targetfind-lower-bound

import { OrderedSet } from 'js-sdsl'

const values = new OrderedSet([10, 20, 40, 50])
const iterator = values.lowerBound(25)
if (!iterator.equals(values.end())) {
  console.log(iterator.pointer) // 40
}

Never read pointer from end(); it throws. lowerBound returns the first element not less than the target according to the set comparator.

Build a sorted unique sequencededuplicate-in-order

import { OrderedSet } from 'js-sdsl'

const unique = new OrderedSet([5, 1, 5, 3, 1])
console.log(Array.from(unique)) // [1, 3, 5]
unique.insert(2)
unique.eraseElementByKey(5)

Use native Set if insertion order is enough. OrderedSet pays tree costs to maintain comparator order and provide bounds operations.

Use indexed STL-style sequence operationsuse-vector

import { Vector } from 'js-sdsl'

const vector = new Vector([10, 20, 30])
vector.pushBack(40)
vector.setElementByPos(1, 25)
vector.insert(2, 99)

console.log(vector.getElementByPos(2)) // 99
console.log([...vector]) // [10, 25, 99, 30, 40]

Positions outside the valid range throw RangeError. Native Array is usually simpler unless STL-compatible container methods help the algorithm.

Merge two sorted linked listsuse-linked-list

import { LinkList } from 'js-sdsl'

const odd = new LinkList([1, 3, 5])
const even = new LinkList([2, 4, 6])
odd.merge(even)

console.log([...odd]) // [1, 2, 3, 4, 5, 6]

Both lists must already be sorted with compatible ordering. Do not use LinkList for indexed access, which requires traversal.

Choose LIFO or FIFO behavior explicitlyuse-stack-and-queue

import { Queue, Stack } from 'js-sdsl'

const pending = new Queue(['first', 'second'])
console.log(pending.front()) // first
console.log(pending.pop())   // first

const history = new Stack(['first', 'second'])
console.log(history.top()) // second
console.log(history.pop()) // second

Queue and Stack expose only their relevant ends. For small workloads, Array with push/pop or an index pointer is often enough.

Erase through a mutable container iteratorerase-while-iterating

import { OrderedSet } from 'js-sdsl'

const set = new OrderedSet([1, 2, 3, 4, 5])
for (let iterator = set.begin(); !iterator.equals(set.end());) {
  if (iterator.pointer % 2 === 0) {
    iterator = set.eraseElementByIterator(iterator)
  } else {
    iterator.next()
  }
}
console.log([...set]) // [1, 3, 5]

eraseElementByIterator returns the next iterator. iterator.next() mutates and returns the same iterator object, unlike JavaScript's standard iterator protocol.

Keep object identity keys in native Mapavoid-hash-object-keys

const metadata = new Map<object, string>()
const frozenKey = Object.freeze({ id: 1 })
metadata.set(frozenKey, 'ready')

console.log(metadata.get(frozenKey)) // ready

js-sdsl HashMap tags object keys with Object.defineProperty and can fail on frozen keys. Native Map already provides identity-safe object keys without mutation.

Install only the deque package for browser codeinstall-isolated-container

npm install @js-sdsl/deque

import Deque from '@js-sdsl/deque'
const events = new Deque<string>()
events.pushBack('connected')

The project publishes each container separately. Confirm the isolated package's import shape and keep its version aligned when mixing it with the main package.

Alternatives

PackageRegistryPick it when
mnemonistnpmUse for a broad, JavaScript-oriented collection of specialized structures including heaps, deques, tries, queues, and indexes
denquenpmUse when the only missing structure is a focused double-ended queue with a smaller API and dependency surface
heap-jsnpmUse when you need only a heap or priority queue and prefer comparator semantics documented around that single structure
immutablenpmUse when persistent immutable collections and structural sharing matter more than STL-style mutable containers