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

@cloud-cli/storage

v1.19.5

Published

A file bin service for all your quick and easy storage needs.

Readme

File storage service

A file bin service for all your quick and easy storage needs.

API

See api.yaml for API specification.

Usage

With docker

docker pull ghcr.io/cloud-cli/storage:latest
docker run --rm -e ROOT_DIR=/opt/data -e PORT=1234 -v$PWD/data:/opt/data ghcr.io/cloud-cli/storage:latest

See also the release page.

As a standalone server with Node.JS

import start from '@cloud-cli/storage';

process.env.ROOT_DIR = process.cwd() + '/data';
start({ port: 1234 });

As an ESM Module

Consuming it as an ESM module: if the server is running at https://bin.example.com, import it as a module in a project:

import { createBin, createFile, writeFile, readFile } from 'https://bin.example.com/index.mjs';

async function save(content) {
  const { binId } = await createBin();
  const { fileId } = await createFile(binId);

  return await writeFile(binId, fileId, content);
}

const { bin: binId, id: fileId, url } = await save('hello');
const content = await readFile(binId, fileId);
// or directly
const hello = await (await fetch(url)).text();

File metadata names may use slash-separated relative paths (for example, photos/2026/image.jpg). Folder paths are retained when importing or exporting ZIP archives. The web UI also supports selecting and uploading a directory. Bins keep UUID identifiers for URLs and API operations, while the web UI assigns each bin a generated display name that can be renamed without changing its URL.

Public and private bins

Bins created without signing in are public, temporary bins. They are not claimable and are deleted after a period without completed uploads. The timer is reset only when a file upload completes, not when a bin is read or modified. Public bins are limited to 5 MiB per file and 50 completed files.

Sign in before creating a bin to create a private bin. Private bins are owned by the authenticated user and are the basis for future sharing permissions and storage plans. Owned bins can be switched between public and private from the web app. An unclaimed public bin cannot be converted to private, which avoids granting ownership based only on knowledge of a bin ID.

At startup, FileBin imports existing disk bins, committed files, metadata, system metadata, and incomplete upload state into the configured SQLite catalog. Imported bins remain public and unclaimed by default because disk state cannot prove an OIDC owner. New authenticated bins are recorded as owned at creation time. Ownership is stored in the storage_bins catalog.

Schedule POST /admin/cleanup nightly with Authorization: Bearer $PUBLIC_BIN_CLEANUP_TOKEN to remove expired public unclaimed bins. The endpoint returns the deleted bin IDs.

Deleting a bin is a soft delete. DELETE /bin/{binId} marks it for removal after BIN_DELETION_GRACE_HOURS (168 by default); the cleanup scheduler then permanently removes its files and catalog records. The authenticated owner can cancel the deletion with POST /bin/{binId}/restore during that grace period.

Large, resumable uploads

createFile() returns an incomplete upload session. For ordinary uploads, use writeFile() as above. API clients can upload non-overlapping byte ranges in parallel with writeFilePart(binId, fileId, part, start, total). Each part is verified with SHA-256 and is durably recorded; use readUploadStatus() to list received ranges after an interruption, then submit only the missing ranges. The file is not available for download or listing until all bytes from 0 to total - 1 have been received. See api.yaml for the Content-Range and Digest request header contract.

Upload sessions are cleaned up after 72 hours by default. Set UPLOAD_RETENTION_HOURS to change the retention period and UPLOAD_CLEANUP_INTERVAL_MINUTES to change the cleanup interval.

For backup objects, create the file with { immutable: true } metadata. The object remains writable while incomplete, then becomes immutable after commit; replacement and deletion return 409. Completed files expose a lowercase SHA-256 checksum in metadata and as a quoted ETag.

File downloads support single-byte HTTP ranges. Clients can send Range: bytes=<offset>- with If-Range: <ETag> and receive 206 Partial Content. The fbin file download command automatically resumes an existing partial local file when the remote ETag is available.

Command-line client

Install the package globally or run node bin/fbin.mjs. Set FILEBIN_URL once, then use JSON-producing commands that map directly to the API:

export FILEBIN_URL=https://bin.example.com
fbin bin create
fbin file upload <bin-id> ./video.mp4 --concurrency 3
fbin file list <bin-id>
fbin file download <bin-id> <file-id> ./video.mp4
fbin zip download <bin-id> ./archive.zip

fbin file upload creates an upload session and prints its ID to stderr. If interrupted, repeat the command with --file-id <id> and the same source file; the CLI queries received ranges and uploads only missing parts. Use --part-size to control chunk size (8 MiB by default).

Bin management is available through fbin bin list, rename, and delete; file management through file list, info, and delete; and protection through fbin lock status, set, and remove. Pass a password with --password or FILEBIN_PASSWORD; the CLI uses HTTP Basic authentication for protected operations. Prefer FILEBIN_PASSWORD to avoid recording a password in shell history.

Password-protected bins

Protection is opt-in from the bin UI. Locked bins reject all bin, file, metadata, and ZIP operations until unlocked. Browser unlocks use an HttpOnly cookie valid for 12 hours. API clients can instead use HTTP Basic auth with any username and the bin password:

await fetch(`${server}/bin/${binId}`, {
  headers: { authorization: `Basic ${btoa(`api:${password}`)}` },
});

Passwords are stored as salted scrypt hashes. A bin ID remains the management capability, so protect a bin immediately after creating it when this matters.

Environment variables

| env | description | | -------------------------- | ----------------------------------------------------------------------------- | | ROOT_DIR | String. Path to a folder where all data is stored | | PORT | Number. HTTP port | | AUTH_PROVIDER | Required OIDC provider URL | | OIDC_CLIENT_ID | Required OIDC client ID | | OIDC_CLIENT_SECRET | OIDC client secret used at /auth/callback | | DATABASE_URL | Private SQLite-over-HTTPS ESM module URL | | SESSION_SECRET | Shared secret for signing session cookies | | PUBLIC_BIN_RETENTION_HOURS | Public-bin inactivity period after the last completed upload, defaults to 168 | | PUBLIC_BIN_CLEANUP_TOKEN | Bearer token accepted by the external cleanup scheduler endpoint | | BIN_MAX_STORAGE_BYTES | Per-bin storage quota in bytes; unset or 0 displays unlimited storage | | ADMIN_SUBJECTS | Comma-separated OIDC subject IDs allowed to access platform administration |