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

ringbud

v1.0.22

Published

> A lightweight, high-performance Ring Buffer for streaming data using JavaScript `TypedArray`s.

Readme

RingBud

A lightweight, high-performance Ring Buffer for streaming data using JavaScript TypedArrays.

Features

  • 🧠 Frame-based buffering (configurable frame size)
  • Zero dependencies
  • 🧵 Supports all major TypedArrays (e.g. Float32Array, Uint8Array, etc.)
  • 📦 Memory efficient with optional frame trimming
  • 🔁 Sync & async iteration support
  • Fully tested and predictable behavior
  • 🧰 Customizable preallocation and cache options

Installation

npm install ringbud

Quick Start

import { RingBufferU8 } from "ringbud";

// Create a ring buffer with frame size of 100
const rb = new RingBufferU8(100);

// Write 50 bytes (not enough for a full frame)
rb.write(new Uint8Array(50).fill(1));
console.log(rb.empty()); // true

// Write 50 more bytes (now we have a complete frame)
rb.write(new Uint8Array(50).fill(1));
console.log(rb.empty()); // false

// Read one frame of 100 bytes
const frame = rb.read();
console.log(frame); // Uint8Array(100)

// After reading, it becomes empty again
console.log(rb.empty()); // true

Supported Types

You can instantiate ring buffers for:

  • Uint8ArrayRingBufferU8
  • Uint16ArrayRingBufferU16
  • Float32ArrayRingBufferF32

Each subclass wraps the base RingBufferBase with preconfigured types.


Configuration Options

All constructors accept:

{
  frameSize: number,                // Number of elements per frame (required)
  preallocateFrameCount?: number,  // Default: 10
  frameCacheSize?: number          // Default: 0 (no trim)
}

Frame Cache Size (Clamping)

When frameCacheSize > 0, the ring buffer trims memory usage by shifting unread bytes after every .read(). This reduces buffer growth at the cost of additional memory copying.


API Reference

Constructor

new RingBufferU8(frameSize: number, options?: {
  preallocateFrameCount?: number;
  frameCacheSize?: number;
});

Methods

| Method | Description | |---------------------|-------------| | write(data) | Appends a TypedArray to the buffer | | read() | Returns the next full frame, or null | | drain() | Returns remaining incomplete data | | peek() | Returns the entire buffer content (not a copy) | | empty() | true if no full frame is available | | remainingFrames() | Number of full frames available to read | | rewind() | Resets read offset so frames can be re-read | | Symbol.iterator() | Enables for (const frame of buffer) | | Symbol.asyncIterator() | Enables for await (const frame of buffer) |


Example: Iteration

for (const frame of rb) {
  console.log(frame); // each is a complete frame
}

// or async
for await (const frame of rb) {
  await process(frame);
}

Example: Auto-Trimming

const rb = new RingBufferU8(100, { frameCacheSize: 1 });

rb.write(new Uint8Array(300)); // 3 frames
rb.read();                     // returns 1st frame

// Buffer automatically shifts remaining frames to the front
rb.peek().subarray(0, 200);    // contains frame 2 and 3

Validations & Safety

  • frameSize must be an integer ≥ 1
  • preallocateFrameCount must be ≥ 1 (if set)
  • Partial frames are never returned from .read() or iterators
  • Trimming only occurs after reads when frameCacheSize > 0
  • If iteration is used, all frames are consumed as if .read() was called repeatedly
  • Frames can be shared or copied depending on cache config

TypedArray Support

Internally, the base class accepts any TypedArray constructor:

new RingBufferBase({
  frameSize: 256,
  TypedArrayConstructor: Uint16Array
});

Built-in classes like RingBufferF32 are wrappers over this API.


Examples

Draining Partial Data

const rb = new RingBufferU8(100);

rb.write(new Uint8Array(230));
rb.read();           // reads 1 frame (100 bytes)
rb.read();           // reads 1 more frame (100 bytes)
rb.read();           // null (30 bytes left)

rb.drain();          // returns 30 bytes

Rewind

rb.rewind();         // enables re-reading all written frames
for (const frame of rb) {
  console.log(frame);
}