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

@possumtech/sqlrite

v5.2.0

Published

SQL Done Right

Readme

SqlRite

SQL-first persistence for Node.js — a zero-dependency wrapper over the built-in node:sqlite. You write SQL in .sql files tagged with comment markers, and SqlRite turns each tagged block into a JavaScript method. No models, no query builder, no implicit find/save — every operation is an explicit SQL block you can read.

  • Requires Node >=25.0.0, npm >=11.1.0. Zero runtime dependencies.
  • Two facades over one core: async (DB in a Worker thread) and sync.

Full reference — exhaustive tag/option semantics, the design contract, security limits, and maintainer notes — lives in SPEC.md. This page is the quickstart.

Install

npm install @possumtech/sqlrite

How it works

Point SqlRite at one or more directories of .sql files. Each tagged block becomes a method on the returned object.

| Tag | Becomes | What it does | | :-- | :-- | :-- | | -- INIT: <name> | runs at open | DDL / PRAGMA executed once when the DB opens. Use idempotent DDL. | | -- PREP: <name> | db.<name>.{all,get,run}(params) | Prepared statement — the only path for runtime or untrusted values. | | -- EXEC: <name> | db.<name>(params) | db.exec() of the block. Trusted SQL only — values are string-interpolated, not bound. | | -- TX: <name> | db.<name>(params) | -- EXEC wrapped in BEGIN/COMMIT (auto-ROLLBACK on error). Trusted SQL only. |

Directories are scanned recursively; files run sorted by basename, numerically (001-*.sql before 002-*.sql). Duplicate EXEC/PREP/TX names warn — the last definition wins.

Usage

Async (default — runs in a Worker thread)

import SqlRite from "@possumtech/sqlrite";

await using sql = await SqlRite.open({ path: "data.db", dir: "sql" });

await sql.addUser.run({ name: "Alice", meta: { theme: "dark" } });
const user = await sql.getUserByName.get({ name: "Alice" });

Construct only via open() — the constructor throws otherwise. Methods return Promises.

Sync

import { SqlRiteSync } from "@possumtech/sqlrite";

using sql = new SqlRiteSync({ dir: ["migrations", "src/users"] });
const users = sql.getUserByName.all({ name: "Alice" });

new SqlRiteSync() cannot register custom functions (registration is async) — use await SqlRiteSync.open() if you pass functions.

| Import | Default export | Named | | :-- | :-- | :-- | | @possumtech/sqlrite | SqlRite (async) | SqlRiteSync | | @possumtech/sqlrite/sync | SqlRiteSync | — | | @possumtech/sqlrite/core | SqlRiteCore (static utilities) | — |

PREP statements

A -- PREP method exposes three modes:

| Mode | For | Returns | | :-- | :-- | :-- | | .run(params) | INSERT/UPDATE/DELETE | { changes, lastInsertRowid } | | .get(params) | one row | row object or undefined | | .all(params) | many rows | array of rows |

  • Bind with named parameters ($name, :name, @name). Pass an object; a leading $/:/@ on keys is optional, so { name } binds $name.
  • Object/array values are JSON.stringify-ed on the way in; output is not parsed — call JSON.parse() yourself.
  • Integers read as number; a value past 2^53 − 1 throws rather than silently rounding. Opt a statement into BigInt with a bigint flag on its tag — see SPEC.md.
-- PREP: addUser
INSERT INTO users (name, meta) VALUES ($name, $meta);

-- PREP: searchUsers
SELECT * FROM users WHERE name REGEXP $pattern;

Configuration

| Option | Type | Default | Description | | :-- | :-- | :-- | :-- | | path | string | ":memory:" | SQLite database file path. | | dir | string \| string[] | "sql" | Directories scanned for .sql files. | | functions | string \| string[] | — | JS module paths for custom SQL functions. | | params | object | — | $var substitutions for -- INIT blocks. |

SqlRite opens with a hardened, WAL-mode posture (foreign keys on, defensive mode, a non-zero busy_timeout) and exposes curated performance knobs (cacheSize, mmapSize, maxPageCount). Every default is overridable; any other key passes through to node:sqlite. Full tables in SPEC.md.

Built-in SQL functions

  • REGEXPcol REGEXP $pattern via JavaScript RegExp, with an optional (?flags) prefix (e.g. (?i)^foo for case-insensitive). Trusted patterns onlyRegExp can catastrophically backtrack (ReDoS); see SPEC.md.
  • uuid()crypto.randomUUID(); usable as a column default: id TEXT PRIMARY KEY DEFAULT (uuid()).

Register your own with the functions option — see SPEC.md.

Safety in one breath

  • -- PREP is the only place runtime or untrusted values belong — it binds them.
  • -- EXEC / -- TX string-interpolate their values — developer-authored SQL only, never untrusted input.
  • REGEXP patterns must be trusted (ReDoS).

License

MIT © @wikitopian