CarpoSDK docs

React hooks

Use TanStack Query hooks for Database, Functions, and Storage work.

The React entry point exposes hooks that use the CarpoProvider client and TanStack Query cache. Place QueryClientProvider above CarpoProvider and call Carpo hooks below them.

Authentication and context

  • useCarpoClient() returns the configured client.
  • useCarpoAuth() returns its native Better Auth React client.

Use Better Auth's useSession() hook for reactive session state. The Carpo provider listens to that session and scopes service query keys by the current identity.

Database reads

HookPurpose
useDatabaseTables(options?)Read visible tables and permissions
useDatabaseRows(table, selectOptions?, queryOptions?)Fetch one bounded result page
useLiveDatabaseRows(table, selectOptions?, queryOptions?)Fetch rows and invalidate them after realtime changes
useInfiniteDatabaseRows(table, selectOptions?, queryOptions?)Fetch page number results with fetchNextPage()
useCursorDatabaseRows(table, selectOptions?, queryOptions?)Fetch successive pages with keyset cursors

Reads accept TanStack Query options such as enabled, select, staleTime, and placeholderData. Carpo provides the query key and query function, and passes TanStack Query's abort signal through to the API request.

Database writes

HookMutation input
useInsertDatabaseRow(table, options?)Row values
useInsertManyDatabaseRows(table, options?){ rows, returning? }
useUpsertDatabaseRows(table, options?){ rows, options } where options includes conflict
useUpdateDatabaseRows(table, options?){ where, values }
useDeleteDatabaseRows(table, options?)where conditions
useInvokeFunction(options?){ functionId, input? }, parsed as JSON

Write hooks accept TanStack mutation options and invalidate the affected table's query keys after a successful write. useInvokeFunction() uses invokeJson(), so it expects a JSON response and reports non successful responses as errors.

Bind hooks to a schema

createCarpoDatabaseHooks<AppDatabase>() returns schema aware versions of useTables, useRows, useLiveRows, useInfiniteRows, useCursorRows, useInsert, useInsertMany, useUpsert, useUpdate, and useDelete.

const db = createCarpoDatabaseHooks<AppDatabase>()

function Todos() {
  const todos = db.useRows('todos', {
    where: { completed: false },
    limit: 25,
  })
  const addTodo = db.useInsert('todos')

  return (
    <>
      <button onClick={() => addTodo.mutate({ title: 'Ship the change' })}>
        Add todo
      </button>
      <pre>{JSON.stringify(todos.data?.rows ?? [], null, 2)}</pre>
    </>
  )
}

Schema types are compile time only. Server table permissions and schema validation remain authoritative.

Storage hooks

Storage hooks are bucket and user scoped. Infinite variants use cursor pagination. Mutations invalidate the affected object, listing, version, or trash keys.

AreaHooks
ClientuseCarpoStorage()
ListingsuseStorageObjects(), useInfiniteStorageObjects()
Object detailuseStorageObjectMetadata(), useStorageObjectExists()
Recovery readsuseStorageObjectVersions(), useInfiniteStorageObjectVersions(), useStorageTrash(), useInfiniteStorageTrash()
MutationsuseUploadStorageObject(), useUpdateStorageObjectMetadata(), useDeleteStorageObjects(), useCopyStorageObject(), useMoveStorageObject(), useRestoreStorageVersion(), useDeleteStorageVersion()
DownloadsuseCreateStorageDownloadUrl(), useDownloadStorageObject()

useUploadStorageObject() takes { file, key, ...options }. Its options match the direct storage.upload(file, options) method. Every Storage hook requires storageBucketId on the combined client.

On this page