Skip to content
Eugene Lazutkin edited this page Jul 17, 2026 · 31 revisions

dynamodb-toolkit

CI NPM version

Opinionated zero-runtime-dependency micro-library for AWS DynamoDB. Built on the AWS JS SDK v3 (@aws-sdk/client-dynamodb + @aws-sdk/lib-dynamodb). ESM-only, hand-written .d.ts sidecars, no build step. Tested on Node, Deno, and Bun — usable from TypeScript and CommonJS consumers alike.

v2 documentation lives at the v2.3-docs git tag of this wiki repo. v2 source remains available on npm as dynamodb-toolkit@2.3.0.

"Toolkit", not "framework"

The pieces are independent. You don't need to adopt the Adapter to use the expression builders, and you don't need the builders to use the batch chunkers. Every layer has a public surface and is consumable on its own:

  • Use buildUpdate / buildCondition to prep a params object, then send it with the raw SDK UpdateCommand — no Adapter in sight.
  • Hand-build your own params and pass them to applyBatch / applyTransaction for chunking, UnprocessedItems retry, and exponential backoff.
  • Use the Adapter for CRUD + hooks but swap in your own @aws-sdk/lib-dynamodb Command invocation anywhere you want raw control.
  • Take the REST handler or leave it — the Adapter works standalone.

Two concrete payoffs: migration (adopt one piece at a time starting from raw-SDK code) and debugging (peel layers back one at a time when something looks off). The boundary between caller code and toolkit machinery stays explicit.

Search

🔍 Search this wiki — ranked, deep-linked search via wiki-search; install the bookmarklet to search in place. Fallback: GitHub wiki search.

Documentation

Start here

Guides

Design-level pages — longer-form than a recipe, broader than a reference. Read them when you're deciding how to shape the table, the keys, or the API, not looking up a method.

  • Hierarchical data walkthrough — a three-table SQL schema packed into one DynamoDB table with structured keys, start to finish: declaration, writes, subtree reads, tier listing, cascades, and the REST mirror.
  • Key expression patterns — a catalogue of key shapes that turn filter problems into index seeks: sparse-by-absence, status+timestamp compounds, multi-tenant prefixes, adjacency lists, write-sharded time series.
  • Multi-type tables — several entity types in one table: key-presence (depth) vs discriminator vs auto-stamped typeField, the typeOf priority chain, and when not to share a table.
  • Pagination — offset/limit vs cursor, what each costs in RCUs, filtered-page semantics, and both modes on the wire (?offset, ?cursor, ?format=jsonl).
  • Mass operation semantics — the contract behind bulk writes: per-item atomicity, the result buckets, idempotent-phase resume, and the queue-worker loop (in process and over HTTP).
  • URL schema design — three canonical URL schemes over the same Adapter: the shipped flat route pack, delimiter-in-key, and hierarchical paths with meta-markers.

Adapter

Expression builders (dynamodb-toolkit/expressions)

Batch / transactions / mass / paths

  • Batch and transactionsapplyBatch, applyTransaction, getBatch, getTransaction
  • Mass operationspaginateList, iterateList, read*, write*, delete*, copy*, move*
  • PathsgetPath, setPath, applyPatch, subsetObject, normalizeFields

REST surface

  • REST core — parsers, builders, policy (framework-agnostic)
  • HTTP handlernode:http (req, res) handler with the standard route pack

Framework adapters

Framework-specific bindings ship in the box as subpath exports — thin ports over one shared engine, with the same wire contract as the bundled HTTP handler. The former standalone dynamodb-toolkit-{koa,express,fetch,lambda} packages are superseded by these subpaths.

  • Framework adapters — the shared surface: routes, options, composite keys from the URL, per-tenant filtering.
  • Express adapterdynamodb-toolkit/express: Express 4.x / 5.x middleware / Router.
  • Koa adapterdynamodb-toolkit/koa: Koa 2.x / 3.x middleware.
  • Fetch adapterdynamodb-toolkit/fetch: (Request) => Promise<Response> for Cloudflare Workers, Deno Deploy, Bun.serve, Hono, and Node's native fetch server.
  • Lambda adapterdynamodb-toolkit/lambda: API Gateway REST + HTTP, Function URL, and ALB; dynamodb-toolkit/lambda/local.js ships local-debug bridges for running the handler on real HTTP.
  • Plain Express routes — skip the adapters entirely: three hand-written routes calling the toolkit directly.

Recipes

Pattern-first pages for common DynamoDB problems that feel trivial in SQL but need non-obvious index shapes here. See Recipes for the full grouped index (by problem domain).

  • Recipe: List records of a tier — "all states globally" via a single sparse GSI on the auto-populated typeField. Simplest cross-partition tier listing.
  • Recipe: Per-tier sparse GSI markers — one GSI per tier with per-tier marker attributes. Finer control over projection + writes; sharded-marker variant for leaf-tier scale.
  • Recipe: List records of a tier within a partition — sparse LSI. Cheaper than a GSI when the listing is always within a known partition.
  • Recipe: Reservation with auto-release — short-lived holds (rental car, meeting room, flash-sale item) that release automatically if the caller goes silent. Composes versionField (optimistic concurrency) + createdAtField + asOf (scope-freeze) + deleteListByParams (resumable sweep).
  • Recipe: Keys-only GSI with runtime projection — declare a GSI with projection: 'keys-only' + indirect: true; reads Query the GSI for keys, then BatchGetItem the base table with the caller's per-call fields. Cheap GSI storage, rich runtime projections.
  • Recipe: Cascade subtree operationsdeleteAllUnder / cloneAllUnder[By] / moveAllUnder[By] against composite keyFields with relationships: {structural: true}. Resumable leaf-first / root-first pagination, constructive-before-destructive moves, MassOpResult partial-failure surfacing.
  • Recipe: Querying subtrees with buildKey — hierarchical subtree queries via adapter.buildKey(values, options). Three shapes: children-only (default), self + descendants ({self: true}), narrow-prefix ({partial: 'Dal'}). Plus the getListUnder sugar and composition with mass ops.
  • Recipe: Filter URL grammar — the ?<op>-<field>=<value> query grammar: op table, multi-value forms, filterable allowlist, key-condition auto-promotion.
  • Recipe: Text search — case-insensitive substring search via searchable + -search-; when to graduate to an external index.
  • Recipe: Provisioning workflowplanTable / ensureTable / verifyTable and the bundled CLI: plan-preview, apply, drift check.
  • Recipe: Resumable mass operations{maxItems, resumeToken} cursors across mass ops; MassOpResult buckets and partial-failure handling.

History

Clone this wiki locally