Skip to content
BunBase BunBase BunBase Docs Alpha v0.1.0

Querying

Fetch and cache a paginated collection list.

import { useList } from "@bunbase/react-sdk";
function PostList() {
const { data, loading, isRefetching, error, refetch } = useList<Post>("posts", {
filter: { status: "published" },
sort: "-_created_at",
limit: 20,
search: "hello world", // full-text search (FTS5)
});
if (loading) return <p>Loading…</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<>
{isRefetching && <p>Updating…</p>}
{data?.items.map((post) => <PostCard key={post._id} post={post} />)}
<button onClick={refetch}>Refresh</button>
</>
);
}

The second argument to useList is a ListQuery object. All fields are optional:

FieldDescription
filterRecord of { field: value } equality filters, or FieldFilter[] for advanced ops (eq, ne, gt, lt, gte, lte, like, in)
sortField name to sort by. Prefix with - for descending: "-_created_at". Array for multi-sort.
limitMax records per page (default 50, max 500)
pagePage number (1-based)
afterCursor: _id of last record — faster than page for large datasets
fieldsComma-separated field names to return
expandArray of relation field names to inline
include_deletedtrue to include soft-deleted records
searchFull-text search query using SQLite FTS5 — see below

Pass search to filter results by text across all user-defined fields:

const { data } = useList<Post>("posts", {
search: "bun native",
filter: { status: "published" },
sort: "-_created_at",
});

FTS5 query syntax is supported:

  • Prefix: bun* matches bun, buns, bundle, etc.
  • Phrase: "bun native" — exact phrase
  • Boolean: bun AND fast, bun OR deno, bun NOT slow

search composes with filter, sort, and limit — all applied together.

OptionDefaultDescription
staleTime30_000ms before cached data is considered stale
refetchIntervalms between automatic background re-fetches
enabledtrueSet false to skip fetching (e.g. wait for a dependency)
realtimefalseSubscribe to collection events and sync the cache automatically
FieldTypeDescription
dataListResult<T> | undefinedCached result — may be stale while isRefetching is true
loadingbooleanTrue only on the very first fetch (no cached data yet)
isRefetchingbooleanTrue when a background refetch is running with stale data visible
errorError | nullLast fetch error
refetch() => voidManually invalidate and re-fetch

After every successful fetch, useList writes each record into {collection}:get:{id}. This means navigating to a detail page with useRecord will load instantly from cache — no loading state, no extra round-trip.


Fetch and cache a single record by ID.

import { useRecord } from "@bunbase/react-sdk";
function PostDetail({ id }: { id: string }) {
const { data: post, loading, error } = useRecord<Post>("posts", id);
if (loading) return <p>Loading…</p>;
if (error) return <p>Not found</p>;
return <article>{post?.title}</article>;
}

Pass null or undefined as id to skip fetching entirely — useful when the ID comes from a route param that may not be resolved yet:

const { data } = useRecord<Post>("posts", router.params.id ?? null);
OptionDefaultDescription
staleTime30_000ms before cached data is considered stale
expandInline related records declared via the relations API

When you navigate from a list page to a detail page:

1. useList("posts") fetched and cached
└─ also wrote posts:get:abc123 via pre-population
2. navigate to /posts/abc123
useRecord("posts", "abc123")
└─ finds posts:get:abc123 in cache → loading: false, data shown immediately
└─ background refetch runs to revalidate (if stale)
└─ if server returns same data → shallow equal → no re-render
└─ if server returns updated data → re-render with latest
// Always background-refetch on navigation
useRecord("posts", id, { staleTime: 0 });
// Cache aggressively for 5 minutes
useRecord("posts", id, { staleTime: 5 * 60_000 });

useRecord subscribes to record-level realtime updates automatically whenever id is provided. There is currently no separate realtime toggle on this hook.