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

dirsql

v0.4.18

Published

Ephemeral SQL index over a local directory

Downloads

8,248

Readme

dirsql (TypeScript SDK)

Ephemeral SQL index over a local directory. dirsql watches a filesystem, ingests structured files into an in-memory SQLite database, and exposes a SQL query interface -- the filesystem is always the source of truth. Built on the Rust core via napi-rs bindings.

Documentation

Also available as dirsql on crates.io and dirsql on PyPI.

Installation

npm add dirsql

Prebuilt binaries ship for linux-x64, linux-arm64, darwin-x64, darwin-arm64, and win32-x64; npm picks up the right one via optionalDependencies, so no Rust toolchain is required. The npm CLI requires Node >= 20.11.

Quick start

Constructing a DirSQL returns immediately; scanning runs in the background and every method awaits it, so you can query right away (or await db.ready to surface scan errors up front). Each table is a (ddl, glob, extract) object: the DDL defines the SQLite schema, the glob selects files (relative to root), and extract returns the rows a matched file contributes -- always an array, return [] to skip a file. dirsql does not read file contents; if extract needs the file body it reads path itself.

import { readFileSync } from "node:fs";
import { DirSQL, type TableDef } from "dirsql";

const tables: TableDef[] = [
  {
    ddl: "CREATE TABLE posts (title TEXT, author TEXT)",
    glob: "posts/*.json",
    extract: (path) => [JSON.parse(readFileSync(path, "utf8"))],
  },
];

const db = new DirSQL({ root: "./my-blog", tables });

const posts = await db.query("SELECT * FROM posts WHERE author = 'alice'");
console.log(posts);

Multiple tables and joins

import { readFileSync } from "node:fs";
import { DirSQL, type TableDef } from "dirsql";

const tables: TableDef[] = [
  {
    ddl: "CREATE TABLE posts (title TEXT, author_id TEXT)",
    glob: "posts/*.json",
    extract: (path) => [JSON.parse(readFileSync(path, "utf8"))],
  },
  {
    ddl: "CREATE TABLE authors (id TEXT, name TEXT)",
    glob: "authors/*.json",
    extract: (path) => [JSON.parse(readFileSync(path, "utf8"))],
  },
];

const db = new DirSQL({ root: "./my-blog", tables });

const results = await db.query(`
  SELECT posts.title, authors.name
  FROM posts JOIN authors ON posts.author_id = authors.id
`);

Ignoring files

Pass ignore patterns to skip files during scanning and watching:

const db = new DirSQL({
  root: "./my-blog",
  tables: [/* ... */],
  ignore: ["**/drafts/**", "**/.git/**"],
});

Watching for changes

db.watch() returns an async iterable of row-level change events as files change on disk:

for await (const event of db.watch()) {
  console.log(`${event.action} on ${event.table}:`, event.row);
}

Each event has .action ('insert' | 'update' | 'delete' | 'error'), .table, .row (the new row, or the deleted row on delete), .oldRow (the previous row, on update), .filePath, and .error (on error).

CLI

npx dirsql "<sql>" runs one query and prints the rows as JSON — the default. npx dirsql server starts an HTTP server exposing the SDK over HTTP: POST /query for SQL and GET /events for a Server-Sent Events change stream. Requires Node >= 20.11. See the CLI reference.

License

MIT