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

payload-db-sqlite-documents

v1.0.0

Published

A [Payload CMS](https://payloadcms.com) database adapter that stores data in **SQLite**, but in a **schemaless / "documents" style** — each document is kept as a whole JSON blob, in the spirit of [`@payloadcms/db-mongodb`](https://github.com/payloadcms/pa

Readme

payload-db-sqlite-documents

A Payload CMS database adapter that stores data in SQLite, but in a schemaless / "documents" style — each document is kept as a whole JSON blob, in the spirit of @payloadcms/db-mongodb, rather than the relational, schema-per-field style of the official @payloadcms/db-sqlite.

It uses Node's built-in node:sqlite driver, so there are no native dependencies to compile.

Why this exists

It's aimed at projects that run @payloadcms/db-mongodb in production — and therefore don't track migrations, because Mongo is schemaless — but want a local-development or preview-deployment experience that doesn't require standing up a real MongoDB instance.

Because storage is schemaless and migration-less like Mongo, yet backed by a single SQLite file, this adapter also makes it practical to source-control the database file itself (git add payload.db) — handy for reproducible local dev and preview environments where you want seed data to travel with the branch.

Local development is the primary design target. Production use isn't discouraged, but see Limitations before reaching for it there.

Requirements

  • Node.js ^22 || ^24 || ^26 — where node:sqlite is a built-in.
  • Payload ^3.85.2 (peer dependency).

Installation

npm install payload-db-sqlite-documents
# or: yarn add payload-db-sqlite-documents / pnpm add payload-db-sqlite-documents

Usage

Pass the adapter as db in your Payload config:

import { buildConfig } from "payload";
import { sqliteDocumentsAdapter } from "payload-db-sqlite-documents";

export default buildConfig({
  db: sqliteDocumentsAdapter({
    // A file path — a single, source-controllable SQLite file.
    filename: "./payload.db",
  }),
  // ...the rest of your config
});

For an ephemeral database (e.g. in tests) omit filename or set it to ":memory:":

db: sqliteDocumentsAdapter(); // defaults to ":memory:"

The adapter advertises defaultIDType: "text", matching the db-mongodb audience — new collections get text (UUID) IDs unless you configure otherwise.

Options

| Option | Type | Default | Description | | -------------- | -------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | filename | string | ":memory:" | Where the SQLite database lives. Passed straight to node:sqlite's DatabaseSync: a filesystem path (source-controllable), or ":memory:" for ephemeral. | | migrationDir | string | Payload's default | Directory Payload reads/writes migration files from. (Migrations are rarely relevant for the Mongo-style, schemaless target.) |

How it works

Storage is schemaless — there is no per-field schema, and no migrations:

  • Collections — each collection gets its own table with a text primary-key id column and the whole document serialised to JSON in a doc column.
  • Globals — share a single payload_globals table, keyed by slug.
  • Versions & drafts — share a single payload_versions table, scoped by collection_slug / global_slug.

Queries compile Payload's Where into parameterised SQL over json_extract(doc, …). Field names and values are always bound as parameters (never string-interpolated), and table names are escaped as quoted identifiers, so slugs, field names, and values can't inject SQL.

Tables are created lazily on first write, so the file only ever contains tables for collections you've actually used.

Query operators

The common scalar and array operators are supported:

equals, not_equals, greater_than, greater_than_equal, less_than, less_than_equal, in, not_in, all, exists, contains, like, not_like, plus and / or composition.

Semantics track db-mongodb where they differ from plain SQL:

  • equals / not_equals are array-aware — a value matches a scalar field or an element of an array field.
  • Negative operators include missing fieldsnot_equals and not_like match rows where the field is absent, as Mongo does.
  • like splits on whitespace — every word must appear (order-independent); contains is a single contiguous substring match. Both are case-insensitive (ASCII).

Transactions

Real transactions are implemented on the single shared connection (BEGIN / COMMIT / ROLLBACK, with SAVEPOINTs for nesting), so multi-statement operations are atomic and roll back on error. Handlers need no special plumbing — an open transaction scopes every write automatically.

Limitations

  • Geospatial operators are not supported. within, intersects, and near throw — SQLite/JSON storage has no geometry support. Every other operator listed above works.
  • A single shared connection. SQLite allows only one live transaction per connection, so genuinely concurrent transactions from separate requests are not isolated. This is fine for the local-dev / preview target, but is why production isn't the primary use case.
  • No migrations. By design — the schemaless, Mongo-style model doesn't track them.

Relationship to @payloadcms/db-sqlite

This adapter aims for near-parity with db-sqlite's public API (exported function, adapter options, generated types), even though the internal storage strategy is completely different: documents/schemaless here vs. relational/schema-based there. If you want a production-grade, relational SQLite adapter with real migrations, use the official @payloadcms/db-sqlite instead.

Development

yarn build   # bundle src -> dist/index.js (+ .d.ts declarations)
yarn test    # vitest run
yarn lint    # eslint
yarn tsc     # typecheck only