- @azure/storage-blob (TypeScript/JavaScript)
- SDK for Azure Blob Storage operations — upload, download, list, and manage blobs and containers.
- Installation
- npm
- install
- @azure/storage-blob @azure/identity
- Current Version
-
- 12.x
- Node.js
-
= 18.0.0 Environment Variables AZURE_STORAGE_ACCOUNT_NAME = < account-name
AZURE_STORAGE_ACCOUNT_KEY
< account-key
OR connection string
AZURE_STORAGE_CONNECTION_STRING
DefaultEndpointsProtocol
https
;
AccountName
=
..
.
Authentication
DefaultAzureCredential (Recommended)
import
{
BlobServiceClient
}
from
"@azure/storage-blob"
;
import
{
DefaultAzureCredential
}
from
"@azure/identity"
;
const
accountName
=
process
.
env
.
AZURE_STORAGE_ACCOUNT_NAME
!
;
const
client
=
new
BlobServiceClient
(
https://
${
accountName
}
.blob.core.windows.net
,
new
DefaultAzureCredential
(
)
)
;
Connection String
import
{
BlobServiceClient
}
from
"@azure/storage-blob"
;
const
client
=
BlobServiceClient
.
fromConnectionString
(
process
.
env
.
AZURE_STORAGE_CONNECTION_STRING
!
)
;
StorageSharedKeyCredential (Node.js only)
import
{
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
)
;
SAS Token
import
{
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
}
)
;
Client Hierarchy
BlobServiceClient (account level)
└── ContainerClient (container level)
└── BlobClient (blob level)
├── BlockBlobClient (block blobs - most common)
├── AppendBlobClient (append-only blobs)
└── PageBlobClient (page blobs - VHDs)
Container Operations
Create Container
const
containerClient
=
client
.
getContainerClient
(
"my-container"
)
;
await
containerClient
.
create
(
)
;
// Or create if not exists
await
containerClient
.
createIfNotExists
(
)
;
List Containers
for
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
)
;
}
Delete Container
await
containerClient
.
delete
(
)
;
// Or delete if exists
await
containerClient
.
deleteIfExists
(
)
;
Blob Operations
Upload Blob (Simple)
const
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
)
;
Upload from File (Node.js only)
const
blockBlobClient
=
containerClient
.
getBlockBlobClient
(
"uploaded-file.txt"
)
;
await
blockBlobClient
.
uploadFile
(
"/path/to/local/file.txt"
)
;
Upload from Stream (Node.js only)
import
*
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
)
,
}
)
;
Upload from Browser
const
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
)
;
Download Blob
const
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" ) ; } Download to File (Node.js only) const blockBlobClient = containerClient . getBlockBlobClient ( "my-file.txt" ) ; await blockBlobClient . downloadToFile ( "/path/to/local/destination.txt" ) ; Download to Buffer (Node.js only) const blockBlobClient = containerClient . getBlockBlobClient ( "my-file.txt" ) ; const buffer = await blockBlobClient . downloadToBuffer ( ) ; console . log ( buffer . toString ( ) ) ; List Blobs // 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 }) ; } } Delete Blob const blobClient = containerClient . getBlobClient ( "my-file.txt" ) ; await blobClient . delete ( ) ; // Delete if exists await blobClient . deleteIfExists ( ) ; // Delete with snapshots await blobClient . delete ( { deleteSnapshots : "include" } ) ; Copy Blob const sourceBlobClient = containerClient . getBlobClient ( "source.txt" ) ; const destBlobClient = containerClient . getBlobClient ( "destination.txt" ) ; // Start copy operation const copyPoller = await destBlobClient . beginCopyFromURL ( sourceBlobClient . url ) ; await copyPoller . pollUntilDone ( ) ; Blob Properties & Metadata Get Properties const 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 ) ; Set Metadata await blobClient . setMetadata ( { author : "John Doe" , category : "documents" , } ) ; Set HTTP Headers await blobClient . setHTTPHeaders ( { blobContentType : "text/plain" , blobCacheControl : "max-age=3600" , blobContentDisposition : "attachment; filename=download.txt" , } ) ; SAS Token Generation (Node.js only) Generate Blob SAS import { 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 }; Generate Container SAS import { 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 ( ) ; Generate Account SAS import { 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 ( ) ; Blob Types Block Blob (Default) Most common type for text and binary files. const blockBlobClient = containerClient . getBlockBlobClient ( "document.pdf" ) ; await blockBlobClient . uploadFile ( "/path/to/document.pdf" ) ; Append Blob Optimized for append operations (logs, audit trails). const 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 ) ; Page Blob Fixed-size blobs for random read/write (VHDs). const 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 ) ; Error Handling import { 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 ; } TypeScript Types Reference import { // 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" ; Best Practices Use DefaultAzureCredential — Prefer AAD over connection strings/keys Use streaming for large files — uploadStream / downloadToFile for files > 256MB Set appropriate content types — Use setHTTPHeaders for correct MIME types Use SAS tokens for client access — Generate short-lived tokens for browser uploads Handle errors gracefully — Check RestError.statusCode for specific handling Use *IfNotExists methods — For idempotent container/blob creation Close clients — Not required but good practice in long-running apps Platform Differences Feature Node.js Browser StorageSharedKeyCredential ✅ ❌ uploadFile() ✅ ❌ uploadStream() ✅ ❌ downloadToFile() ✅ ❌ downloadToBuffer() ✅ ❌ uploadData() ✅ ✅ SAS generation ✅ ❌ DefaultAzureCredential ✅ ❌ Anonymous/SAS access ✅ ✅ When to Use This skill is applicable to execute the workflow or actions described in the overview.