TypeScript
The TypeScript package provides one collection API over R2 document storage and D1 indexes. Choose the adapter for your runtime, then provide a schema and document codec.
Install
The package requires Node.js 22 or later for the Node.js adapters. Cloudflare Workers use the Workers subpath.
npm install @nexcraft-dev/r2d1Node.js
Use the Node.js adapters for R2 and D1. The code below assumes you have configured r2Config, d1Config, schema, and codec.
import { R2D1 } from "@nexcraft-dev/r2d1";
import { NodeR2DocumentStore, NodeD1IndexStore } from "@nexcraft-dev/r2d1/node";
const users = await new R2D1(
new NodeR2DocumentStore(r2Config),
new NodeD1IndexStore(d1Config),
).collection(schema, codec);
await users.put({ id: "user-1", country: "NZ", score: 4.5 });
const page = await users
.query().where("country").eq("NZ")
.sortBy("score", "DESC").limit(20).fetch();Cloudflare Workers
Bind an R2 bucket as DOCUMENTS and a D1 database as INDEXES, then pass those bindings to the Workers adapters.
import { R2D1 } from "@nexcraft-dev/r2d1";
import {
WorkersR2DocumentStore,
WorkersD1IndexStore,
} from "@nexcraft-dev/r2d1/workers";
const users = await new R2D1(
new WorkersR2DocumentStore(env.DOCUMENTS),
new WorkersD1IndexStore(env.INDEXES),
).collection(schema, codec);Java data compatibility
R2 keys, D1 tables, indexes, and cursor format follow the Java contracts. The document byte format belongs to your application: Java defines no default format. Use a TypeScript codec that writes and reads the same bytes. The jsonCodec helper is optional and does not support bigint. TypeScript long fields use bigint.
Complete examples
The repository includes complete Node.js, Workers, and shared codec examples.
