Skip to main content
The Document Client simplifies working with Amazon DynamoDB by abstracting away AttributeValue shapes. Instead of wrapping every value in a type descriptor like { S: "hello" }, you pass plain JavaScript objects and the client handles marshalling and unmarshalling automatically.

Installation

npm install @aws-sdk/lib-dynamodb @aws-sdk/client-dynamodb

Type mapping

The Document Client maps between native JavaScript types and DynamoDB AttributeValue shapes:
JavaScript typeDynamoDB AttributeValue
StringS
Number / BigInt / NumberValueN
BooleanBOOL
nullNULL
ArrayL
ObjectM
Set<Uint8Array, Blob, …>BS
Set<Number, BigInt, NumberValue>NS
Set<String>SS
Uint8Array, Buffer, File, BlobB
For example, the following raw DynamoDB list value:
{ "L": [{ "NULL": true }, { "BOOL": false }, { "N": 1 }, { "S": "two" }] }
Is represented by the Document Client as a plain JavaScript array:
[null, false, 1, "two"]

Creating the Document Client

First create a DynamoDBClient, then wrap it with DynamoDBDocumentClient.from():
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
Use DynamoDBDocumentClient (bare-bones) for smaller bundle sizes. Use DynamoDBDocument (full client) if you prefer calling methods like docClient.put() directly instead of sending Command objects.
Alternatively, use the full document client:
import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDB({});
const docClient = DynamoDBDocument.from(client);

// Call operations directly as methods
await docClient.put({
  TableName: "MyTable",
  Item: {
    id: "2",
    content: "content from DynamoDBDocument",
  },
});

Available commands

The following commands are available for use with DynamoDBDocumentClient:
  • GetCommand
  • PutCommand
  • DeleteCommand
  • UpdateCommand
  • QueryCommand
  • ScanCommand
  • BatchGetCommand
  • BatchWriteCommand
  • TransactGetCommand
  • TransactWriteCommand

Examples

Writing an item with PutCommand

import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb";

const docClient = DynamoDBDocumentClient.from(client);

await docClient.send(
  new PutCommand({
    TableName: "MyTable",
    Item: {
      id: "1",
      content: "content from DynamoDBDocumentClient",
    },
  })
);

Scanning a table with pagination

Use the built-in paginator for full table scans:
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, paginateScan, ScanCommand } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({ region: "us-west-2" });
const docClient = DynamoDBDocumentClient.from(client);

const paginatorConfiguration = { client: docClient };

// The input is wrapped in a function to avoid mutation across pages
const scanRequestInput = () => ({
  TableName: "YOUR_TABLE_NAME",
  Limit: 100,
});

let pageNumber = 1;
for await (const page of paginateScan(paginatorConfiguration, scanRequestInput())) {
  console.log("page:", pageNumber++);
  console.log(page.Items);
}
You can also handle pagination manually using the LastEvaluatedKey token:
const firstPage = await docClient.send(new ScanCommand(scanRequestInput()));
let paginationToken = firstPage.LastEvaluatedKey;

while (paginationToken) {
  const page = await docClient.send(
    new ScanCommand({
      ...scanRequestInput(),
      ExclusiveStartKey: paginationToken,
    })
  );
  paginationToken = page.LastEvaluatedKey;
  console.log(page.Items);
}
Before performing a full table scan, consider whether BatchGetItem or a Query would be more efficient.

Marshalling options

Pass a translateConfig object as the second argument to DynamoDBDocumentClient.from() to control how values are marshalled and unmarshalled.
const marshallOptions = {
  // Convert empty strings, blobs, and sets to null
  convertEmptyValues: false,
  // Remove undefined values from objects and arrays
  removeUndefinedValues: false,
  // Convert plain objects (class instances) to DynamoDB map attributes
  convertClassInstanceToMap: false,
  // Allow numbers beyond Number.MAX_SAFE_INTEGER (may lose precision)
  allowImpreciseNumbers: false,
};

const unmarshallOptions = {
  // Return numbers as NumberValue instead of native JS numbers
  wrapNumbers: false,
};

const translateConfig = { marshallOptions, unmarshallOptions };

const client = new DynamoDBClient({});
const docClient = DynamoDBDocument.from(client, translateConfig);

marshallOptions

OptionTypeDefaultDescription
convertEmptyValuesbooleanfalseConvert empty strings, blobs, and sets to null
removeUndefinedValuesbooleanfalseStrip undefined values from objects and arrays
convertClassInstanceToMapbooleanfalseMarshal class instances as DynamoDB map attributes
allowImpreciseNumbersbooleanfalseAllow numbers beyond Number.MAX_SAFE_INTEGER, which may lose precision

unmarshallOptions

OptionTypeDefaultDescription
wrapNumbersboolean | ((str: string) => any)falseWhen true, return numbers as NumberValue. Pass a function for custom conversion (e.g. BigInt)

Large numbers and NumberValue

By default, the Document Client throws an error if a number exceeds Number.MAX_SAFE_INTEGER to prevent silent precision loss. Use NumberValue to store and retrieve large numbers precisely.

Writing large numbers

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { NumberValue, DynamoDBDocument } from "@aws-sdk/lib-dynamodb";

const docClient = DynamoDBDocument.from(new DynamoDB({}));

await docClient.put({
  Item: {
    id: 1,
    smallNumber: NumberValue.from("123"),
    bigNumber: NumberValue.from("1000000000000000000000.000000000001"),
    nSet: new Set([123, NumberValue.from("456"), 789]),
  },
});

Reading large numbers

Configure wrapNumbers to control how numbers are returned on reads:
const docClient = DynamoDBDocument.from(new DynamoDB({}), {
  unmarshallOptions: {
    // Use BigInt for all numbers
    wrapNumbers: (str) => BigInt(str),
  },
});

const response = await docClient.get({ Key: { id: 1 } });
// Numbers in response are BigInt values
NumberValue does not support mathematical operations. Call .toString() on a NumberValue to pass it to a big number library.

Cleaning up

destroy() on the Document Client is a no-op — it does not own the underlying DynamoDBClient. Call destroy() on the original client to release resources:
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

// ...perform operations...

docClient.destroy(); // no-op
client.destroy();    // releases DynamoDBClient resources

Build docs developers (and LLMs) love