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

@undefineds.co/drizzle-solid

v0.3.4

Published

Drizzle ORM adapter for Solid Pods

Readme

drizzle-solid

Chinese version: README.zh-CN.md

drizzle-solid stores application-owned data in Solid Pods with typed schemas and a Drizzle-aligned developer experience.

Use it when you want:

  • TypeScript schemas for Pod data
  • explicit Pod layout through base and subjectTemplate
  • a choice between a Solid-first API (pod()) and a Drizzle-shaped API (drizzle())
  • exact entity reads and writes by IRI or locator
  • SPARQL-backed reads when your backend exposes query capability

What it is good at

  • application-owned data in your Pod or a user Pod
  • typed CRUD over known resource layouts
  • gradual migration from drizzle-orm
  • Pod-native concepts such as IRIs, documents, links, discovery, notifications, and federation

What it is not trying to be

  • a general-purpose RDF exploration toolkit
  • full SQL/database parity across every Solid backend
  • a library that hides Pod boundaries, permissions, or network costs
  • a raw SQL-first abstraction

Install

yarn add @undefineds.co/drizzle-solid drizzle-orm
# optional: install when your app wants the built-in SPARQL engine
yarn add @comunica/query-sparql-solid
npm install @undefineds.co/drizzle-solid drizzle-orm
# optional: install when your app wants the built-in SPARQL engine
npm install @comunica/query-sparql-solid

@comunica/query-sparql-solid is an optional peer dependency.

Current support stance:

  • supported: @comunica/query-sparql-solid 4.x
  • not in the current supported matrix: 3.x

If another in-process runtime already ships Comunica, inject that engine instead of installing a second copy.

Choose your API style

pod(session)

Use this for new code when you want Solid concepts to be explicit in the API:

  • collection(table)
  • entity(table, iri)
  • bind(schema, options)
  • sparql(query)

drizzle(session)

Use this when you are migrating from drizzle-orm or want to keep builder-shaped code:

  • select / insert / update / delete
  • db.query.<table>
  • findByLocator / findByIri
  • updateByLocator / updateByIri
  • deleteByLocator / deleteByIri

Both styles use the same runtime. The difference is API shape, not storage behavior.

Quick start

import { pod, podTable, string, datetime } from '@undefineds.co/drizzle-solid';

const posts = podTable('posts', {
  id: string('id').primaryKey(),
  title: string('title').predicate('http://schema.org/headline'),
  content: string('content').predicate('http://schema.org/text'),
  createdAt: datetime('createdAt').predicate('http://schema.org/dateCreated'),
}, {
  base: 'https://alice.example/data/posts/',
  subjectTemplate: '{id}.ttl',
  type: 'http://schema.org/CreativeWork',
});

const client = pod(session);
await client.init(posts);

const created = await client.collection(posts).create({
  id: 'post-1',
  title: 'Hello Solid',
  content: 'Stored as RDF in a Pod document.',
  createdAt: new Date(),
});

if (!created) {
  throw new Error('Create failed');
}

const post = client.entity(posts, created['@id']);

console.log(await post.get());
await post.update({ title: 'Updated title' });
await post.delete();

Drizzle-style exact operations

import { drizzle, podTable, string } from '@undefineds.co/drizzle-solid';

const posts = podTable('posts', {
  id: string('id').primaryKey(),
  title: string('title').predicate('http://schema.org/headline'),
}, {
  base: 'https://alice.example/data/posts/',
  subjectTemplate: '{id}.ttl',
  type: 'http://schema.org/CreativeWork',
});

const db = drizzle(session);
await db.init(posts);

await db.insert(posts).values({
  id: 'post-1',
  title: 'Hello Solid',
});

const row = await db.findByLocator(posts, { id: 'post-1' });

await db.updateByLocator(posts, { id: 'post-1' }, {
  title: 'Updated title',
});

await db.deleteByLocator(posts, { id: 'post-1' });

How Pod layout works

Every model describes both shape and placement.

  • base defines where documents live
  • subjectTemplate defines how business fields map to an IRI
  • type is the primary persisted rdf:type

Common subjectTemplate patterns:

  • #{id} — many entities in one document
  • {id}.ttl — one document per entity
  • {id}.ttl#it — one document per entity with a stable fragment
  • {chatId}/messages.ttl#{id} — partitioned layout with multiple locator variables

If your template uses multiple variables, exact lookup requires either:

  • the full IRI, or
  • a complete locator with every required variable

Collection reads vs exact entity operations

This is the most important runtime rule.

Collection reads

Use collection reads when you want a list or filtered subset:

  • client.collection(table).list(...)
  • db.select().from(table)...
  • db.query.<table>.findMany(...)

Exact entity operations

Use exact-target helpers when you mean one concrete entity:

  • client.entity(table, iri)
  • db.findByIri(table, iri)
  • db.findByLocator(table, locator)
  • db.updateByIri(...)
  • db.updateByLocator(...)
  • db.deleteByIri(...)
  • db.deleteByLocator(...)

Do not rely on where({ id: ... }) or where(eq(table.id, ...)) as an exact-target shortcut.

SPARQL support and backend behavior

drizzle-solid works across different Solid runtimes, but capabilities differ.

| Capability | Community Solid Server | xpod | | --- | --- | --- | | Basic CRUD | ✅ | ✅ | | Document notifications | ✅ | ✅ | | Drizzle-style read facade | ✅ | ✅ | | SPARQL pushdown | ⚠️ Limited / often client-assisted | ✅ Better in-process support | | Filter / aggregation pushdown | ❌ Mostly client-side execution | ✅ Better server-side support | | Federated queries | ⚠️ Client-side federation | ⚠️ Client-side federation | | In-process local runtime | ⚠️ External setup | ✅ via @undefineds.co/xpod |

Practical rule:

  • if you have a SPARQL endpoint or sidecar, use it for collection queries
  • if you only have plain LDP document access, exact-target reads and writes still work
  • plain-LDP document mode does not silently widen exact operations into scans

Examples

The canonical examples in examples/ are part of the integration verification flow:

  • examples/01-quick-start.ts
  • examples/02-relational-query.ts
  • examples/03-zero-config-discovery.ts
  • examples/04-notifications.ts
  • examples/05-data-discovery.ts
  • examples/06-federated-query.ts
  • examples/07-hooks-and-profile.ts
  • examples/08-iri-based-operations.ts
  • examples/08-schema-inheritance.ts
  • examples/09-multi-variable-templates.ts

Documentation

Start here:

  • docs/guides/installation.md
  • docs/api/README.md
  • docs/guides/migrating-from-drizzle-orm.md
  • docs/guides/multi-variable-templates.md
  • docs/guides/notifications.md
  • docs/guides/data-discovery.md

Contributing

Before pushing:

yarn quality
SOLID_ENABLE_REAL_TESTS=true SOLID_SERIAL_TESTS=true yarn vitest --run tests/integration/css

Examples must remain runnable and verified.

License

MIT

Related links

  • GitHub: https://github.com/undefinedsco/drizzle-solid
  • npm: https://www.npmjs.com/package/@undefineds.co/drizzle-solid
  • xpod: https://github.com/undefinedsco/xpod