Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Azure Blob Storage JavaScript/TypeScript SDK (@azure/storage-blob) for blob operations. Use for uploading, downloading, listing, and managing blobs and containers. Supports block blobs, append blobs, page blobs, SAS tokens, and streaming. Triggers: "blob storage", "@azure/storage-blob", "BlobServiceClient", "ContainerClient", "upload blob", "download blob", "SAS token", "block blob".
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-20 | ✗→✓ | ▲ Improved | 196% | 0% |
| case-19 | ✓→✓ | = Same ✓ | 125% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 190% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 122% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 149% | 0% |
SDK for Azure Blob Storage operations — upload, download, list, and manage blobs and containers.
bashnpm install @azure/storage-blob @azure/identity
Current Version: 12.x Node.js: >= 18.0.0
bashAZURE_STORAGE_ACCOUNT_NAME=<account-name> AZURE_STORAGE_ACCOUNT_KEY=<account-key> # OR connection string AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=... AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
typescriptimport { BlobServiceClient } from "@azure/storage-blob"; import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity"; // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}); // Or use a specific credential directly in production: // See https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes // const credential = new ManagedIdentityCredential(); const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!; const client = new BlobServiceClient( `https://${accountName}.blob.core.windows.net`, credential );
typescriptimport { BlobServiceClient } from "@azure/storage-blob"; const client = BlobServiceClient.fromConnectionString( process.env.AZURE_STORAGE_CONNECTION_STRING! );
typescriptimport { BlobServiceClient, StorageSharedKeyCredential } from "@azure/storage-blob"; const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!; const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY!; const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey); const client = new BlobServiceClient( `https://${accountName}.blob.core.windows.net`, sharedKeyCredential );
typescriptimport { BlobServiceClient } from "@azure/storage-blob"; const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!; const sasToken = process.env.AZURE_STORAGE_SAS_TOKEN!; // starts with "?" const client = new BlobServiceClient( `https://${accountName}.blob.core.windows.net${sasToken}` );
BlobServiceClient (account level)
└── ContainerClient (container level)
└── BlobClient (blob level)
├── BlockBlobClient (block blobs - most common)
├── AppendBlobClient (append-only blobs)
└── PageBlobClient (page blobs - VHDs)typescriptconst containerClient = client.getContainerClient("my-container"); await containerClient.create(); // Or create if not exists await containerClient.createIfNotExists();
typescriptfor await (const container of client.listContainers()) { console.log(container.name); } // With prefix filter for await (const container of client.listContainers({ prefix: "logs-" })) { console.log(container.name); }
typescriptawait containerClient.delete(); // Or delete if exists await containerClient.deleteIfExists();
typescriptconst containerClient = client.getContainerClient("my-container"); const blockBlobClient = containerClient.getBlockBlobClient("my-file.txt"); // Upload string await blockBlobClient.upload("Hello, World!", 13); // Upload Buffer const buffer = Buffer.from("Hello, World!"); await blockBlobClient.upload(buffer, buffer.length);
typescriptconst blockBlobClient = containerClient.getBlockBlobClient("uploaded-file.txt"); await blockBlobClient.uploadFile("/path/to/local/file.txt");
typescriptimport * as fs from "fs"; const blockBlobClient = containerClient.getBlockBlobClient("streamed-file.txt"); const readStream = fs.createReadStream("/path/to/local/file.txt"); await blockBlobClient.uploadStream(readStream, 4 * 1024 * 1024, 5, { // bufferSize: 4MB, maxConcurrency: 5 onProgress: (progress) => console.log(`Uploaded ${progress.loadedBytes} bytes`), });
typescriptconst blockBlobClient = containerClient.getBlockBlobClient("browser-upload.txt"); // From File input const fileInput = document.getElementById("fileInput") as HTMLInputElement; const file = fileInput.files![0]; await blockBlobClient.uploadData(file); // From Blob/ArrayBuffer const arrayBuffer = new ArrayBuffer(1024); await blockBlobClient.uploadData(arrayBuffer);
typescriptconst blobClient = containerClient.getBlobClient("my-file.txt"); const downloadResponse = await blobClient.download(); // Read as string (browser & Node.js) const downloaded = await streamToText(downloadResponse.readableStreamBody!); async function streamToText(readable: NodeJS.ReadableStream): Promise<string> { const chunks: Buffer[] = []; for await (const chunk of readable) { chunks.push(Buffer.from(chunk)); } return Buffer.concat(chunks).toString("utf-8"); }
typescriptconst blockBlobClient = containerClient.getBlockBlobClient("my-file.txt"); await blockBlobClient.downloadToFile("/path/to/local/destination.txt");
typescriptconst blockBlobClient = containerClient.getBlockBlobClient("my-file.txt"); const buffer = await blockBlobClient.downloadToBuffer(); console.log(buffer.toString());
typescript// List all blobs for await (const blob of containerClient.listBlobsFlat()) { console.log(blob.name, blob.properties.contentLength); } // List with prefix for await (const blob of containerClient.listBlobsFlat({ prefix: "logs/" })) { console.log(blob.name); } // List by hierarchy (virtual directories) for await (const item of containerClient.listBlobsByHierarchy("/")) { if (item.kind === "prefix") { console.log(`Directory: ${item.name}`); } else { console.log(`Blob: ${item.name}`); } }
typescriptconst blobClient = containerClient.getBlobClient("my-file.txt"); await blobClient.delete(); // Delete if exists await blobClient.deleteIfExists(); // Delete with snapshots await blobClient.delete({ deleteSnapshots: "include" });
typescriptconst sourceBlobClient = containerClient.getBlobClient("source.txt"); const destBlobClient = containerClient.getBlobClient("destination.txt"); // Start copy operation const copyPoller = await destBlobClient.beginCopyFromURL(sourceBlobClient.url); await copyPoller.pollUntilDone();
typescriptconst blobClient = containerClient.getBlobClient("my-file.txt"); const properties = await blobClient.getProperties(); console.log("Content-Type:", properties.contentType); console.log("Content-Length:", properties.contentLength); console.log("Last Modified:", properties.lastModified); console.log("ETag:", properties.etag);
typescriptawait blobClient.setMetadata({ author: "John Doe", category: "documents", });
typescriptawait blobClient.setHTTPHeaders({ blobContentType: "text/plain", blobCacheControl: "max-age=3600", blobContentDisposition: "attachment; filename=download.txt", });
typescriptimport { BlobSASPermissions, generateBlobSASQueryParameters, StorageSharedKeyCredential, } from "@azure/storage-blob"; const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey); const sasToken = generateBlobSASQueryParameters( { containerName: "my-container", blobName: "my-file.txt", permissions: BlobSASPermissions.parse("r"), // read only startsOn: new Date(), expiresOn: new Date(Date.now() + 3600 * 1000), // 1 hour }, sharedKeyCredential ).toString(); const sasUrl = `https://${accountName}.blob.core.windows.net/my-container/my-file.txt?${sasToken}`;
typescriptimport { ContainerSASPermissions, generateBlobSASQueryParameters } from "@azure/storage-blob"; const sasToken = generateBlobSASQueryParameters( { containerName: "my-container", permissions: ContainerSASPermissions.parse("racwdl"), // read, add, create, write, delete, list expiresOn: new Date(Date.now() + 24 * 3600 * 1000), // 24 hours }, sharedKeyCredential ).toString();
typescriptimport { AccountSASPermissions, AccountSASResourceTypes, AccountSASServices, generateAccountSASQueryParameters, } from "@azure/storage-blob"; const sasToken = generateAccountSASQueryParameters( { services: AccountSASServices.parse("b").toString(), // blob resourceTypes: AccountSASResourceTypes.parse("sco").toString(), // service, container, object permissions: AccountSASPermissions.parse("rwdlacupi"), // all permissions expiresOn: new Date(Date.now() + 24 * 3600 * 1000), }, sharedKeyCredential ).toString();
Most common type for text and binary files.
typescriptconst blockBlobClient = containerClient.getBlockBlobClient("document.pdf"); await blockBlobClient.uploadFile("/path/to/document.pdf");
Optimized for append operations (logs, audit trails).
typescriptconst appendBlobClient = containerClient.getAppendBlobClient("app.log"); // Create the append blob await appendBlobClient.create(); // Append data await appendBlobClient.appendBlock("Log entry 1\n", 12); await appendBlobClient.appendBlock("Log entry 2\n", 12);
Fixed-size blobs for random read/write (VHDs).
typescriptconst pageBlobClient = containerClient.getPageBlobClient("disk.vhd"); // Create 512-byte aligned page blob await pageBlobClient.create(1024 * 1024); // 1MB // Write pages (must be 512-byte aligned) const buffer = Buffer.alloc(512); await pageBlobClient.uploadPages(buffer, 0, 512);
typescriptimport { RestError } from "@azure/storage-blob"; try { await containerClient.create(); } catch (error) { if (error instanceof RestError) { switch (error.statusCode) { case 404: console.log("Container not found"); break; case 409: console.log("Container already exists"); break; case 403: console.log("Access denied"); break; default: console.error(`Storage error ${error.statusCode}: ${error.message}`); } } throw error; }
typescriptimport { // Clients BlobServiceClient, ContainerClient, BlobClient, BlockBlobClient, AppendBlobClient, PageBlobClient, // Authentication StorageSharedKeyCredential, AnonymousCredential, // SAS BlobSASPermissions, ContainerSASPermissions, AccountSASPermissions, AccountSASServices, AccountSASResourceTypes, generateBlobSASQueryParameters, generateAccountSASQueryParameters, // Options & Responses BlobDownloadResponseParsed, BlobUploadCommonResponse, ContainerCreateResponse, BlobItem, ContainerItem, // Errors RestError, } from "@azure/storage-blob";
DefaultAzureCredential for local development; use ManagedIdentityCredential or WorkloadIdentityCredential for productionuploadStream/downloadToFile for files > 256MBsetHTTPHeaders for correct MIME typesRestError.statusCode for specific handling*IfNotExists methods — For idempotent container/blob creation| Feature | Node.js | Browser | |---------|---------|---------| | StorageSharedKeyCredential | ✅ | ❌ | | uploadFile() | ✅ | ❌ | | uploadStream() | ✅ | ❌ | | downloadToFile() | ✅ | ❌ | | downloadToBuffer() | ✅ | ❌ | | uploadData() | ✅ | ✅ | | SAS generation | ✅ | ❌ | | DefaultAzureCredential | ✅ | ❌ | | Anonymous/SAS access | ✅ | ✅ |
Other measured skills in the registry, with their headline benchmark lift.