Skip to content
BunBase BunBase BunBase Docs Alpha v0.1.0

Collections

client.collection<T>(name) returns a typed client for a single collection.

interface Post {
title: string;
body: string;
published: boolean;
score?: number;
}
const posts = client.collection<Post>("posts");

Every record is intersected with BunBaseRecord — system fields (_id, _created_at, _updated_at, _owner_id, _deleted_at) are always present.

const post = await posts.create({
title: "Hello BunBase",
body: "...",
published: true,
});
console.log(post._id); // "01JKX..." — ULID
console.log(post._created_at); // Unix ms

Create many in parallel:

const created = await posts.createMany([
{ title: "Post 1", published: true },
{ title: "Post 2", published: false },
]);

Rejects if any individual create fails.

const post = await posts.get("01JKX...");
const updated = await posts.update("01JKX...", { title: "Updated title" });

Only provided fields are changed. System fields are ignored.

await posts.delete("01JKX...");
// Sets _deleted_at. Record is hidden from list/get by default.
const post = await posts.restore("01JKX...");
const total = await posts.count();
const published = await posts.count({ filter: { published: true } });
const result = await posts.list({
filter: { published: true },
sort: "-_created_at",
limit: 20,
page: 1,
});
result.items; // (Post & BunBaseRecord)[]
result.total; // total matching records
result.next_cursor; // cursor for next page (null if last page)

Simple equality:

await posts.list({ filter: { published: true } });
await posts.list({ filter: { score: 42 } });

Operator filters:

await posts.list({
filter: {
score: { gte: 10 },
title: { like: "%bunbase%" },
},
});
OperatorMeaning
eqEqual
neNot equal
gtGreater than
ltLess than
gteGreater than or equal
lteLess than or equal
likeSQL LIKE — use % as wildcard
inIn array: { status: { in: ["draft", "published"] } }
await posts.list({ sort: "-_created_at" }); // descending
await posts.list({ sort: "score,-_created_at" }); // multiple fields

Prefix - for descending.

More efficient than offset pagination for large datasets:

// Page 1
const page1 = await posts.list({ limit: 20 });
// Page 2
if (page1.next_cursor) {
const page2 = await posts.list({ limit: 20, after: page1.next_cursor });
}

When after is set, page is ignored.

const result = await posts.list({
fields: ["_id", "title", "published"],
});

Inline related records declared via the relations API:

// "one" relation — expand the foreign key field
const result = await posts.list({ expand: ["author_id"] });
// Each post.author_id is now the full user object.
// "many" relation — expand the reverse side
const user = await client.collection("users").get(id, {
expand: ["posts"],
});
// user.posts is a Post[] array.
const all = await posts.list({ include_deleted: true });
const results = await posts.list({ search: "hello world" });
// Composable with filters, sort, and pagination:
const results = await posts.list({
search: "bun native",
filter: { published: true },
sort: "-_created_at",
limit: 20,
});

The search param maps to the server’s FTS5 index. Prefix queries (bun*), phrase queries ("bun native"), and boolean operators (bun AND native) are supported.

Run up to 100 create/update/delete operations atomically. All succeed or all roll back.

const results = await posts.batch([
{ op: "create", data: { title: "Hello" } },
{ op: "update", id: "01JKX...", data: { status: "published" } },
{ op: "delete", id: "01JKW..." },
]);
// results[0] → { op: "create", record: { _id: "01JKY...", ... } }
// results[1] → { op: "update", record: { _id: "01JKX...", ... } }
// results[2] → { op: "delete", id: "01JKW..." }

If any operation fails, batch() throws a BunBaseError with a 400 status and a message indicating which operation failed.

posts.channel // "collection:posts"
posts.recordChannel(id) // "record:posts:01JKX..."

Use with client.realtime.subscribe().

MethodDescription
list(query?)List records with optional filter/sort/page/search
get(id, options?)Get a single record
create(data)Create a record
createMany(items[])Create multiple records in parallel
update(id, patch)Partial update
delete(id)Soft-delete
restore(id)Restore a soft-deleted record
count(query?)Count matching records
batch(operations[])Atomic batch create/update/delete
channelReturns the collection channel string
recordChannel(id)Returns the record channel string