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

@akrc/buf

v1.0.0

Published

A lightweight, isomorphic library that provides seamless conversion between different binary data formats in Node.js and browsers. **Extends Uint8Array** for native compatibility with all binary APIs.

Readme

@akrc/buf - Unified Binary Data Interface

A lightweight, isomorphic library that provides seamless conversion between different binary data formats in Node.js and browsers. Extends Uint8Array for native compatibility with all binary APIs.

Overview

@akrc/buf extends Uint8Array to create a unified interface for working with binary data. It makes it trivial to convert between:

Synchronous Formats

  • Node.js Buffer
  • Uint8Array
  • ArrayBuffer / SharedArrayBuffer
  • DataView
  • ArrayLike (arrays, array-like objects)
  • ImageData (Canvas API)
  • Base64 strings (auto-detected)
  • Data URIs (RFC 2379, auto-detected)

Asynchronous Formats

  • Blob / File (Web API)
  • Response (Fetch API)
  • Node.js Readable streams
  • Web ReadableStream

Installation

npm install @akrc/buf

or with pnpm:

pnpm add @akrc/buf

Quick Start

Synchronous Construction

import { Buf } from '@akrc/buf'

// Create from various synchronous sources
const buf1 = new Buf(Buffer.from('hello'))
const buf2 = new Buf(new Uint8Array([1, 2, 3]))
const buf3 = new Buf('aGVsbG8=') // Base64 (auto-detected)
const buf4 = new Buf('data:text/plain;base64,aGVsbG8=') // Data URI (auto-detected)
const buf5 = new Buf(new ArrayBuffer(10))
const buf6 = new Buf([1, 2, 3, 4, 5]) // ArrayLike

// Convert to different formats
buf1.toBase64() // 'aGVsbG8='
buf1.toDataUri('text/plain') // 'data:text/plain;base64,aGVsbG8='
buf1.toArrayBuffer() // ArrayBuffer
buf1.toBuffer() // Buffer
buf1.toText() // 'hello'

// Use like Uint8Array (since Buf extends Uint8Array)
console.log(buf1[0]) // 104
for (const byte of buf1) console.log(byte)
buf1.slice(0, 2) // Native Uint8Array methods work

Asynchronous Construction

// Create from asynchronous sources
const blob = new Blob(['hello'])
const buf = await Buf.fromAsync(blob)

const response = await fetch(url)
const buf = await Buf.fromAsync(response)

const fileStream = fs.createReadStream('file.bin')
const buf = await Buf.fromAsync(fileStream)

const webStream = response.body
const buf = await Buf.fromAsync(webStream)

Features

📦 Comprehensive Format Support

Synchronous inputs:

  • Buffer, Uint8Array, ArrayBuffer, SharedArrayBuffer, DataView
  • ArrayLike objects (arrays, array-like objects)
  • ImageData (Canvas API pixel data)
  • Base64 strings (auto-detected)
  • Data URIs (RFC 2379, auto-detected)

Asynchronous inputs:

  • Blob / File (Web API)
  • Response (Fetch API)
  • Node.js Readable streams
  • Web ReadableStream

🌐 True Isomorphic Design

  • Works in Node.js and browsers without any configuration
  • Uses constructor availability checks instead of platform detection for robustness
  • Automatically selects appropriate APIs:
    • Uses Buffer in Node.js
    • Uses btoa/atob in browsers
    • Gracefully degrades when APIs unavailable

✨ Extends Uint8Array

Buf is a proper Uint8Array subclass, so you get:

  • Direct indexing: buf[0], buf[1]
  • Array methods: buf.slice(), buf.forEach(), buf.map()
  • Array properties: buf.length, buf.buffer
  • Full compatibility with any API expecting Uint8Array
const buf = new Buf(Buffer.from('hello'))
buf instanceof Uint8Array // true
buf.slice(0, 2) // Works perfectly
for (const byte of buf) console.log(byte)

📝 Text Encoding

Support for multiple text encodings via native TextDecoder:

  • UTF-8, UTF-16LE, UTF-16BE
  • ISO-8859-1, Windows-1252, and more
