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

node-catbox

v6.0.0

Published

A library for interacting with Catbox.moe written in TypeScript.

Readme

This library aims to be a sort of successor to https://www.npmjs.com/package/catbox.moe.

Features

  • Catbox uploads by file path, direct URL, and stream
  • Litterbox uploads by file path and stream with configurable lifetime
  • Catbox album management (create, edit, add/remove files, delete)
  • Native EventEmitter events
  • Built-in timeouts and optional retries for transient HTTP errors

Requirements

  • >= Node.js 24

Installation

npm i node-catbox
yarn add node-catbox
bun add node-catbox

Usage

Request timeouts

The timeout covers the complete upload and response transfer for each attempt. Catbox defaults to 5 minutes and Litterbox defaults to 30 minutes because Litterbox accepts substantially larger files. Override either default when needed:

const catbox = new Catbox(undefined, { requestTimeoutMs: 10 * 60_000 });
const litterbox = new Litterbox({ requestTimeoutMs: 60 * 60_000 });

Requests are not retried by default: even an HTTP gateway error can occur after an upload or album mutation has completed remotely. If your application accepts the possibility of duplicate operations, explicitly enable up to two retries with retryTransientErrors: true in either client's constructor options. Transport failures are never automatically retried. Enabled retries honor Retry-After seconds or HTTP dates, with exponential backoff as a minimum. If the server requests a wait longer than requestTimeoutMs, the call fails instead of retrying early.

Response bodies are limited to 64 KiB by default, including decompressed HTTP error bodies. Set maxResponseBytes in the constructor options to change this limit.

Cancelling an operation

Every upload and album/file management method accepts an optional signal. It cancels stream staging, HTTP transfer, and retry waits. Use AbortSignal.timeout(...) for an overall deadline in addition to the per-attempt HTTP timeout:

await catbox.uploadFileStream({
    stream,
    filename: 'file.ext',
    signal: AbortSignal.timeout(60_000)
});

Cancellation removes staged temporary files. An arbitrary source iterator may continue its own work if it ignores cancellation; the client stops awaiting it. Cancellation cannot undo a mutation already applied by the server.

Uploading to Catbox

import { Catbox } from 'node-catbox';

const catbox = new Catbox();

try {
	const response = await catbox.uploadFile({
		path: '/path/to/my/file.ext',
		// NEW in v4.2.0 (optional)
		// default: 200 * 1024 * 1024 (200 MB)
		maxFileBytes: 200 * 1024 * 1024
	});
	// or to upload from direct file URL
	const response = await catbox.uploadURL({
		url: 'https://i.imgur.com/8rR6IZn.png'
	});

	console.log(response); // -> https://files.catbox.moe/XXXXX.ext
} catch (err) {
	console.error(err); // -> error message from server
}

// ---

// NEW in v3.4.0

const stream = createReadStream('/path/to/my/file.ext');
await catbox.uploadFileStream({
	stream,
	filename: 'file.ext',
	// NEW in v4.2.0 (optional)
	// default: 200 * 1024 * 1024 (200 MB)
	maxStreamBytes: 200 * 1024 * 1024
});

Choosing a file path or stream

Prefer uploadFile({ path }) when the file already exists on disk. It uploads directly from a file-backed Blob. uploadFileStream first stages the entire input in a temporary file so it can validate the size before sending and replay the body when retries are enabled. Staging adds a full disk write and read, requires temporary disk space, and delays the HTTP request until the source ends.

Use the stream method for sources without a file path, and provide a signal to bound the time spent waiting for input. Staging keeps memory use independent of the total upload size.

User Hash

Some operations require your account's user hash which can be set on instantiation with

const catbox = new Catbox('098f6bcd4621d373cade4e832');

... or later with

const catbox = new Catbox();

catbox.setUserHash('098f6bcd4621d373cade4e832');

Deleting Files

import { Catbox } from 'node-catbox';

// user hash required
const catbox = new Catbox('098f6bcd4621d373cade4e832');

