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

flit-physics

v0.2.2

Published

Flit is a tiny little physics engine for 3js. CPU-first, GPU-shaped.

Readme

Flit

Flit is a tiny little physics engine for 3js. It doesn't do much yet! but I believe!

Spheres, gravity, and a spatial-hash broadphase — nothing more, on purpose. All simulation state lives in flat Float32Arrays (structure-of-arrays), so the CPU path doubles as the reference implementation for a future WebGPU compute backend: same buffers, same kernels, no re-architecting.

What's in the box

  • World — point-sphere particles, semi-implicit Euler integration, impulse + positional-correction contact solver, infinite ground plane.
  • SpatialHash — uniform grid broadphase keyed by Morton (Z-order) cell codes. This is the Euclidean cousin in the LSH family: MinHash buckets documents by Jaccard similarity; this buckets positions so nearby points collide in the same bucket. Morton keys are bijective (no hash-collision pair bloat), invertible (no side table), and locality-ordered for a future sorted-array GPU backend.
  • Distance & bit utilities — squared Euclidean/L1/Minkowski/L∞/Hellinger/ chi-square/KL distances (ported from FLANN), Morton (Z-order) keys, float bit-flips for radix sorting, octagonal approximate distance. See THIRD_PARTY_NOTICES.md for provenance and licenses.

For agents

Building a little three.js game or demo? Two ways in:

  • Skill: skills/flit/SKILL.md — copy the skills/flit/ directory into your agent's skills path (e.g. .claude/skills/, ~/.code_puppy/skills/). It carries the 30-second integration recipe, the MCP option, measured performance envelope, and contributor rules.
  • MCP server (no code needed): npm run mcp, or point your client at it:
{
  "mcpServers": {
    "flit": {
      "command": "npx",
      "args": ["vite-node", "mcp/server.ts"],
      "cwd": "<path-to-this-repo>"
    }
  }
}

Tools: flit_info, flit_reset, flit_spawn (rain/explosion/grid/fountain presets), flit_add_particles, flit_step, flit_state — the last two return flat xyz positions shaped for InstancedMesh syncing.

Usage

npm i flit-physics
import { World } from 'flit-physics';

const world = new World({ restitution: 0.4 }); // gravity and a floor at y=0 included

const ball = world.addParticle({ position: [0, 10, 0], radius: 0.5, mass: 1 });

// fixed timestep, e.g. from your rAF loop
world.step(1 / 60);

// sync to three.js: positions is a live Float32Array, 3 floats per particle
mesh.position.set(
  world.positions[ball * 3],
  world.positions[ball * 3 + 1],
  world.positions[ball * 3 + 2],
);

Develop

npm install
npm test        # vitest
npm run build   # tsc -> dist/
npm run bench   # broadphase + full-step micro-benchmarks
npm run demo    # three.js demo scene (vite dev server)

Benchmarks

Deterministic seeds; numbers from a local dev machine, recorded at commit time (see commit messages for the full series, including rejected designs).

  • bench/broadphase.bench.ts — broadphase only, N=4096: xor-hash 3.4–3.7 ms (444 pairs, ~90% collision bloat) → Morton keys with ordered probing 3.5–3.7 ms (234 pairs, exact).
  • bench/world.bench.ts — full World.step, N=1024: xor-hash 0.85 ms/step → Morton ordered-probing 0.83 ms/step → 0.93 ms/step with the sequential-impulse velocity solver (4 iterations + LUT friction). Exact keys, real contacts, +11%.
  • bench/scaling.bench.ts — two regimes, and one important caveat. Fixed box (density rises): pairs scale ~N² from crowding physics. Scaled box (constant spawn density): flat O(N) ≈ 1.2 ms per 1000 through N=8000 — but only while bodies are scattered. The caveat: with gravity on, everything rains into a dense floor pile over ~2-4s (WARMUP=240 to reproduce), and steady-state piles are contact-solver dominated: ~4.3 ms per 1000 at N=8000 (87k contacts x 4 iterations), putting the 60fps pile budget near 3k bodies. The known fix for piles is island sleeping / agglomeration — parked.
  • bench/morton-libs.bench.ts — codec bake-off vs npm libs (npm run bench:libs): ours 3.8 ns/encode, fast-morton MB 26.1, fast-morton LUT 43.8, @thi.ng/morton 539.9. In-house wins; the libs stay as devDependencies purely so the bake-off stays runnable.
  • Rejected on measurement (see commits): 63-bit BigInt keys (13× alloc regression); sorted-array + binary-search broadphase (1.4× slower than Map probing in JS — negative result recorded).

Roadmap

  • ~~Morton-ordered broadphase cells~~ — done, measured, shipped
  • ~~three.js demo scene~~ — npm run demo, 220 balls in a box
  • Open issue: settled-pile solver cost — see docs/issues/001-settled-pile-performance.md (self-contained brief with repro, evidence, and definition of done; suitable for an agent or human to pick up)
  • WebGPU compute backend once the CPU reference settles

License

MIT — see LICENSE. Third-party portions and their licenses are listed in THIRD_PARTY_NOTICES.md.