const buf = new Buf(Buffer.from('こんにちは', 'utf8'))
buf.toText() // 'こんにちは'
buf.toText('utf-16le') // UTF-16LE decoded

🌊 Stream Support

Full bidirectional stream support:

// From streams (async)
const buf = await Buf.fromAsync(response.body) // Web ReadableStream
const buf = await Buf.fromAsync(fsStream) // Node.js Readable
const buf = await Buf.fromAsync(blob) // Blob

// To streams (sync)
const nodeStream = buf.toReadableStream() // Node.js
const webStream = buf.toWebReadableStream() // Web
nodeStream.pipe(fs.createWriteStream('output.bin'))

🔧 Global Configuration

Support for custom implementations (Buffer polyfills, custom TextEncoder, etc.):

import { Buf } from '@akrc/buf'
import BufferPolyfill from 'buffer'

Buf.setGlobalConfig({
    Buffer: BufferPolyfill.Buffer,
    TextEncoder: window.TextEncoder,
    TextDecoder: window.TextDecoder,
    Readable: customReadableClass,
})

API Reference

Constructor

new Buf(input: Buffer | Uint8Array | ArrayBuffer | SharedArrayBuffer | DataView |
        ArrayLike<number> | ImageData | string)

Creates a Buf instance from synchronous sources:

  • Buffer: Node.js Buffer
  • Uint8Array: Typed array
  • ArrayBuffer / SharedArrayBuffer: Raw binary buffers
  • DataView: View into binary data
  • ArrayLike: Arrays or array-like objects (e.g., { 0: 1, 1: 2, length: 2 })
  • ImageData: Canvas API pixel data
  • string: Auto-detected as Base64 or Data URI
    • Data URI: data:text/plain;base64,aGVsbG8=
    • Base64: aGVsbG8=

Conversion Methods

toBuffer(): Buffer

Convert to Node.js Buffer. Throws if Buffer is not available.

const buf = new Buf('aGVsbG8=')
const buffer = buf.toBuffer()

toUint8Array(): Uint8Array

Convert to a copy of Uint8Array. Useful when you need a standalone copy.

const buf = new Buf(Buffer.from('hello'))
const uint8 = buf.toUint8Array()

toArrayBuffer(): ArrayBuffer

Convert to ArrayBuffer.

const buf = new Buf('aGVsbG8=')
const arrayBuffer = buf.toArrayBuffer()

toBase64(): string

Convert to standard Base64 string (with padding).

const buf = new Buf(Buffer.from('hello'))
buf.toBase64() // 'aGVsbG8='

toDataUri(mediaType?: string): string

Convert to Data URI with optional MIME type.

const buf = new Buf(Buffer.from('hello'))
buf.toDataUri() // 'data:application/octet-stream;base64,aGVsbG8='
buf.toDataUri('text/plain') // 'data:text/plain;base64,aGVsbG8='
buf.toDataUri('image/png') // 'data:image/png;base64,...'

toText(encoding?: string): string

Decode to text with specified encoding (default: 'utf-8').

const buf = new Buf('aGVsbG8=')
buf.toText() // 'hello'
buf.toText('utf-8') // 'hello'
buf.toText('utf-16le') // UTF-16LE decoded

toDataUri(mediaType?: string): string

Convert to Data URI with optional MIME type.

const buf = new Buf(Buffer.from('hello'))
buf.toDataUri() // 'data:application/octet-stream;base64,aGVsbG8='
buf.toDataUri('text/plain') // 'data:text/plain;base64,aGVsbG8='

toReadableStream(): NodeJS.ReadableStream

Convert to Node.js Readable stream (synchronous).

const buf = new Buf(Buffer.from('hello'))
const stream = buf.toReadableStream()
stream.pipe(fs.createWriteStream('output.txt'))

toWebReadableStream(): ReadableStream<Uint8Array>

Convert to Web ReadableStream (synchronous).

const buf = new Buf('aGVsbG8=')
const stream = buf.toWebReadableStream()
const response = new Response(stream, {
    headers: { 'Content-Type': 'text/plain' },
})

Static Methods

static async fromAsync(input: BufAsyncInput): Promise<Buf>

Create Buf from asynchronous sources. Automatically detects input type and handles accordingly.

