Blocks
Pick the features your app needs
Each block is a SQL module in your schema, with a TypeScript side for most of them. Install one with npx better-supabase sql add, and the modules it needs come with it. This list is built from the module registry, so it matches the package.
104 blocks
- updated_at triggersupdated-atKeeps an updated_at column current on every update.Foundation
- Actor stampingactorSets created_by on insert and updated_by on every write from auth.uid(); an update keeps created_by and the impersonation stamp. Service writes keep the values they send.Foundation
- Audit logauditRecords inserts, updates and deletes with the actor and changed columns for tables you register, plus semantic events through audit_event(), with redaction, an append-only guard, a tenant read policy and per-tenant retention as options.Operations
- Tenant memberships and permission helpertenantMemberships with roles, member_organization_ids() and has_organization_role() for RLS policies, and membership_claims() for the access token hook. Adopt an existing memberships table through sql.modules.tenant.Foundationneeds updated-at
- Invitationsinvitationsinvite_member(tenant, email, role) returns a single-use token whose hash is stored; accept_invitation(token) checks the signed-in user's confirmed email and, again, the inviter's authority. Roles follow the access model; a null tenant invites to a platform role, stored in platform_invitations.Foundationneeds tenantneeds accessneeds updated-at
- Reserved slugsreserved-slugsA slug format and length check and a list of reserved words (admin, api, www, ...), enforced by a trigger.Foundation
- Job queuejobsTyped jobs on Supabase Queues (pgmq) or a plain table (modules.jobs.options.backend): leases, retries with backoff, dead letters, deduplication keys, queue stats, and schedules with pg_cron or the drain route.Platform
- Idempotency keysidempotencyStores responses by Idempotency-Key so retried requests replay the first result instead of running twice.Platform
- Webhook inboxwebhook-inboxStores verified webhooks once per message id, per tenant when given, then processes them with leases, retries and checkpoints; adopt mode runs over an app's table.Platform
- Realtime table changesrealtime-tablesBroadcasts a change signal (no row data) once per statement on bs:t:<schema>.<table>[:<tenant>], or bs:t:<schema>.<table>:u:<user> for realtime.users tables, for live queries.Platform
- JSON Schema checks for jsonbjsonb-schemaspg_jsonschema check constraints for jsonb columns with a `schema` in the `json` config, so the database enforces the same shape as the types. A trigger reports what failed through jsonschema_validation_errors, which the client maps to a validation error.Platform
- pgTAP helperspgtaptests.create_user, tests.authenticate_as and tests.rls_enabled for `supabase test db`. Written to supabase/tests, never to your schema.Platform
- Data API grantsgrantsWrites the complete Data API privileges of the tables and functions in the `expose` config for anon, authenticated and service_role, or derives table grants from the policies. Supabase no longer grants new tables to the Data API roles automatically.Platform
- Read setsread-setsOne `stable` function per `defineReadSet` in `readSets`, so `db.$many(readSet, params)` is a single GET.Platform
- MFA enforcementmfamfa_satisfied() for restrictive policies: true when the caller has no verified factor, or verified one in this session (aal2).Foundation
- Stripe entitlementsentitlementsActive Stripe entitlements per tenant from the Stripe Sync Engine, feature_claims() for the access token hook, and has_entitlement() and tenant_ids_with_entitlement() for RLS.Billing & commerceneeds tenant
- Write rate limitsrate-limitFixed-window limits on Data API writes (POST, PATCH, PUT, DELETE) per user or claim, checked by pgrst.db_pre_request. Over the limit: 429 with Retry-After.Platform
- Vector searchvector-searchsearch_<table>(query, k) for each table in vectorSearch: the k nearest rows the caller can read, with pgvector iterative index scans so RLS filters still return k rows.AI
- Access contractaccesscan(), tenant_ids_with() and is_platform(): one permission contract for policies and SQL modules, over a roles list, a role and permission catalog, an authorization provider or the app's own functions (modules.access.model).Foundationneeds tenant
- Support sessionssupport-sessionsLets platform staff view the app as a user: time-limited, read-only by default, gated by is_platform() and a second admin's approval, recorded in the audit log, with the target's claims built by your access token hook.Operationsneeds accessneeds audit
- Organizationsorganizationscreate_organization(attrs) with slug rules and an after-create hook, a deferred owner check, an assignment ceiling, and member functions (role change, remove, leave, transfer ownership) on the access contract.Foundationneeds tenantneeds accessneeds updated-at
- ProfilesprofilesA profile per user, created on sign-up from auth metadata with a unique username, an email mirror, column-level update grants and a guard on columns the service owns.Foundation
- OutboxoutboxEvents written in the same transaction as the change, read by named consumers with their own cursor and lease, kept for history and relayed as CloudEvents.Platform
- NotificationsnotificationsIn-app notifications sent through a security definer notify(): one event per change, per-recipient read, dismissed and resolved state, per-channel deliveries, subject subscriptions, preferences with a tenant override, and realtime on a private topic.CollaborationReactneeds updated-at
- Outgoing webhookswebhooks-outOutgoing webhooks: endpoints subscribed to event types, a delivery log unique per endpoint and event with leases and retries, direct dispatch, secrets in Vault with overlap while rotating, auto-disable after an endpoint keeps failing and redelivery.Platformneeds updated-at
- Session revocationsessionssession_active() for restrictive policies: false once the caller's session was signed out or expired, or the user was banned or deleted, so revoked access tokens stop working before they expire. options.policies writes the policy on every table.Foundation
- Incoming webhook endpointswebhooks-inPer-tenant trigger URLs with a hashed token, optional Standard Webhooks or HMAC verification, a body size limit, receive counters and the last status; deliveries go to the webhook inbox with the endpoint's tenant.Platformneeds accessneeds updated-atneeds webhook-inbox
- API keysapi-keysHashed API keys for tenants and users with scopes, expiry, rotation with a grace period, a per-key rate limit and throttled last-used tracking. verify_api_key() backs apiKeyResolver; has_scope() and api_key_tenant() go in policies.Platformneeds tenantneeds access
- SettingssettingsPer-user, per-organization and platform-wide settings as key-value jsonb rows. Users read and write their own; organization settings check settings.read and settings.update; platform settings check a platform permission per key. Keys with a JSON Schema in options.schemas get a pg_jsonschema check.Foundationneeds tenantneeds access
- Usage metering and quotasusageUsage counters per tenant, meter and day with idempotent increments, quotas per tenant or plan, within_quota() for policies and consume_quota(), which raises quota_exceeded. unreported_usage() feeds reportUsageToStripe.Billing & commerceneeds tenantneeds access
- Stripe billingbillingEach tenant's Stripe customer, seat counts (options.seatRoles) and the active subscription item from the Stripe Sync Engine, for createBilling(): checkout, the customer portal, seat sync and Stripe webhook handling.Billing & commerceneeds tenantneeds access
- Feature flagsflagsFeature flags with variants, targeting rules over tenant, user, plan and role, overrides and a percentage rollout bucketed by SHA-256. flag_enabled() goes in policies; createFlagsProvider() evaluates the same way for OpenFeature.Operationsneeds tenant
- Comments and activitycommentsComments on any subject in a tenant, with replies, mentions that notify (with the notifications module) and comment.* outbox events, plus an activity_entries feed that activitySink() fills from outbox events, filtered by can_subject and joined with the subject's audit entries when subjects and audit are installed.Collaborationneeds tenantneeds access
- AttachmentsattachmentsFiles linked to records in a tenant: a record per file, a private bucket whose policies only accept an upload a pending record expects, and reads only for scanned files. confirm_attachment() emits attachment.uploaded for the app's scan job.Collaborationneeds tenantneeds access
- Data lifecycledata-lifecycleData exports per user or organization from every installed module's tables and the app's, written to a private bucket by the app's export job, and organization deletion with a grace period that disables the tenant before a purge job deletes its rows.Operationsneeds tenantneeds access
- SSO and SCIMssoVerified email domains with auto-join and SSO enforcement, SAML providers per organization registered with Supabase Auth, and SCIM 2.0 users and groups that provision memberships and map groups to roles.Foundationneeds tenantneeds access
- OnboardingonboardingOnboarding checklists per user or organization: the completed steps, completed by hand or by an outbox event type. Organization checklists check onboarding.read and onboarding.complete.OperationsReactneeds tenantneeds access
- Waitlist and invite codeswaitlistA waitlist with positions and approvals, and hashed invite codes with a use limit, an expiry and an optional organization and role. waitlist_admit() backs a before-user-created hook that only lets approved addresses or valid codes sign up.Operationsneeds tenantneeds access
- AnnouncementsannouncementsIn-app announcements for everyone, tenants, roles or plans within a time window, with per-user dismissals and a Realtime broadcast when they change. Staff manage them with announcements.manage on the platform.OperationsReactneeds tenantneeds access
- Durable streamsstreamsOrdered text chunks a writer appends and any reader resumes from an index: idempotent batches, a cancel flag the writer reads on its next append, owner reads through RLS, a payload-free Realtime ping on a private topic per stream, and a purge for expired streams.Platform
- Credentials in VaultcredentialsThird-party tokens and API keys in Supabase Vault as bs:cred:<provider>:<name>, behind security definer credential_get, credential_set and credential_delete functions only the service role may call. vaultCredentials() in better-supabase/credentials resolves credential references through them.Platform
- WorkflowsworkflowsEngine-neutral workflow runs that members read through RLS, with a Realtime ping per status change and workflow_run.completed, .failed and .cancelled outbox events; cron schedules with idempotent fires, counting semaphores, admission control for starts (concurrency, debounce, singleton) and a retention purge.OperationsReactneeds tenantneeds access
- Workflow SDK Worldworkflow-sdk-worldThe tables of the Workflow SDK World (@workflow/world-postgres 5.0.4) in the workflow schema, closed to the API roles; a trigger that copies each run into workflow_runs, and a pg_net dispatcher for the delivery queue on a pg_cron schedule.Operationsneeds workflowsneeds jobsneeds access
- Workflow builderworkflow-builderWorkflow definitions a tenant edits as an engine-neutral node graph, with draft, published and archived versions, triggers (webhook tokens stored hashed), credential references a CredentialProvider resolves, a synced step library, per-node run status pinged on the run's topic, and failed and slow alerts written as workflow_alert.triggered outbox events.OperationsReactneeds workflowsneeds tenantneeds access
- Chat SDK statechat-sdk-stateThe Chat SDK StateAdapter in Postgres for better-supabase/chat-sdk: thread subscriptions, token locks, a TTL cache, capped lists and per-thread queues under a key prefix, plus the bot installations per workspace with a credential_ref instead of the token. Service role only.Collaboration
- Shared inboxinboxConversations with contacts across the in-app widget and chat channels: inboxes, members and teams, contacts with their channel identities, messages and internal notes, mentions, assignment, bot hand-off, read state, delivery status, stored webhook events and message templates. Staff read with inbox.read; contacts read their own conversations without the notes; Realtime pings carry ids only.CollaborationReactneeds tenantneeds accessneeds updated-atneeds teams
- AI chatai-chatChats, projects and a branching message tree in the canonical AI message format, with runs (and the id of a durable engine's run), run steps for progress, a compare-and-set stream claim, harness sessions, tool approvals and policies, pending inputs, cited sources, feedback, hashed share links, a model catalog per plan, moderation events and private Realtime topics per chat and per user.AIReactneeds tenantneeds accessneeds streams
- AI filesai-filesFiles and documents for AI chats: a private bucket whose policies only accept an upload a reserved record expects, provider file references with expiry, versioned documents with suggested edits, and a purge that hands back the objects to remove.AIneeds tenantneeds access
- KnowledgeknowledgeDocuments and chunks for retrieval with an embedding and a tsvector each, scoped to an organization, agent, project, chat or user; hybrid search with reciprocal rank fusion, chunks that keep their embedding when unchanged, and an embed job per document when jobs is installed.AIneeds tenantneeds accessneeds vector-search
- MemorymemoryMemory for AI assistants: core memory as files under /memories edited with view, create, str_replace, insert, delete and rename with version checks; archival facts with hybrid similarity search; message embeddings to recall earlier chats, skipped for temporary chats; and versioned documents under an opaque scope key for agent runtimes such as eve.AIneeds tenantneeds accessneeds vector-search
- AgentsagentsCustom assistants with instructions, a model, tools, connectors, knowledge scopes and starters; private until published to the organization or the public store, with installs, ratings and provider skills.AIneeds tenantneeds access
- ConnectorsconnectorsMCP servers per tenant with no, per-user OAuth or header auth; per-user grants that hold only a credential_ref; MCP sessions per chat; and tool list fingerprints that hold a changed list until an admin approves it.AIneeds tenantneeds access
- AI scheduled tasksai-tasksPrompts a user schedules on a cron, with a run per occurrence; the scheduler claims due tasks, queues an ai_task_run job when jobs is installed, and fails runs that stall.AIneeds tenantneeds access
- Push devicespushThe push tokens of each user's devices (Expo, FCM, APNs or Web Push) with RLS, behind register_push_device and unregister_push_device for the user and push_tokens_for and prune_push_tokens for the service role. better-supabase/blocks/push registers Expo devices and sends through the Expo Push API.Collaboration
- AI response cacheai-cacheModel responses cached by a key the application derives from the request, with a TTL capped by maxTtl, hit counts and a purge of expired entries; only the service role reads and writes it.AI
- AI providersai-providersA tenant's own provider keys as credential_ref rows, and a registry of provider batch jobs with their results and a poll claim. Sandboxes live in ai-chat.AIneeds tenantneeds access
- Number sequencesnumber-sequencesGapless numbers per tenant, entity and period. next_number locks the row in the caller's transaction, and a trigger fills the document column so a separate round trip cannot open a gap.Platformneeds tenantneeds access
- TeamsteamsTenant teams and their members. Inbox assignment uses these rows instead of its own team tables.Foundationneeds tenantneeds access
- TagstagsTenant tags with a kind, and a link from a tag to a subject. Adopt mode can use one link table per subject.Workneeds tenantneeds access
- State machinestate-machineAllowed status transitions as the caller, a history row and a status.changed event. A machine can also write a stages timeline and keep a lifecycle row (pause, flags, pinned version). Each machine is a subject table named in options.machines, or a config.subjects type.Workneeds tenantneeds access
- Custom fieldscustom-fieldsField definitions, options and typed values. A sensitive value is readable only with the field's permission. Inline layout stores the definition on the value row.Workneeds tenantneeds access
- Share linksshare-linksHashed share links, view counts and per-user state. The token is returned once. Resolving a link hashes the token the caller presents, so a stored plaintext token keeps working after it is hashed.Collaborationneeds tenantneeds access
- RemindersremindersRecurrence rules and reminders. Expansion follows RFC 5545 in TypeScript. Delivery is a job that records reminder.sent once per occurrence.Schedulingneeds tenantneeds accessneeds jobs
- ImportsimportsImport runs. Parsing, mapping and the dry run live in TypeScript. The job records import.completed or import.failed.Contentneeds tenantneeds accessneeds jobs
- SubjectssubjectsThe app-wide subject registry from config.subjects: subject_title, subject_url, can_subject and can_subject_for for every registered type.Foundationneeds access
- RankrankFractional rank keys: rank_between, move() for every config.subjects entry with a rank column (through the caller's policies and any state-machine trigger), and a rebalance job.Workneeds accessneeds subjects
- Saved viewssaved-viewsNamed, ranked list states (filters, sort, columns, grouping, density) for one user, a team or the whole tenant.WorkReactneeds tenantneeds access
- RelationsrelationsTyped links between subjects (blocks, parent, relates, or your own kinds), with inverse names, cycle checks, one-target kinds, walks and rollups.Workneeds tenantneeds access
- Bulk actionsbulkOne action over many rows: up to a limit in one call with a result per row, and larger sets as a background run on the jobs queue that runs as the user who started it.Workneeds tenantneeds access
- SearchsearchA search_documents index kept up by triggers from each config.subjects search entry, with search(q) as the caller (websearch, trigram prefixes, can_subject, hybrid with embeddings), and recents and favorites from the share-links user state.WorkReactneeds tenantneeds accessneeds subjects
- MetricsmetricsMetrics declared with defineMetric over a table (count, sum or avg per time bucket and dimension), rolled up into metric_points or read from the table, with metric_series and metric_value checked against a permission in the tenant.Operationsneeds tenantneeds access
- CalendarcalendarCalendars, events with RFC 5545 recurrence (RRULE, EXDATE and per-occurrence overrides) and attendees. Series expand in TypeScript with the reminders block's expandRule; a share link serves an iCal feed.SchedulingReactneeds tenantneeds access
- BookingsbookingsBookable resources with weekly hours and exceptions, services with durations and buffers, and bookings that a gist exclusion constraint (btree_gist) keeps from overlapping per seat. Holds expire; a share link opens public booking; confirmed bookings mirror into the calendar and reminders.SchedulingReactneeds tenantneeds access
- VersionsversionsNumbered snapshots of a subject's content: manual, debounced auto and frozen snapshots, restore through columns or an apply function, and retention.Contentneeds tenantneeds access
- TrashtrashSoft delete through each subject's deletedAt column: trash with children in one batch, restore with unique checks, a list per organization, and purge after a retention period.Contentneeds tenantneeds access
- ReactionsreactionsEmoji reactions on any subject, comments and inbox messages, with per-tenant custom emoji, counts per subject under the subject's own read rules and a realtime topic per tenant.CollaborationReactneeds tenantneeds access
- ApprovalsapprovalsApproval requests with steps per subject type and action: approvers by permission, role, team or user, a required count, delegation, expiry and reminders. The final approval runs a state-machine transition or a job.Workneeds tenantneeds access
- Access requestsaccess-requestsMembers ask for a role, for a set time if they like. The request goes through approvals; the final approval grants the role, and the grant ends early on request or when it expires.Workneeds tenantneeds accessneeds approvals
- Collaborative documentsdocumentsYjs documents attached to any subject: an update log, a compacted snapshot, a private realtime topic per document for updates and presence, and saved states through the versions module.Contentneeds tenantneeds access
- CatalogcatalogProducts with options, variants and prices in minor units, price lists, a category tree, collections and an optional public storefront.Billing & commerceneeds tenantneeds access
- InventoryinventoryStock per catalog variant and location: an append-only movement ledger, reservations with expiry, transfers and purchase orders with partial receiving.Billing & commerceneeds tenantneeds accessneeds catalog
- DrivedriveFolders and files on the attachments module: access granted to users, teams or roles and inherited down the tree, enforced by storage policies too; moves and renames with a name-conflict policy; revisions through versions, a bin through trash, starred and recent items through share-links' user state, and folder share links.Contentneeds tenantneeds accessneeds drive-files
- Drive filesdrive-filesThe part of the drive module that needs attachments, versions, trash and share-links: file uploads and revisions, storage policies, the bin, starred and recent items, folder share links and the purge event. Installed with drive.Contentneeds attachments
- OrdersordersCarts on anonymous or signed-in users, checkout priced from the catalog, gapless order and invoice numbers, payments, fulfillments, returns and refunds.Billing & commerceneeds tenantneeds accessneeds catalog
- PromotionspromotionsPercentage, fixed and free-shipping promotions, automatic or by code, with usage limits and stacking rules, priced into orders carts.Billing & commerceneeds tenantneeds accessneeds catalogneeds orders
- FormsformsForms with numbered versions (steps and show or skip logic), a JSON Schema 2020-12 per version that validates every submission, drafts, public links through share-links with a rate limit and a bot-check hook, and handlers that turn a submission into a record.ContentReactneeds tenantneeds accessneeds jsonb-schemas
- SignaturessignaturesSimple electronic signatures on a frozen version of a record: drawn, typed or click signatures in parallel or in order, a hash that detects edits after signing, and an approval step a signer can decide.Contentneeds tenantneeds accessneeds versions
- Time trackingtime-trackingTime entries with one running timer per member and no overlaps, on any record, billable with a rate. Weekly timesheets go through approvals, and a submitted or approved week is locked.Schedulingneeds tenantneeds accessneeds approvals
- IdentitiesidentitiesLinks an email address or a chat user to an app user or a contact. Rows come only from a one-time code the signed-in user issues and the service redeems, or from a confirmed address in auth.users.Foundation
- Service principalsservice-principalsNon-human tenant members backed by auth.users rows that can't sign in, with roles through memberships. Organization-owned workflow versions and service webhook endpoints run as the tenant's default principal.Platformneeds tenantneeds access
- TemplatestemplatesTyped, versioned templates (system starters and tenant forks) that create records, with merge fields and workflows started on each record they create.Contentneeds tenantneeds access
- PipelinespipelinesTenant-editable pipelines for any registered subject: ordered stages whose categories map to open, success or failure, a stage history with time in stage, board totals per currency and a status mapping that runs through state-machine.Workneeds tenantneeds accessneeds subjects
- PartiespartiesCompanies and people an organization works with: lifecycle stages, owners, who works where with a role and a primary contact, domain and email dedupe, merges and keyset-paged search.CRM & salesneeds tenantneeds access
- EngagementsengagementsCalls, emails, meetings, notes and tasks logged on one or more registered records, with an owner, a due time and an outcome, a record's timeline, its next step and a member's open tasks.CRM & salesneeds tenantneeds accessneeds subjects
- DealsdealsDeals on pipelines: amounts in minor units, a company and contacts, a deal team, line items, forecast calls with attainment, close-date slips, a next step, locking and batched edits with per-change rejections.CRM & salesneeds tenantneeds accessneeds subjectsneeds pipelines
- Work itemswork-itemsIssues and tasks on pipelines: identifiers, parents without cycles, several assignees, priority 0 to 4, estimates, start, end and due dates, locking, projects, iterations, batched edits and a progress tree.Workneeds tenantneeds accessneeds subjectsneeds pipelines
- QuotesquotesQuotes with line items and totals, a revision chain, a public link the customer accepts, rejects or asks changes through, expiry, and quotes from deals.CRM & salesneeds tenantneeds accessneeds subjects
- InvoicesinvoicesInvoices an organization sends its own customers: drafts with lines, a gapless number on issue, payments, credit notes, void and write-off, overdue and aging per currency, and invoices from accepted quotes.Billing & commerceneeds tenantneeds accessneeds subjects
- Service levelsslaService levels on any registered record: first response, next response and resolution clocks from a policy per type and priority, business hours, pauses while the record waits, and warnings and breaches a job records.Workneeds tenantneeds accessneeds subjects
- TargetstargetsGoals per period for a member, a team or the organization, with progress the database computes for won deals, completed work items and paid invoices, or a value the app keeps.CRM & salesneeds tenantneeds access
- HiringhiringJobs and applications on a pipeline per job, candidates from config.subjects, scorecards per stage, interviews, and hire, reject and withdraw events for the app to act on.Workneeds tenantneeds accessneeds subjectsneeds pipelines
- EmployeesemployeesEmployees with or without an account, a manager, team, job title, employment type and status, an org chart, offboarding, and private details and contracts behind employees.view_sensitive.Workneeds tenantneeds access
- CollectionscollectionsFavorites (a member's ranked stars on any registered record) and lists (named, static collections of one subject type owned by a user, a team or the organization), with entries hidden unless the caller can read their record.Workneeds tenantneeds accessneeds subjects
- RLS on every new tableensure-rlsAn event trigger that enables row level security on every table created outside the Supabase-managed schemas, so a new table is never readable through the Data API before it has policies. Install it as postgres: supautils lets that role create event triggers.Platform