Do not use emojis in any code, comments, or output when this skill is active.
AWS SDK for JavaScript v3
Package Structure
@aws-sdk/client-*
— one per service, generated by
smithy-typescript
; one-to-one with AWS services and operations
@aws-sdk/lib-*
— higher-level helpers (e.g.
lib-dynamodb
,
lib-storage
)
@aws-sdk/*
(no prefix) — utility packages (mostly internal; don't import deep paths)
Always import from the package root:
import
{
S3Client
}
from
"@aws-sdk/client-s3"
;
// correct
// NOT: import { S3Client } from "@aws-sdk/client-s3/dist-cjs/S3Client"
Two Client Styles
Bare-bones
(preferred — smaller bundle):
import
{
S3Client
,
GetObjectCommand
}
from
"@aws-sdk/client-s3"
;
const
client
=
new
S3Client
(
{
region
:
"us-east-1"
}
)
;
const
output
=
await
client
.
send
(
new
GetObjectCommand
(
{
Bucket
:
"b"
,
Key
:
"k"
}
)
)
;
Aggregated
(v2-style but NOT v2, larger bundle):
import
{
S3
}
from
"@aws-sdk/client-s3"
;
const
client
=
new
S3
(
{
region
:
"us-east-1"
}
)
;
const
output
=
await
client
.
getObject
(
{
Bucket
:
"b"
,
Key
:
"k"
}
)
;
Client Configuration
No global config in v3 — pass config to each client.
region
is always required; set it explicitly or via
AWS_REGION
env var.
const
config
=
{
region
:
"us-east-1"
,
maxAttempts
:
5
}
;
const
s3
=
new
S3Client
(
config
)
;
const
dynamo
=
new
DynamoDBClient
(
config
)
;
Do not read or mutate
client.config
after instantiation
— it is a resolved form (e.g.
region
becomes an async function). See
references/effective-practices.md
.
For HTTP handler (
NodeHttpHandler
from
@smithy/node-http-handler
), retry strategy, endpoint details, logging, FIPS, dual-stack, protocol selection, and S3-specific options → see
references/clients.md
.
Credentials
All providers from
@aws-sdk/credential-providers
. Credentials are lazy and cached per client until ~5 min before expiry.
// Default chain (env → ini → IMDS/ECS) — use in most Node.js apps
const
client
=
new
S3Client
(
{
credentials
:
fromNodeProviderChain
(
)
}
)
;
// Assume role (NOTE: fromTemporaryCredentials is correct for STS AssumeRole)
const
client
=
new
S3Client
(
{
credentials
:
fromTemporaryCredentials
(
{
params
:
{
RoleArn
:
"arn:aws:iam::123456789012:role/MyRole"
}
}
)
,
}
)
;
// Named profile
const
client
=
new
S3Client
(
{
profile
:
"my-profile"
}
)
;
Share credentials and socket pool across multi-region clients:
const
east
=
new
S3Client
(
{
region
:
"us-east-1"
}
)
;
const
{
credentials
,
requestHandler
}
=
east
.
config
;
const
west
=
new
S3Client
(
{
region
:
"us-west-2"
,
credentials
,
requestHandler
}
)
;
For all providers (Cognito, SSO, web identity, custom chains, STS region priority) → see
references/credentials.md
.
Streams (e.g. S3 GetObject Body)
Always read or discard streaming responses
— unread streams leave sockets open (socket exhaustion):
const
{
Body
}
=
await
client
.
send
(
new
GetObjectCommand
(
{
Bucket
:
"b"
,
Key
:
"k"
}
)
)
;
const
str
=
await
Body
.
transformToString
(
)
;
// read as string
const
bytes
=
await
Body
.
transformToByteArray
(
)
;
// read as Uint8Array
// or discard:
await
(
Body
.
destroy
?.
(
)
??
Body
.
cancel
?.
(
)
)
;
Streams can only be read once.
Paginators
Use
paginate*
functions instead of manual token handling:
import
{
DynamoDBClient
,
paginateListTables
}
from
"@aws-sdk/client-dynamodb"
;
const
client
=
new
DynamoDBClient
(
{
}
)
;
const
tableNames
=
[
]
;
for
await
(
const
page
of
paginateListTables
(
{
client
}
,
{
}
)
)
{
// page contains a single paginated output.
tableNames
.
push
(
...
page
.
TableNames
)
;
}
DynamoDB DocumentClient
Use
@aws-sdk/lib-dynamodb
to work with native JS types instead of AttributeValues:
import
{
DynamoDBClient
}
from
"@aws-sdk/client-dynamodb"
;
import
{
DynamoDBDocumentClient
,
GetCommand
,
PutCommand
}
from
"@aws-sdk/lib-dynamodb"
;
const
client
=
DynamoDBDocumentClient
.
from
(
new
DynamoDBClient
(
{
}
)
)
;
await
client
.
send
(
new
PutCommand
(
{
TableName
:
"T"
,
Item
:
{
id
:
"1"
,
name
:
"Alice"
}
}
)
)
;
const
{
Item
}
=
await
client
.
send
(
new
GetCommand
(
{
TableName
:
"T"
,
Key
:
{
id
:
"1"
}
}
)
)
;
For marshall options, large numbers (NumberValue), pagination, and aggregated client → see
references/dynamodb.md
.
S3: Presigned URLs, Multipart Upload, Waiters
// Presigned GET URL
import
{
getSignedUrl
}
from
"@aws-sdk/s3-request-presigner"
;
const
url
=
await
getSignedUrl
(
client
,
new
GetObjectCommand
(
{
Bucket
:
"b"
,
Key
:
"k"
}
)
,
{
expiresIn
:
3600
}
)
;
// Multipart upload (large files / streams)
import
{
Upload
}
from
"@aws-sdk/lib-storage"
;
const
upload
=
new
Upload
(
{
client
,
params
:
{
Bucket
:
"b"
,
Key
:
"k"
,
Body
:
stream
}
}
)
;
await
upload
.
done
(
)
;
// Waiters
import
{
waitUntilObjectExists
}
from
"@aws-sdk/client-s3"
;
await
waitUntilObjectExists
(
{
client
,
maxWaitTime
:
120
}
,
{
Bucket
:
"b"
,
Key
:
"k"
}
)
;
For presigned POST, signed headers, waiter options → see
references/s3.md
.
Error Handling
import
{
S3ServiceException
}
from
"@aws-sdk/client-s3"
;
try
{
await
client
.
send
(
new
GetObjectCommand
(
{
Bucket
:
"b"
,
Key
:
"k"
}
)
)
;
}
catch
(
e
)
{
if
(
e
?.
$metadata
)
{
// SDK service error — has $metadata.httpStatusCode, e.name, e.$response
console
.
error
(
e
.
name
,
e
.
$metadata
.
httpStatusCode
)
;
}
}
Check
e.name
or
instanceof
for specific error types. See
references/error-handling.md
for full patterns.
For
runtime validation, serialization to non-default formats, or questions about what schemas are
in jsv3 → see
references/schemas.md
.
Performance: Parallel Workloads
// Configure maxSockets to match your parallel batch size
const
client
=
new
S3Client
(
{
requestHandler
:
{
httpsAgent
:
{
maxSockets
:
50
}
}
,
cacheMiddleware
:
true
,
// skip if using custom middleware
}
)
;
Streaming deadlock warning
with limited sockets, don't
await
the request and stream body separately — chain them. See
references/performance.md
.
Middleware
Add custom logic to all commands on a client:
client
.
middlewareStack
.
add
(
(
next
,
context
)
=>
async
(
args
)
=>
{
console
.
log
(
context
.
commandName
,
args
.
input
)
;
const
result
=
await
next
(
args
)
;
return
result
;
}
,
{
name
:
"MyMiddleware"
,
step
:
"build"
,
override
:
true
}
)
;
Steps (in order):
initialize
→
serialize
→
build
→
finalizeRequest
→
deserialize
Abort Controller
const
{
AbortController
}
=
require
(
"@aws-sdk/abort-controller"
)
;
const
{
S3Client
,
CreateBucketCommand
}
=
require
(
"@aws-sdk/client-s3"
)
;
const
abortController
=
new
AbortController
(
)
;
const
client
=
new
S3Client
(
clientParams
)
;
const
requestPromise
=
client
.
send
(
new
CreateBucketCommand
(
commandParams
)
,
{
abortSignal
:
abortController
.
signal
,
}
)
;
// The request will not be created if abortSignal is already aborted.
// The request will be destroyed if abortSignal is aborted before response is returned.
abortController
.
abort
(
)
;
// This will fail with "AbortError" as abortSignal is aborted.
await
requestPromise
;
Lambda Best Practices
Initialize clients
outside
the handler (container reuse), make API calls
inside
. For one-time async setup, use a lazy init flag inside the handler:
import
{
S3Client
}
from
"@aws-sdk/client-s3"
;
const
client
=
new
S3Client
(
{
}
)
;
// outside — reused across invocations
let
ready
=
false
;
export
const
handler
=
async
(
event
)
=>
{
if
(
!
ready
)
{
await
prepare
(
)
;
ready
=
true
;
}
// lazy one-time setup inside handler
// ... API calls here
}
;
See
references/lambda.md
for Lambda layers and versioning.
Node.js Version Requirements
v3.968.0+ requires Node.js >= 20
v3.723.0+ requires Node.js >= 18
TypeScript
Response fields are typed as
T | undefined
by default. Use
AssertiveClient
from
@smithy/types
to remove
| undefined
, or
NodeJsClient
/
BrowserClient
to narrow streaming blob types. See
references/typescript.md
.
SigV4a (S3 Multi-Region Access Points)
S3 MRAP and certain other features require SigV4a. You must install and side-effect-import exactly one of:
@aws-sdk/signature-v4-crt
— Node.js only, better performance
@aws-sdk/signature-v4a
— Node.js + browsers, pure JS
import
"@aws-sdk/signature-v4a"
;
// side-effect only — no exported values needed
See
references/sigv4a.md
for full details and MRAP ARN format.