Provides TypeScript patterns for DynamoDB-Toolbox v2: schema/table/entity modeling, .build() workflows, query/scan access patterns, batch/transaction operations, single-table designs with computed keys. For type-safe DynamoDB access layers in TS services.
From developer-kit-typescriptnpx claudepluginhub giuseppe-trisciuoglio/developer-kit --plugin developer-kit-typescriptThis skill is limited to using the following tools:
references/api-dynamodb-toolbox-v2.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides agent creation for Claude Code plugins with file templates, frontmatter specs (name, description, model), triggering examples, system prompts, and best practices.
This skill provides practical TypeScript patterns for using DynamoDB-Toolbox v2 with AWS SDK v3 DocumentClient. It focuses on type-safe schema modeling, .build() command usage, and production-ready single-table design.
item, string, number, list, set, map, and recordGetItem, PutItem, UpdateItem, DeleteItem via .build().key(), .required(), .default(), .transform(), .link()..build() commands everywhere: avoid ad-hoc command construction for consistency and type safety.npm install dynamodb-toolbox @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
import { Table } from 'dynamodb-toolbox/table';
import { Entity } from 'dynamodb-toolbox/entity';
import { item, string, number, list, map } from 'dynamodb-toolbox/schema';
const client = new DynamoDBClient({ region: process.env.AWS_REGION ?? 'eu-west-1' });
const documentClient = DynamoDBDocumentClient.from(client);
export const AppTable = new Table({
name: 'app-single-table',
partitionKey: { name: 'PK', type: 'string' },
sortKey: { name: 'SK', type: 'string' },
indexes: {
byType: { type: 'global', partitionKey: { name: 'GSI1PK', type: 'string' }, sortKey: { name: 'GSI1SK', type: 'string' } }
},
documentClient
});
const now = () => new Date().toISOString();
export const UserEntity = new Entity({
name: 'User',
table: AppTable,
schema: item({
tenantId: string().required('always'),
userId: string().required('always'),
email: string().required('always').transform(input => input.toLowerCase()),
role: string().enum('admin', 'member').default('member'),
loginCount: number().default(0),
tags: list(string()).default([]),
profile: map({
displayName: string().optional(),
timezone: string().default('UTC')
}).default({ timezone: 'UTC' })
}),
computeKey: ({ tenantId, userId }) => ({
PK: `TENANT#${tenantId}`,
SK: `USER#${userId}`,
GSI1PK: `TENANT#${tenantId}#TYPE#USER`,
GSI1SK: `EMAIL#${userId}`
})
});
.build() CRUD Commandsimport { PutItemCommand } from 'dynamodb-toolbox/entity/actions/put';
import { GetItemCommand } from 'dynamodb-toolbox/entity/actions/get';
import { UpdateItemCommand, $add } from 'dynamodb-toolbox/entity/actions/update';
import { DeleteItemCommand } from 'dynamodb-toolbox/entity/actions/delete';
await UserEntity.build(PutItemCommand)
.item({ tenantId: 't1', userId: 'u1', email: 'A@Example.com' })
.send();
const { Item } = await UserEntity.build(GetItemCommand)
.key({ tenantId: 't1', userId: 'u1' })
.send();
await UserEntity.build(UpdateItemCommand)
.item({ tenantId: 't1', userId: 'u1', loginCount: $add(1) })
.send();
await UserEntity.build(DeleteItemCommand)
.key({ tenantId: 't1', userId: 'u1' })
.send();
import { QueryCommand } from 'dynamodb-toolbox/table/actions/query';
import { ScanCommand } from 'dynamodb-toolbox/table/actions/scan';
const byTenant = await AppTable.build(QueryCommand)
.query({
partition: `TENANT#t1`,
range: { beginsWith: 'USER#' }
})
.send();
const byTypeIndex = await AppTable.build(QueryCommand)
.query({
index: 'byType',
partition: 'TENANT#t1#TYPE#USER'
})
.options({ limit: 25 })
.send();
const scanned = await AppTable.build(ScanCommand)
.options({ limit: 100 })
.send();
import { BatchWriteCommand } from 'dynamodb-toolbox/table/actions/batchWrite';
import { TransactWriteCommand } from 'dynamodb-toolbox/table/actions/transactWrite';
await AppTable.build(BatchWriteCommand)
.requests(
UserEntity.build(PutItemCommand).item({ tenantId: 't1', userId: 'u2', email: 'u2@example.com' }),
UserEntity.build(PutItemCommand).item({ tenantId: 't1', userId: 'u3', email: 'u3@example.com' })
)
.send();
await AppTable.build(TransactWriteCommand)
.requests(
UserEntity.build(PutItemCommand).item({ tenantId: 't1', userId: 'u4', email: 'u4@example.com' }),
UserEntity.build(UpdateItemCommand).item({ tenantId: 't1', userId: 'u1', loginCount: $add(1) })
)
.send();
TENANT#, USER#, ORDER#).computeKey) to avoid drift..options({ consistent: true }) only where strict read-after-write is required.Primary references curated from Context7 are available in:
references/api-dynamodb-toolbox-v2.md