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

@net-mesh/sdk

v0.38.2

Published

Ergonomic TypeScript SDK for the Net mesh network

Readme

Net TypeScript SDK

A latency-first encrypted mesh where services and agents announce what they can do, discover each other at runtime, and invoke work over typed RPC.

npm License: MIT OR Apache-2.0

There is no broker. Every node is a peer on a flat, encrypted topology. A node publishes the capabilities it has — a GPU, a model, a tool, a licensed seat — and other nodes find it by what it can do, not by hostname. Credentials never leave the node that holds them: the machine with the secret runs the work.

// Find something that can do the job, then do it — no registry, no config.
const peers = node.findNodes({ requireTags: ['gpu'], minVramGb: 16 });
const rpc = node.rpc();
const resp = await callTool(rpc, 'summarize', { text });
rpc.raw.close();   // release the handle before node.shutdown()

Why this instead of a queue

Kafka, NATS and Redis Streams move bytes between a fixed producer and a fixed consumer through a broker you operate. That's a different problem. Net is for when the set of participants isn't known in advance and work has state worth observing:

| You need | Net gives you | |---|---| | Tools that appear and vanish at runtime | Capability announce + discovery, event-driven — no polling, no service registry | | Work spread across machines or organizations | One flat encrypted mesh; multi-hop discovery bounded at 16 hops | | Credentials that must not travel | The node holding the secret executes; callers never see it | | More than "did it return 200" | Durable logs, folded state, artifacts, streams, and replayable recovery | | GPUs matched by capability, not hostname | Hardware is a discoverable characteristic, with atomic gang-claim under contention |

Don't reach for it when one API call solves the problem, when a single server and database are enough, or when you have a fixed producer, a fixed consumer and a broker you're happy operating. The honest version of that list is in When to Use Net.

Install

npm install @net-mesh/sdk @net-mesh/core

@net-mesh/sdk is the TypeScript wrapper; @net-mesh/core is the napi-rs native binding it dispatches into. Prebuilt .node artifacts ship with every feature enabled.

Upgrade both together, and install them together. The wrapper is a thin typed layer over the binding, so a version skew surfaces as a missing method at the call site rather than at install time — which is why @net-mesh/sdk also declares a @net-mesh/core peer floor. If npm reports an unmet peer dependency, do not --force past it: the SDK is calling a binding method your core does not have. CHANGELOG.md records what each release asks a caller to change — read it before upgrading, especially if you filter on minVramGb / minMemoryGb.

The loop: announce → discover → invoke

Announce a tool, and it becomes discoverable across the mesh:

import { MeshNode, serveTool } from '@net-mesh/sdk';

// `psk` is a 64-character hex string, not bytes — it is hex-decoded at
// the native boundary. A `Uint8Array` here does not type-check and
// does not satisfy the runtime constructor.
const psk = '42'.repeat(32);                 // both peers share the same PSK
const node = await MeshNode.create({ bindAddr: '127.0.0.1:0', psk });

// Port 0 means the OS chooses; `localAddr()` is how the peer learns
// which port to connect to.
console.log(node.localAddr());

// `serveTool` takes the RPC handle, not the node — `node.rpc()` bridges the
// two. Hold the handle: each `rpc()` call makes a new one with its own
// reference to the mesh, and an outstanding reference blocks `shutdown()`.
const rpc = node.rpc();

const handle = serveTool(rpc, {
  name: 'web_search',
  description: 'Search the web for relevant pages.',
  tags: ['web', 'research'],
}, async (req: { query: string }) => {
  return { results: [`first hit for '${req.query}'`] };
});
// handle.close() when done — always close explicitly. Then `rpc.raw.close()`
// before `node.shutdown()`.

Discover — react to the mesh changing rather than polling it:

import { listTools, watchTools } from '@net-mesh/sdk';

for (const t of listTools(node)) {
  console.log(`${t.toolId} v${t.version}  tags=${t.tags}`);
}

const controller = new AbortController();
for await (const change of watchTools(node, { signal: controller.signal })) {
  console.log(change);   // pushed on fold mutation — no timer, no re-diff
}

Invoke — callTool takes the RPC handle, finds a provider for the name, and calls it:

import { callTool } from '@net-mesh/sdk';

const rpc = node.rpc();
const resp = await callTool(rpc, 'web_search', { query: 'how does the fold work' });
rpc.raw.close();   // release before node.shutdown()

For services rather than tools, nRPC gives you the same shape with deadlines, streaming and cancellation — Typed RPC.

A dedicated host for browser games

The browser package's networked store (@net-mesh/browser's hostStore) can run on a native node, so a game world outlives any one player's tab and no player holds the whole world:

import { MeshNode, meshStoreTransport } from '@net-mesh/sdk';
import { hostStore } from '@net-mesh/browser';

const mesh = await MeshNode.create({ bindAddr: '0.0.0.0:9000', psk });
await mesh.start();
const host = hostStore({
  definition: world,                                   // the same definition the pages use
  transport: meshStoreTransport(mesh, { listen: ['store/my-game.world'] }),
  initialState, maxEventBytes: 8104, authorize, actions, inputs,
});

meshStoreTransport receives with mesh.onStreamData(streamId, handler), which delivers each event with the peer whose session authenticated it — the identity every authorize decision rests on (recv has no sender). A host lists its store labels in listen (store/<definition id> by default) because players write first; streamIdFromLabel(label) is the id a browser page derives for the same label.

