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

@nuvix/storage

v1.0.1

Published

S3-compatible storage library for Nuvix BaaS platform with support for AWS S3, Wasabi, MinIO, and local storage

Readme

@nuvix/storage

A powerful, TypeScript-first S3-compatible storage library for the Nuvix BaaS platform. Supports multiple storage backends including local filesystem, AWS S3, Wasabi, and MinIO with a unified API.

✨ Features

  • 🚀 S3-Compatible API - Consistent interface across all storage providers
  • 🔌 Multiple Storage Backends - Local, AWS S3, Wasabi, MinIO, and more
  • 📝 TypeScript First - Full type safety with comprehensive TypeScript definitions
  • File Validation - Built-in validators for file types, sizes, names, and extensions
  • 🔄 Chunked Uploads - Support for large file uploads with multipart upload
  • 🌐 Modern Builds - ESM and CommonJS support for maximum compatibility
  • 🧪 Well Tested - Comprehensive test suite with real implementation testing

📦 Installation

# Using npm
npm install @nuvix/storage

# Using yarn
yarn add @nuvix/storage

# Using pnpm
pnpm add @nuvix/storage

# Using bun
bun add @nuvix/storage

🚀 Quick Start

ESM (Modern)

import {
  Storage,
  Local,
  Wasabi,
  MinIO,
  FileExt,
  FileSize,
} from "@nuvix/storage";

// Set up local storage
const localStorage = new Local("./uploads");
Storage.setDevice(Storage.DEVICE_LOCAL, localStorage);

// Upload a file
const localDevice = Storage.getDevice(Storage.DEVICE_LOCAL);
await localDevice.write("test.txt", "Hello, World!", "text/plain");

CommonJS (Legacy)

const { Storage, Local, Wasabi, MinIO } = require("@nuvix/storage");

// Set up local storage
const localStorage = new Local("./uploads");
Storage.setDevice(Storage.DEVICE_LOCAL, localStorage);

🔧 Storage Devices

Local File System

import { Local, Storage } from "@nuvix/storage";

const localStorage = new Local("./uploads");
Storage.setDevice("local", localStorage);

// Write file
await localStorage.write("documents/file.txt", "content", "text/plain");

// Read file
const content = await localStorage.read("documents/file.txt");

// Check if file exists
const exists = await localStorage.exists("documents/file.txt");

Wasabi Cloud Storage

import { Wasabi, Storage } from "@nuvix/storage";

const wasabiStorage = new Wasabi(
  "my-app-uploads", // root path
  "your-access-key", // access key
  "your-secret-key", // secret key
  "your-bucket-name", // bucket name
  Wasabi.US_CENTRAL_1, // region
  Wasabi.ACL_PRIVATE, // ACL (optional)
);

Storage.setDevice("wasabi", wasabiStorage);

// Upload with metadata
await wasabiStorage.uploadData(
  "Hello, Cloud!",
  "cloud-file.txt",
  "text/plain",
  1,
  1,
  { author: "user123" },
);

AWS S3

import { S3, Storage } from "@nuvix/storage";

const s3Storage = new S3(
  "my-app-uploads", // root path
  "your-access-key", // access key
  "your-secret-key", // secret key
  "your-bucket-name", // bucket name
  S3.US_EAST_1, // region
  S3.ACL_PRIVATE, // ACL (optional)
);

Storage.setDevice("s3", s3Storage);

MinIO

import { MinIO, Storage } from "@nuvix/storage";

const minioStorage = new MinIO(
  "my-app-uploads", // root path
  "minioadmin", // access key (default MinIO credentials)
  "minioadmin", // secret key (default MinIO credentials)
  "your-bucket-name", // bucket name
  "localhost:9000", // MinIO endpoint
  MinIO.ACL_PRIVATE, // ACL (optional)
  false, // useSSL (optional, default: false)
);

Storage.setDevice("minio", minioStorage);

// Upload to MinIO
await minioStorage.write("local-file.txt", "Hello, MinIO!", "text/plain");

// Read from MinIO
const content = await minioStorage.read("local-file.txt");

// Check if file exists
const exists = await minioStorage.exists("local-file.txt");

// Get file information
const size = await minioStorage.getFileSize("local-file.txt");
const mimeType = await minioStorage.getFileMimeType("local-file.txt");

🛡️ File Validation

File Extension Validation

import { FileExt } from "@nuvix/storage";

const imageValidator = new FileExt(["jpg", "png", "gif", "webp"]);

console.log(imageValidator.isValid("photo.jpg")); // true
console.log(imageValidator.isValid("document.pdf")); // false

