npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

payloadcms-db-dynamo

v1.0.0

Published

DynamoDB database adapter for Payload CMS (single-table design)

Readme

payloadcms-db-dynamo

DynamoDB database adapter for Payload CMS. Stores collections, globals, and version rows in a single-table layout with GSIs for sorting, indexed lookups, and geo queries.

Status: this entire project is vibe coded in a weekend, but it has two full working kitchen sink examples checked in. Use at your own risk. I made this to be able to deploy Payload CMS into AWS Lambda with OpenNext and have its data backed into DynamoDB, to pay $0 when scaled to zero.

Requirements

Examples

Kitchen-sink Payload 3.x and 4.x apps that use this adapter with the repo-root DynamoDB Local compose file: examples/README.md.

Install

npm install payloadcms-db-dynamo payload

Configure

import { buildConfig } from 'payload'
import { dynamoAdapter } from 'payloadcms-db-dynamo'

export default buildConfig({
  db: dynamoAdapter({
    tableName: 'payload',
    // Optional: create the table on init (local dev / DynamoDB Local only).
    // In AWS, provision the table with IaC instead.
    ensureTables: true,
    clientConfig: {
      region: process.env.AWS_REGION ?? 'us-east-1',
      endpoint: process.env.DYNAMODB_ENDPOINT, // e.g. http://localhost:8000
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID ?? 'test',
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ?? 'test',
      },
    },
  }),
  // collections, globals, ...
})

Options

| Option | Description | |--------|-------------| | tableName | Physical DynamoDB table name (default payload). | | clientConfig | Passed to DynamoDBClient (region, endpoint, credentials, retries). | | client | Inject an existing DynamoDBClient (adapter will not destroy it). | | ensureTables | When true, create the table and GSIs during init if missing. | | migrationDir | Directory for migration files (default migrations). | | bulkOperationsSingleTransaction | When true, updateMany / deleteMany run inside one transaction per request when req has no transaction yet. DynamoDB limits each transact to 100 items; larger bulks are split automatically on commit. |

Table schema

Generate a JSON description of the table, GSIs, and per-collection metadata for your IaC tool:

npx payload generate:db-schema

By default this writes src/payload-generated-dynamodb.json. Pass generateSchema({ outputFile: '...' }) on the adapter to customize the path.

Migrations

Works with Payload’s migration commands (migrate, migrate:status, migrate:down, migrate:reset, migrate:fresh). Point migrationDir at your project’s migration folder.

migrateFresh drops and recreates the table, then re-runs migrations — destructive; use only in development.

Transactions

Supports Payload request transactions (beginTransaction / commitTransaction / rollbackTransaction).

Query & writes

  • Where: equals, comparisons, in / not_in / all, exists, like / not_like / contains, and / or, plus geo near / within / intersects on point fields.
  • Collections: Declared indexes use forward IDX#…#value partitions for equals / in, and the gsi2 reverse index for exists / not_equals / not_in on that field; default list sorting uses the configured sort field (typically createdAt).
  • Geo: point fields support radius and bounding-box style queries.
  • Join fields: Resolved on find / findOne.
  • Updates: Optimistic concurrency via updatedAt; unknown fields in request bodies are not persisted.

One-shot cleanup after upgrade

If rows were written before strict field projection was enabled, run the exported helper once:

import { getPayload } from 'payload'
import config from './payload.config'
import { scrubUnknownFields } from 'payloadcms-db-dynamo'

const payload = await getPayload({ config })
const report = await scrubUnknownFields(payload)
await payload.destroy()

Typing migrations (optional)

Migration files receive { payload, req, session } from Payload. For TypeScript migrations, import the argument types:

import type { MigrateDownArgs, MigrateUpArgs } from 'payloadcms-db-dynamo'

export async function up({ payload }: MigrateUpArgs) {
  // ...
}

export async function down({ payload }: MigrateUpArgs) {
  // ...
}

Plain .js migrations do not need this import.

License

MIT