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

shredstream

v2.0.0

Published

Solana ShredStream SDK for Node.js — ultra-low latency UDP shred streaming

Downloads

73

Readme

Solana ShredStream SDK for JavaScript / TypeScript

Solana ShredStream SDK/Decoder for JavaScript/TypeScript, enabling ultra-low latency Solana transaction streaming via UDP shreds from ShredStream.com

Part of the ShredStream.com ecosystem — ultra-low latency Solana shred streaming via UDP.

License: MIT TypeScript Node

📋 Prerequisites

  1. Create an account on ShredStream.com
  2. Launch a Shred Stream and pick your region (Frankfurt, Amsterdam, Singapore, Chicago, and more)
  3. Enter your server's IP address and the UDP port where you want to receive shreds
  4. Open your firewall for inbound UDP traffic on that port (e.g. configure your cloud provider's security group)
  5. Install Node.js 18+ and npm:
    # Linux (Ubuntu/Debian)
    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
    sudo apt install -y nodejs
    
    # macOS
    brew install node

🎁 Want to try before you buy? Open a ticket on our Discord to request a free trial.

📦 Installation

npm install shredstream

⚡ Quick Start

Create a file index.ts:

import { ShredListener } from 'shredstream';
import { VersionedTransaction } from '@solana/web3.js';

const PORT = parseInt(process.env.SHREDSTREAM_PORT || '8001');
const listener = ShredListener.bind(PORT);

while (true) {
  const batch = listener.nextTransactionSync();
  if (batch === null) {
    throw new Error(`shredstream listener stopped: ${listener.lastIoErrorKind ?? 'unknown'}`);
  }
  for (const raw of batch.transactions) {
    const tx = VersionedTransaction.deserialize(new Uint8Array(raw));
    console.log(`slot ${batch.slot}: ${tx.signatures[0]}`);
  }
}

nextTransactionSync() is the lowest-latency path — recommended for dedicated MEV / sniping consumers. A null return is a terminal state (socket closed, fatal I/O like BrokenPipe or NetworkDown); inspect listener.lastIoErrorKind and let your process supervisor (systemd, Docker, k8s) restart you. If you need to mix with other Node async I/O (dgram.send, HTTP, timers), use for await (const batch of listener) instead — see Performance.

Run it:

npx tsx index.ts

📖 API Reference

ShredListener

  • ShredListener.bind(port) — Bind with defaults (64 MB recv buf, 3 slot window, FEC enabled)
  • ShredListener.bindWithOptions(port, opts) — Custom configuration
  • ShredListener.offline() — Bind on ephemeral port; drive via handlePacket()
  • ShredListener.fromFd(fd, opts) — Adopt an existing UDP file descriptor
  • listener.nextTransactionSync()Sync single-pull (lowest latency, MEV-grade — see Performance)
  • for await (const { slot, transactions } of listener) — Async iterator, compatible with other Node async I/O
  • await listener.nextTransaction() — Async single-pull, resolves to { slot, transactions } | null
  • await listener.nextShred() — Raw shred header { slot, index, payloadLen }
  • listener.handlePacket(buf: Buffer) — Inject an externally-received UDP datagram
  • listener.close() — Release the socket

Options

interface ListenerOptions {
  recvBuf?: number;
  maxAge?: bigint;
  busyPollUs?: number;
  disableBusyPoll?: boolean;
  poolSize?: number;
  enableFec?: boolean;
  disableSalvageDelivery?: boolean;
  accumulator?: { maxFecSetsPerSlot?: number; stuckBatchTimeoutMs?: number };
}

| Field | Default | Description | |-------|---------|-------------| | recvBuf | 64 MB | SO_RCVBUF size. Kernel rmem_max must allow it | | maxAge | 3n | Slot retention window | | busyPollUs | 200 | Linux SO_BUSY_POLL µs (best-effort) | | disableBusyPoll | false | Pass true to disable busy poll explicitly | | poolSize | 4096 | Number of 2 KiB buffers in the zero-copy pool | | enableFec | true | Reed-Solomon recovery on dropped data shreds | | disableSalvageDelivery | false | Drop salvaged tail txs for lowest p99 | | accumulator.maxFecSetsPerSlot | 32 | Per-slot FEC buffer cap | | accumulator.stuckBatchTimeoutMs | 50 | Force-finalize a stuck batch after this delay |

Metrics

Read-only getters mirroring the Rust crate. All u64 counters are bigint:

| Group | Getters | |-------|---------| | Throughput | dataShredCountTotal, codeShredCountTotal, bytesReceived, slotCount | | Decoder | batchesDecodedStreamingTotal, batchesDecodedFallbackTotal, batchesSkippedTotal, decodeErrorsTotal | | FEC | fecRecoveriesTotal, fecRecoveryFailuresTotal, fecSetsDiscardedUnusedTotal, fecSetsEvictedEarlyTotal | | Unparseable | unparseablePackets, unparseableTooShort, unparseableVariant, unparseablePayload, unparseableSlotRange | | Slot lifecycle | slotsCompletedTotal, slotsEvictedByAge, droppedKnownSlots, harvestedBatchesTotal, salvagedTailTxTotal | | Tail control | batchesForceFinalizedCorruptedTotal, batchesForceFinalizedTimeoutTotal | | Pool / I-O | poolExhaustedCount, lastIoErrorKind, busyPollActive, localAddress |

Helpers

  • classifyVariant(byte: number)'DataLegacy' | 'CodeLegacy' | 'DataMerkleUnchained' | 'DataMerkleResigned' | 'CodeMerkleUnchained' | 'CodeMerkleResigned' | null
  • variantProofSize(byte) / variantResigned(byte) / variantMerkleSuffix(byte) — Merkle metadata
  • pinCurrentThreadToCpu(cpuId: number) — Best-effort thread pinning. Linux: sched_setaffinity; macOS: hint; other: no-op

🎯 Use Cases

ShredStream.com shred data powers a wide range of latency-sensitive strategies — HFT, MEV extraction, token sniping, copy trading, liquidation bots, on-chain analytics, and more.

💎 PumpFun Token Sniping

ShredStream.com SDK detects PumpFun token creations ~499ms before they appear on PumpFun's live feed — tested across 25 consecutive detections:

Ready-to-run example included: see examples/pumpfun_creates.ts. Run with npx tsx examples/pumpfun_creates.ts [port].

🏎️ Performance

Two delivery APIs, depending on what your process does between batches.

listener.nextTransactionSync() — MEV-grade hot loop (default in Quick Start)

Synchronous pull. Returns { slot, transactions } | null directly — no Promise allocation, no Buffer.from round-trip, no event-loop hop. Fastest possible delivery.

while (true) {
  const batch = listener.nextTransactionSync();
  if (batch === null) {
    throw new Error(`shredstream listener stopped: ${listener.lastIoErrorKind ?? 'unknown'}`);
  }
  for (const raw of batch.transactions) {
    // synchronous decode + outbound send (e.g. raw-socket, RDMA, etc.)
  }
}

⚠️ Sync mode blocks the libuv event loop while parked on UDP recv. Any other async I/O in this process (dgram.send, HTTP, fs.readFile, setTimeout) will not progress while sync mode is parked. Use sync mode only in a dedicated process or a worker_thread whose only job is to consume shreds. For mixed workloads, switch to for await below.

for await / await listener.nextTransaction() — mixed async workloads

Async-await flow. Compatible with any other Node async I/O (dgram, fs, HTTP clients, timers). The iterator parks on the libuv event loop while waiting on UDP.

for await (const { slot, transactions } of listener) {
  // safe to await other async work here
}

⚙️ Configuration

OS Tuning

# Linux
sudo sysctl -w net.core.rmem_max=67108864
sudo sysctl -w net.core.busy_read=200

# macOS
sudo sysctl -w kern.ipc.maxsockbuf=67108864

🚀 Launch a Shred Stream

Need a feed? Launch a Solana Shred Stream on ShredStream.com — sub-millisecond delivery, multiple global regions, 5-minute setup.

🔗 Links

  • 🌐 Website: https://www.shredstream.com/
  • 📖 Documentation: https://docs.shredstream.com/
  • 🐦 X (Twitter): https://x.com/ShredStream
  • 🎮 Discord: https://discord.gg/4w2DNbTaWD
  • 💬 Telegram: https://t.me/ShredStream
  • 💻 GitHub: https://github.com/ShredStream
  • 🎫 Support: Discord
  • 📊 Benchmarks: Discord

📄 License

MIT — ShredStream.com