File Size Validation

import { FileSize } from "@nuvix/storage";

const sizeValidator = new FileSize(5 * 1024 * 1024); // 5MB limit

console.log(sizeValidator.isValid(1024 * 1024)); // true (1MB)
console.log(sizeValidator.isValid(10 * 1024 * 1024)); // false (10MB)

File Name Validation

import { FileName } from "@nuvix/storage";

const nameValidator = new FileName();

console.log(nameValidator.isValid("validfile123.txt")); // true
console.log(nameValidator.isValid("invalid-file.txt")); // false (contains hyphen)

File Type (MIME) Validation

import { FileType } from "@nuvix/storage";

const typeValidator = new FileType(["jpeg", "png", "gif"]);

// Validates based on file content, not extension
console.log(await typeValidator.isValid("./image.jpg")); // true if actual JPEG

Upload File Validation

import { Upload } from "@nuvix/storage";

const uploadValidator = new Upload();

console.log(await uploadValidator.isValid("./existing-file.txt")); // true
console.log(await uploadValidator.isValid("./non-existent.txt")); // false

🔄 Advanced Features

Chunked Uploads

// Upload large files in chunks
const chunks = ["chunk1", "chunk2", "chunk3"];
const metadata = {};

for (let i = 0; i < chunks.length; i++) {
  await device.uploadData(
    chunks[i],
    "large-file.txt",
    "text/plain",
    i + 1, // current chunk
    chunks.length, // total chunks
    metadata,
  );
}

File Transfer Between Devices

const sourceDevice = Storage.getDevice("local");
const targetDevice = Storage.getDevice("wasabi");

// Transfer file from local to cloud
await sourceDevice.transfer("local-file.txt", "cloud-file.txt", targetDevice);

Human-Readable File Sizes

import { Storage } from "@nuvix/storage";

console.log(Storage.human(1024)); // "1.00kB"
console.log(Storage.human(1048576)); // "1.00MB"
console.log(Storage.human(1024, 2, "binary")); // "1.00KiB"

🏗️ Building

The library is built using Rollup and provides both ESM and CommonJS outputs:

# Build for production
bun run build

# Build and watch for changes
bun run build:watch

# Clean build directory
bun run clean

🧪 Testing

Comprehensive test suite with real implementation testing:

# Run all tests
bun test

# Run tests in watch mode
bun run test:watch

# Run tests with coverage
bun run test:coverage

# Run specific test files
bun test storage.test.ts
bun test device/
bun test validator/

Testing with Real Cloud Storage

Set environment variables to test against real storage services:

# For Wasabi testing
export WASABI_ACCESS_KEY="your-access-key"
export WASABI_SECRET_KEY="your-secret-key"
export WASABI_BUCKET="your-test-bucket"

# For AWS S3 testing
export AWS_ACCESS_KEY="your-access-key"
export AWS_SECRET_KEY="your-secret-key"
export AWS_BUCKET="your-test-bucket"

# For MinIO testing
export MINIO_ACCESS_KEY="minioadmin"
export MINIO_SECRET_KEY="minioadmin"
export MINIO_BUCKET="test-bucket"
export MINIO_ENDPOINT="localhost:9000"

📝 API Reference

Storage Class

  • Storage.setDevice(name, device) - Register a storage device
  • Storage.getDevice(name) - Get a registered storage device
  • Storage.exists(name) - Check if a device is registered
  • Storage.human(bytes, decimals?, system?) - Format bytes to human-readable string

Device Interface

All storage devices implement the same interface:

  • upload(source, path, chunk?, chunks?, metadata?) - Upload file
  • uploadData(data, path, contentType, chunk?, chunks?, metadata?) - Upload data
  • read(path, offset?, length?) - Read file content
  • write(path, data, contentType) - Write file
  • delete(path, recursive?) - Delete file/directory
  • exists(path) - Check if file exists
  • getFileSize(path) - Get file size
  • getFileMimeType(path) - Get file MIME type
  • getFileHash(path) - Get file MD5 hash
  • transfer(source, destination, targetDevice) - Transfer file

🌍 Browser Support

This library is designed for Node.js environments. For browser usage, you'll need to provide polyfills for Node.js modules or use a bundler that can handle Node.js dependencies.

🤝 Contributing

Contributions are welcome! Please read our contributing guidelines and ensure all tests pass:

bun run lint        # Check code style
bun run lint:fix    # Fix code style issues
bun test           # Run test suite

📄 License

MIT © Nuvix

🔗 Links