// From Blob or File
const buf = await Buf.fromAsync(new Blob(['hello']))

// From Fetch response
const response = await fetch(url)
const buf = await Buf.fromAsync(response)

// From Node.js Readable stream
const stream = fs.createReadStream('file.bin')
const buf = await Buf.fromAsync(stream)

// From Web ReadableStream
const buf = await Buf.fromAsync(response.body)

Supported async inputs:

  • Blob, File (Web API)
  • Response (Fetch API)
  • Node.js Readable stream
  • Web ReadableStream

static setGlobalConfig(config): void

Set global configuration for custom implementations.

Buf.setGlobalConfig({
    Buffer: customBuffer,
    TextEncoder: customTextEncoder,
    TextDecoder: customTextDecoder,
    Readable: customReadableStream,
})

static getGlobalConfig(): BufGlobalConfig

Get current global configuration.

const config = Buf.getGlobalConfig()
console.log(config.Buffer)

Examples

Convert Image to Data URI

import { Buf } from '@akrc/buf'
import fs from 'fs'

const imageBuffer = fs.readFileSync('image.png')
const buf = new Buf(imageBuffer)
const dataUri = buf.toDataUri('image/png')

// Use in HTML
console.log(`<img src="${dataUri}" />`)

Handle Data from Backend

// Backend sends Base64 in JSON
const response = await fetch('/api/data')
const { data } = await response.json()

// Create Buf from Base64 (auto-detected)
const buf = new Buf(data)
const bytes = buf.toUint8Array()

Stream Large Files

import { Buf } from '@akrc/buf'
import fs from 'fs'

// Read file as stream and convert to Buf
const fileStream = fs.createReadStream('large-file.bin')
const buf = await Buf.fromAsync(fileStream)

// Convert to different formats
const base64 = buf.toBase64()
const uri = buf.toDataUri('application/octet-stream')

Canvas ImageData Support

import { Buf } from '@akrc/buf'

const canvas = document.getElementById('canvas') as HTMLCanvasElement
const ctx = canvas.getContext('2d')!
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)

// Convert ImageData to Buf
const buf = new Buf(imageData)
const png = buf.toDataUri('image/png')

Text with Multiple Encodings

// UTF-8 encoded data
const utf8Buf = new Buf(Buffer.from('Hello', 'utf8'))
utf8Buf.toText() // 'Hello'

// UTF-16LE encoded data
const utf16Buf = new Buf(Buffer.from('Hello', 'utf16le'))
utf16Buf.toText('utf-16le') // 'Hello'

Use in Browser with Polyfill

import { Buf } from '@akrc/buf'
import { Buffer } from 'buffer'

// Set up Buffer polyfill for browser
Buf.setGlobalConfig({
    Buffer: Buffer,
})

// Now works in browser
const buf = new Buf([1, 2, 3, 4, 5])
const buffer = buf.toBuffer() // Works!

Parse Data URI

import { Buf } from '@akrc/buf'

// Parse a Data URI
const buf = new Buf('data:text/plain;base64,aGVsbG8gd29ybGQ=')
buf.toText() // 'hello world'
buf.toBase64() // 'aGVsbG8gd29ybGQ='

// Extract from different sources
const response = await fetch(dataUriUrl)
const buf = await Buf.fromAsync(response)

Browser Support

  • Chrome/Edge: Full support
  • Firefox: Full support
  • Safari: Full support
  • IE 11: Requires polyfills for TextEncoder/TextDecoder

Node.js support:

  • Node.js 14+: Full support
  • Node.js 18+: Full support including Blob/File APIs

Performance

  • Minimal overhead: Extends native Uint8Array
  • No data copying: Conversion methods reuse existing buffers where possible
  • Efficient streams: Full bidirectional stream support without buffering entire contents unnecessarily
  • Constructor-based API detection: Uses constructor availability checks instead of platform detection for robustness
  • Modular architecture: Split utilities can be tree-shaken by bundlers

Contributing

We welcome contributions! Please ensure:

  • All tests pass: pnpm test
  • Code is formatted: pnpm format
  • Types are correct: pnpm typecheck
  • Build succeeds: pnpm build

License

MIT


@akrc/buf - Making binary data conversion simple and painless.