The bus

NetNode is the other node type: a sharded, in-process event bus with explicit backpressure.

import { NetNode } from '@net-mesh/sdk';

const node = await NetNode.create({ shards: 4 });

node.emit({ sensor: 'lidar', range_m: 12.5 });
node.emitRaw('{"sensor":"radar","range_m":45.0}');
node.emitBatch([{ a: 1 }, { a: 2 }, { a: 3 }]);

await node.flush();

const stats = node.stats();
console.log(`${stats.eventsIngested} ingested, ${stats.eventsDropped} dropped`);

await node.shutdown();   // explicit — Node finalizers are non-deterministic

Consume what you emit — on a transport that stores. The default is memory, which selects the Noop adapter: it counts batches and discards them, so subscribe() on the node above would block forever with nothing to yield.

const node = await NetNode.create({
  shards: 4,
  transport: { type: 'redis', url: 'redis://127.0.0.1:6379' },
});

node.emit({ sensor: 'lidar', range_m: 12.5 });

for await (const event of node.subscribe({ limit: 100 })) {
  console.log('event', event);
}

Memory is the right choice for ingestion, batching, backpressure, counters and lifecycle — everything above this snippet. Use redis, jetstream or mesh the moment a consumer has to receive something.

emit returns once the event is accepted into the local ring buffer — not that anyone processed it. Under backpressure it drops, and stats().eventsDropped is how you find out. That distinction is the whole philosophy: Submitted Is Not Completed.

Claude Code Skill

Net looks like Kafka or NATS from the outside, and the model underneath is different enough that an agent working from surface familiarity will write integration code that compiles, runs, and is quietly wrong. Install the skills first:

npx skills add ai-2070/net-claude-skill -g

Drop -g to install into the current project only. To update to the latest version:

npx skills update -g

Restart Claude Code and run /skills — net-event-bus and net-payments should be listed. They load automatically when a request matches:

"Wire up a Net publisher and subscriber over the mesh in TypeScript."

net-event-bus covers pub/sub, nRPC, the MCP bridge, organization capability auth, the gang-claim scheduler, and RedEX / CortEX / Dataforts. net-payments covers x402 pricing, quotes, settlement and spend policy. Full install options in Claude Skills.

Give the agent the source too

opensrc is a small tool that fetches a package's real source into a local cache for exactly this purpose:

npx -y opensrc@latest path ai-2070/net

Surfaces and the Cargo features behind them

Every wrapper dispatches into @net-mesh/core. Published artifacts ship every feature enabled, so this table matters only for source builds — a disabled feature's symbols are absent at runtime and the import resolves to undefined.

Everything below imports from the package root, @net-mesh/sdk. The only other entry point is @net-mesh/sdk/tool; the package's exports map defines those two and nothing else, so a per-feature subpath such as @net-mesh/sdk/mesh fails with ERR_PACKAGE_PATH_NOT_EXPORTED.

| Cargo feature | Surface | |---|---| | net | MeshNode, NetStream, channel auth | | cortex | Redex, RedexFile, TasksAdapter, MemoriesAdapter, NetDb | | meshdb | MeshQuery, MeshQueryRunner, MeshQueryStream, QueryBuilder, InMemoryChainReader | | meshos | MeshOsDaemonSdk, MeshOsDaemonHandle, DaemonHealth, CapabilityAdvert | | compute | DaemonRuntime, DaemonHandle, MigrationHandle | | groups | ReplicaGroup, ForkGroup, StandbyGroup | | deck | DeckClient, OperatorIdentity, admin / snapshot / status streams | | redis | RedisStreamDedup |

The bus surface — NetNode, EventStream, capabilities, identity, predicates — is always present. To slim a build:

cd net/crates/net/bindings/node
napi build --platform --release --no-default-features --features "cortex meshdb meshos"

--no-default-features is load-bearing: without it the crate's full default set stays on and nothing is slimmed.

What's in the box

| Surface | Guide | |---|---| | Event bus — shards, typed streams, backpressure, Redis / JetStream | Event bus | | Mesh streams — direct peer-to-peer, windowed | Mesh streams | | Capabilities — announce and discover | Discover and invoke | | nRPC — typed request/response, streaming, cancellation | Typed RPC | | Distributed mesh channels — roster fan-out with capability auth | Channels | | RedEX / CortEX / NetDB — logs, folds, queries | Durable logs, Folds, NetDB | | MeshDB — federated queries | MeshDB | | Dataforts — blobs, greedy cache, data gravity | Blob storage | | Compute + Groups — daemons, migration, replica/fork/standby | Daemons, Continuity | | Deck — the operator surface | Deck | | MCP bridge — wrap an MCP server, or serve the mesh as MCP | Wrap MCP, Expose as MCP | | Organizations — capabilities only your org can discover | Private capabilities | | Security — identity, delegable tokens, subnets | Identity, Security model | | Errors — the error classes and how to branch on them | Errors | | Redis Streams dedup | Deduplication |

Where to go next

  1. Quickstart — install both packages and connect two nodes.
  2. Discover and invoke — announce a tool and call it by capability.
  3. Production deployment — run the mesh beyond a single host.
  4. Errors — the error hierarchy, then @net-mesh/sdk on npm for the typed surface.

GitHub

License

MIT OR Apache-2.0