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 🙏

© 2026 – Pkg Stats / Ryan Hefner

hashmap

v3.0.1

Published

HashMap Class for JavaScript

Readme

hashmap

A small HashMap class for JavaScript — any key type, stable API since 2012, rewritten for 3.0.

Works in Node.js (14+) and the browser. ESM, CommonJS, TypeScript types, and an IIFE build included.

NPM

npm install hashmap
import HashMap from 'hashmap'
// or
const HashMap = require('hashmap')

Why this exists

Native Map didn't exist when this library was created. It does now — and for most new code, Map is the right default.

hashmap is still worth reaching for when you need more than Map gives you:

| | hashmap | Map | WeakMap | |---|---|---|---| | Any key type (null, numbers, strings, objects, …) | yes | yes | objects only | | Object keys by identity | yes | yes | yes | | Iterate all entries / .size | yes | yes | no | | Value-based equality for Date, RegExp, arrays | yes | no | no | | Reverse lookup (.search(value)) | yes | no | no | | Method chaining on mutators | yes | partial | no |

Use hashmap when:

  • You need custom key equality — two Date objects with the same timestamp, two /foo/ regexes, arrays compared element-wise.
  • You need .search() — find the key for a value.
  • You're maintaining legacy code that already depends on this API (plugin systems, protobuf registries, object-key pools, etc.).
  • You want a stable, zero-dependency map that behaves the same in Node and the browser.

Use native Map when: string/number/symbol keys with === equality is enough. That's most apps.

Use WeakMap when: keys are objects and you want them garbage-collected when nothing else references them. You can't iterate a WeakMap.


Quick start

const map = new HashMap()

map.set('1', 'string one')
map.set(1, 'number one')
map.get('1') // 'string one'
map.get(1)   // 'number one'

const a = {}
const b = {}
map.set(a, 'first')
map.set(b, 'second')
map.get(a) // 'first' — object identity, not stringification

Method chaining

new HashMap()
  .set(1, 'one')
  .set(2, 'two')
  .forEach((value, key) => console.log(key, value))

Iteration

map.forEach((value, key) => { /* … */ })

for (const { key, value } of map) {
  console.log(key, value)
}

Reverse lookup

map.set('id', 42)
map.search(42) // 'id'

API

Constructor

  • new HashMap() — empty map
  • new HashMap(other) — copy from another HashMap
  • new HashMap([['k1', 'v1'], ['k2', 'v2']]) — from pairs array
  • new HashMap(k1, v1, k2, v2, …) — from arguments

Methods

| Method | Description | |---|---| | get(key) | Value for key, or undefined | | set(key, value) | Store a pair (chainable) | | has(key) | Whether key exists | | delete(key) | Remove by key (chainable) | | search(value) | Key for value, or null | | clear() | Remove all entries (chainable) | | forEach(fn, ctx?) | Iterate (value, key) (chainable) | | keys() / values() / entries() | Arrays of keys, values, or [key, value] pairs | | clone() | Shallow copy as a new HashMap | | copy(other) | Copy entries from other into this map (chainable) | | multi(k1, v1, …) | Set several pairs at once (chainable) | | size | Number of entries |

Deprecated aliases kept for compatibility: remove()delete(), count()size, type().

TypeScript

Types ship with the package. Generics work as expected:

import HashMap from 'hashmap'

const cache = new HashMap<string, number>()
cache.set('answer', 42)

Upgrading from 2.x / @types/hashmap

Types ship with the package since 3.0.0 — remove DefinitelyTyped:

npm uninstall @types/hashmap

@types/hashmap used export = HashMap (CommonJS assignment import). 3.0 uses a default export:

import HashMap from 'hashmap'
// import HashMap = require('hashmap')  // still works in TS with esModuleInterop

hash() was removed (internal helper, no known dependents). Deprecated remove(), count(), and type() remain. See docs/backwards-compatibility.md.


Browser

For a script tag without a bundler, use the IIFE build:

<script src="node_modules/hashmap/dist/hashmap.iife.js"></script>
<script>
  const map = new HashMap()
  map.set(document.body, 'root')
</script>

Benchmarks

3.0 rewrote the internals (numeric hashing, flat entry storage, eager Map index, cached entry hashes). Measured on Node 24, ~250 ms per benchmark, string keys unless noted. Run locally:

npm run benchmark
npm run benchmark -- -o tmp/current.json --compare tmp/benchmark-baseline.json

vs 2.4.0

| Operation | 2.4.0 | 3.0.0 | Change | |---|---:|---:|---:| | set | 226K | 266K | 1.2× | | get | 224K | 298K | 1.3× | | has | 237K | 268K | 1.1× | | delete | 210K | 264K | 1.3× | | set (replace existing key) | 7K | 193K | 26× | | get (map with 1024 entries) | 10K | 273K | 27× | | forEach (1024 entries) | 29K | 1.7M | 60× | | keys (1024 entries) | 26K | 722K | 28× | | clone (1024 entries) | 11K | 19K | 1.7× | | copy (1024 entries) | 12K | 19K | 1.6× | | set after delete (1024 entries) | 238K | 91K | 0.4× |

Summary: 18 of 20 benchmarks faster than 2.4.0. Biggest wins: replacing/updating keys, iteration, and clone/copy. Remaining gaps: burst inserts into an empty map and delete-then-set on large maps.

Values are ops/sec (higher is better). Native Map is faster on plain get with string keys — hashmap trades that for custom equality, .search(), and the legacy API.


Development

npm test        # types + unit tests
npm run build   # dist (esm, cjs, iife, dts)
npm run lint

License

MIT © Ariel Flesler