Standards Docs
Concepts

Records

Runtime instances of objects: how to fetch, create, update, and delete them with React hooks.

Records are the runtime instances of objects. The React hooks in @stndrds/react load and mutate them.

// @noverify
import { useCreateRecord, useRecords } from "@stndrds/react";

function ContactList() {
  const { data: contacts, isLoading } = useRecords("contacts");
  const create = useCreateRecord("contacts");

  if (isLoading) return null;

  return (
    <ul>
      {contacts?.data.map((c) => (
        <li key={c.id}>{c.values.firstName}</li>
      ))}
    </ul>
  );
}

useRecords takes the object name as a positional string argument, not a config object. The response is { data: TypedRecord[], total: number }.

Hook surface

HookUse case
useRecordfetch one record by id
useRecordsfetch a list
useSearchRecordstext search
useInfiniteSearchRecordspaginated search
useCreateRecordcreate
useUpdateRecordupdate
useDeleteRecorddelete single (soft — moves to archive)
useRestoreRecordrestore a soft-deleted record
usePurgeRecordpermanently destroy a soft-deleted record
useBulkDeleteRecordsbulk delete
useObject / useObjectsfetch object definitions
useMyProfilecurrent actor
useSchemaClientdirect client access (escape hatch)

Query keys

Always use the recordsKeys factory from @stndrds/react when interacting with the query cache. Never write ad-hoc key arrays — the factory guarantees that invalidations cover all cache shapes (list, detail, grid, kanban).

// @noverify
import { recordsKeys } from "@stndrds/react";
import { useQueryClient } from "@tanstack/react-query";

const queryClient = useQueryClient();
queryClient.invalidateQueries({
  queryKey: recordsKeys.list("contacts"),
});

Available keys: all, lists, list, details, detail, grids, grid, kanbans, kanban, search, searchInfinite.

Optimistic updates

Optimistic update logic lives in @stndrds/react hooks (useUpdateRecord.onMutate). The pattern snapshots all relevant caches, applies the update immediately, and rolls back on error. Do not replicate this logic in @stndrds/ui components.

Optimistic updates belong in @stndrds/react, never in @stndrds/ui. The useRecordSave hook in @stndrds/ui is a thin wrapper — it does not touch the query cache.

Deletion is now a soft-delete: useDeleteRecord archives the record (sets deletedAt) and cascade-archives its edges. Restore via useRestoreRecord — only cascade-tagged edges wake up; edges independently archived stay archived. To permanently destroy a record, soft-delete it first, then call usePurgeRecord (requires manage permission).

On this page