await catbox.deleteFiles({
	files: ['XXXXX.ext']
});

Creating an album

import { Catbox } from 'node-catbox';

// user hash only required if you plan to edit or delete the album later
const catbox = new Catbox('098f6bcd4621d373cade4e832');

const albumURL = await catbox.createAlbum({
	title: 'album title',
	description: 'album description',
	files: ['XXXXX.ext'] // optional
});

Editing an album

import { Catbox } from 'node-catbox';

// user hash required
const catbox = new Catbox('098f6bcd4621d373cade4e832');

await catbox.editAlbum({
	id: 'YYYYY',
	title: 'new title',
	description: 'new description',
	files:  ['WWWWW.ext', 'VVVVV.ext'] // optional
});

Warning This is a potentially destructive method where values are applied to the album directly. Consider using the method below if you are only adding/removing files from an album.

Adding and removing files from an album

import { Catbox } from 'node-catbox';

// user hash required
const catbox = new Catbox('098f6bcd4621d373cade4e832');

await catbox.addFilesToAlbum({
	id: 'YYYYY',
	files: ['ZZZZZ.ext']
});
await catbox.removeFilesFromAlbum({
	id: 'YYYYY',
	files: ['ZZZZZ.ext']
});

Deleting an album

import { Catbox } from 'node-catbox';

// user hash required
const catbox = new Catbox('098f6bcd4621d373cade4e832');

await catbox.removeAlbum({
	id: 'YYYYY'
});

Uploading to Litterbox

import { Litterbox } from 'node-catbox';

const litterbox = new Litterbox();

await litterbox.uploadFile({
	path: '/path/to/my/file.ext',
	duration: '12h', // or omit to default to 1h
	// NEW in v4.1.0 (optional)
	// FileNameLength.Six | FileNameLength.Sixteen
	fileNameLength: 16,
	// NEW in v4.2.0 (optional)
	// default: 1024 * 1024 * 1024 (1 GB)
	maxFileBytes: 1024 * 1024 * 1024
});

// ---

import { FileLifetime } from 'node-catbox';

// Using an enum for duration
await litterbox.uploadFile({
	path: '/path/to/my/file.ext',
	duration: FileLifetime.TwelveHours
});

// ---

// NEW in v3.4.0

const stream = createReadStream('/path/to/my/file.ext');
await litterbox.uploadFileStream({
	stream,
	filename: 'file.ext'
});

// ---

// NEW in v4.1.0

import { FileNameLength } from 'node-catbox';

// Using an enum for file name length
await litterbox.uploadFile({
	path: '/path/to/my/file.ext',
	fileNameLength: FileNameLength.Sixteen
});

Events

As of v4.0.0, both Catbox and Litterbox emit a request and response event as well as events specific to each class:

import { Catbox, Litterbox } from 'node-catbox';

const catbox    = new Catbox();
const litterbox = new Litterbox();

// `request` is a sanitized read-only snapshot (no raw body)
catbox.on('request', request => console.log(request.method, request.hasBody));
// `response` is a read-only snapshot
catbox.on('response', response => console.log(`${response.status} - ${response.statusText}`));

litterbox.on('uploadingFile', (filepath, duration) => console.log('Uploading file', filepath, 'with a duration of', duration));

As of v4.2.0, request snapshots are explicitly sanitized and do not expose raw request body data (including any userhash values).

Catbox-specific events:

  • uploadingURL
  • uploadingFile
  • uploadingStream
  • deletingFiles
  • creatingAlbum
  • editingAlbum
  • addingFilesToAlbum
  • removingFilesFromAlbum
  • removingAlbum

Litterbox-specific events:

  • uploadingFile
  • uploadingStream

Testing

By default, network-dependent integration tests are skipped to avoid flaky failures and rate limits.

  • Run default deterministic test suite (no Catbox account required): yarn test
  • Run full suite including live integration tests:
    • Create a .env file in the project root with USER_HASH=<your_catbox_user_hash>
    • Run with RUN_INTEGRATION_TESTS=1