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

@vjeko.com/azure-blob

v1.0.0

Published

Helper for accessing Azure Storage BLOB functionality from Node.js applications (primarily concerned with Azure Functions)

Downloads

207

Readme

@vjeko.com/azure-blob

npm version License: MIT TypeScript Node.js

A TypeScript wrapper for Azure Blob Storage that simplifies blob operations through an intuitive object-based API. Instead of dealing with low-level Azure SDK calls, clients, streams, and configuration, you work with simple objects that handle all the complexity for you.

Table of Contents

Features

  • Simple API – Read and write blobs with single method calls
  • Type-Safe – Full TypeScript support with generics
  • Multiple Content Types – JSON, string, and binary blob support
  • Container Management – Create, list, and delete containers and blobs
  • Concurrent Access – Built-in optimistic locking with automatic retries
  • Secondary Indexes – Optional indexing for fast lookups
  • Extensible – Easy to create custom blob types

Prerequisites

  • Node.js 22 or higher
  • An Azure Storage account
  • TypeScript 5.0+ (if using TypeScript)

Why Use This Library?

Working directly with the Azure Storage Blob SDK requires managing service clients, container clients, block blob clients, streams, buffers, upload options, and error handling. This library abstracts all of that away:

// Before: Azure SDK directly
const serviceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = serviceClient.getContainerClient("users");
const blobClient = containerClient.getBlockBlobClient("john-doe.json");
const downloadResponse = await blobClient.download();
const content = await streamToBuffer(downloadResponse.readableStreamBody);
const user = JSON.parse(content.toString());

// After: This library
const blob = new Blob<User>("users://john-doe");
const user = await blob.read();

Installation

npm install @vjeko.com/azure-blob

Configuration

Set the Azure Storage connection string as an environment variable:

AZURE_STORAGE_CONNECTION_STRING=<your-connection-string>

Basic Usage

import { Blob } from "@vjeko.com/azure-blob";

interface User {
  name: string;
  email: string;
}

// Create a blob reference using "container://path" format
const userBlob = new Blob<User>("users://john-doe");

// Check existence
const exists = await userBlob.exists();

// Write data
await userBlob.write({ name: "John", email: "[email protected]" });

// Read data
const user = await userBlob.read();

// Read with default value if blob doesn't exist
const userOrDefault = await userBlob.read({ name: "Unknown", email: "" });

// Delete
await userBlob.delete();

// Copy to another location
await userBlob.copyTo("archive://users/john-doe");

Blob Types

The library provides specialized blob classes for different content types:

Blob<T> – JSON Data

The primary class for storing typed objects with automatic JSON serialization.

import { Blob } from "@vjeko.com/azure-blob";

const configBlob = new Blob<AppConfig>("settings://app-config");
await configBlob.write({ theme: "dark", language: "en" });

StringBlob – Plain Text

Stores raw string content without JSON serialization.

import { StringBlob } from "@vjeko.com/azure-blob";

const logBlob = new StringBlob("logs://2024-01-15.txt");
await logBlob.write("Application started at 10:00");

BinaryBlob – Binary Data

Stores binary Buffer data directly for files, images, or other binary content.

import { BinaryBlob } from "@vjeko.com/azure-blob";

const imageBlob = new BinaryBlob("images://photo.png");
await imageBlob.write(imageBuffer);

Container Operations

The BlobContainer class provides container-level operations:

import { BlobContainer } from "@vjeko.com/azure-blob";

const container = new BlobContainer("my-container");

// Create container
await container.createIfNotExists();

// Check existence
const exists = await container.exists();

// List blobs
for await (const blob of container.listBlobPaths("folder/")) {
  console.log(blob.name);
}

// Delete a blob by path
await container.deleteBlobAtPath("folder/file.json");

// Delete the container
await container.delete();

Concurrent Updates

For scenarios where multiple processes may update the same blob, the library provides safe update methods with automatic retry logic:

// Update a blob safely, even with concurrent access
await blob.optimisticUpdate(
  (current) => ({ ...current, counter: current.counter + 1 }),
  { counter: 0 } // default value if blob doesn't exist
);

// Update only if the blob already exists
await blob.optimisticUpdateIfExists(
  (current) => ({ ...current, lastAccess: new Date().toISOString() })
);

Indexed Blobs

For advanced scenarios requiring fast lookups across multiple blobs, IndexedBlob maintains secondary indexes that are automatically updated on writes:

import { IndexedBlob } from "@vjeko.com/azure-blob";

const productBlob = new IndexedBlob<Product>(
  "products://items",
  "sku-12345",
  [["category"], ["category", "inStock"]]
);

await productBlob.write({ name: "Widget", category: "electronics", inStock: true });
const index = await productBlob.readIndex("category");

Extending

Create custom blob types by extending the base Blob<T> class:

import { Blob } from "@vjeko.com/azure-blob";

class EncryptedBlob<T> extends Blob<T> {
  protected override serializeBeforeWrite(data: T): Buffer {
    return encrypt(JSON.stringify(data));
  }

  protected override deserializeAfterRead(content: Buffer): T {
    return JSON.parse(decrypt(content));
  }

  protected override readContent(buffer: Buffer): Buffer {
    return buffer;
  }
}

API Reference

Blob<T>

| Method | Description | |--------|-------------| | exists() | Check if the blob exists | | read(defaultValue?) | Read blob content, optionally with a default value | | readBlob() | Read content along with ETag metadata | | write(data, etag?, overwrite?) | Write data to the blob | | delete(etag?) | Delete the blob | | optimisticUpdate(update, default, timeout?, maxAttempts?) | Safe concurrent update with retries | | optimisticUpdateIfExists(update, timeout?, maxAttempts?) | Update only if blob exists | | copyTo(destination) | Copy blob to a new path |

BlobContainer

| Method | Description | |--------|-------------| | exists() | Check if the container exists | | create(isPublic?) | Create the container | | createIfNotExists(isPublic?) | Create if it doesn't exist | | delete() | Delete the container | | listBlobPaths(prefix) | List blobs matching a prefix | | deleteBlobAtPath(path) | Delete a specific blob |

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please make sure to:

  • Update tests as appropriate
  • Follow the existing code style
  • Update documentation for any new features

Issues

Found a bug or have a feature request? Please open an issue with a clear description.

License

This project is licensed under the MIT License - see the LICENSE file for details.