# VibeFlui / FluiKit LLM Reference VibeFlui is an AI-friendly schema-driven UI framework for React and Next.js. FluiKit is the core component. A JSON-friendly `FluiKitConfig` schema plus a runtime registry plus a page file renders tables, forms, actions, feedback, detail views, dashboard cards, and layouts. Use this file when an AI assistant generates, reviews, migrates, or refactors VibeFlui code. Official docs: - Docs home: https://vibeflui.com/docs - AI Guide: https://vibeflui.com/docs/ai-guide - AI Source Map: https://vibeflui.com/docs/ai-guide/source-map - Schema reference: https://vibeflui.com/docs/schema/root-schema - API reference: https://vibeflui.com/docs/api-reference/schema-root Public documentation URLs use rewritten paths without numeric prefixes. For example, use `/docs/ai-guide/source-map`, not `/docs/09-ai-guide/source-map`. ## Mental model ```txt schema (JSON-friendly) + registry (runtime implementations) + page (wiring) -> generated UI ``` VibeFlui is the UI layer only. The backend still owns authentication, authorization, business logic, persistence, workflow, audit logs, and final validation. ## Hard generation rules - Do not invent schema keys, action values, provider behavior, adapter behavior, response statuses, or plugin claims. - Keep schema JSON-friendly. Never put functions, JSX, promises, classes, or runtime objects in schema. - Reference runtime behavior by string keys: `renderer`, `component`, `adapter`, `validator`, `transformer`, `handler`, `permission`, `optionLoader`, `computed`, `classNameResolver`, `message resolver`, hooks, and events. - Register the real functions and components at runtime through `FluiKitProvider`, `createRegistry`, or plugins. - Keep schema, registry, custom components/renderers, reusable handlers, and page wiring in separate files. - Do not put all generated code into one `page.tsx`. - Do not inline JSX inside `createRegistry`. Import components/renderers from their own files, then register them. - Do not inline async handlers inside ``, ``, or page props. Define named functions in a handler/helper file. - Prefer `actions.*.handler` and `actions.row[].handler` with runtime `registry.actionHandlers` for custom action behavior. - Declare expected registry keys in `schema.registry.*` when useful for documentation, inspection, or AI review. - For table custom filters, use `table.filters` with `type: "custom"` and `component`. Do not use form field adapter syntax for table filters. - Prefer boolean `status` (`true`/`false`) for generated examples. Recognized string statuses (`"rejected"`, `"accepted"`, `"failed"`, etc., see Response contract) are also valid and are matched case-insensitively — do not claim `status` is boolean-only. - Use `code: 200` in generic docs examples unless explaining REST creation semantics. - Use `.test` email domains in examples, such as `ada@example.test`. - Avoid `any` in TypeScript examples. Use `unknown` plus narrowing or exported VibeFlui types. - If a feature is not in the current source, package docs, or official docs, mark it unverified instead of presenting it as available. - Do not document roadmap items as supported runtime features. ## Recommended file organization ```txt app//page.tsx schemas//.resource.schema.ts components/vibeflui/renderers//... components/vibeflui/fields/... lib/vibeflui/registry.tsx lib/vibeflui/handlers/.actions.ts ``` Page files should mainly import schema/registry and render: ```tsx "use client" import { FluiKit, FluiKitProvider } from "@vibeflui/core" import { userSchema } from "@/schemas/users/user.resource.schema" import { vibefluiRegistry } from "@/lib/vibeflui/registry" export default function UsersPage() { return ( ) } ``` ## Response contract Backend handlers and endpoints should return this mutation response shape: ```ts type FluiKitMutationResponse = { status: boolean | string code?: number | string message?: string data?: TData } ``` Status resolution: - `status: true` -> success feedback. - `status: false` with `code` 400..499 -> warning feedback for expected business or validation responses. - `status: false` with `code` 500+ -> error feedback for server/runtime failures. - Recognized string statuses (case-insensitive) also resolve directly: `"success"`/`"succeeded"`/`"ok"`/`"accepted"` -> success, `"rejected"`/`"warning"` -> warning, `"failed"`/`"failure"`/`"fail"`/`"error"` -> error. - If `status` is neither a recognized boolean/string nor accompanied by a resolvable `code`, VibeFlui cannot determine an outcome and falls back to displaying success feedback by default — always return a recognized `status` value instead of the backend's raw, unmapped field names. Examples: ```ts return { status: true, code: 200, message: "User saved successfully.", data: user } return { status: false, code: 409, message: "Email is already registered." } return { status: false, code: 500, message: "Unable to save the user." } return { status: "rejected", code: 409, message: "Email is already registered." } // also valid ``` Prefer the boolean `status` + numeric `code` form for generated examples — it is unambiguous — but a backend's recognized string `status` (e.g. `"rejected"`) is not invalid. ## Minimal usage ```ts import type { FluiKitConfig } from "@vibeflui/core" export const userSchema = { resource: "users", endpoint: "/api/users", table: { columns: ["name", "email", "role.name", "status"] }, form: { fields: ["name", "email", "roleId"] }, actions: true } satisfies FluiKitConfig ``` ```tsx import { FluiKit } from "@vibeflui/core" import { userSchema } from "@/schemas/users/user.resource.schema" export default function Page() { return } ``` ## Root schema keys Root type: `FluiKitConfig`. Only `resource` is required. - `resource`: required resource key used by table, form, actions, messages, and endpoints. - `version`, `title`, `description`: metadata/display text. - `mode`: compact mode, `"static" | "server" | "readonly"`. - `dataMode`: explicit data loading mode, `"static" | "server"`. - `uiMode`: `"interactive" | "readonly"`. Readonly disables mutation/action execution in the UI. - `adapter`: UI adapter key or config. It does not install dependencies or register components by itself. - `identity`: `{ key, param }` for row identity and endpoint placeholders. - `endpoint`: string or operation map for REST-style endpoint execution. - `provider`: provider metadata. Core has a REST endpoint provider and supports runtime registered providers. Non-REST provider types require an implementation/plugin. - `handlers`: operation-to-handler key map. Supported as an alias path; prefer action-level `handler` for new examples. - `theme`: preset, class names, variants, color mode, conditional classes, and resolver keys. - `layout`: page, tabs, wizard, sections, and surface configuration. - `dashboard`: KPI/card configuration. - `table`: columns, search, filters, sorting, pagination, row selection, export, state, and row actions. - `form`: fields, grid, groups, sections, mode, labels, validation, options, and transforms. - `detail`: read-only detail view configuration. - `actions`: built-in create/edit/delete/view plus row, bulk, and toolbar actions. - `permissions`: UI permission keys, role arrays, or declarative conditions. Backend must still authorize. - `hooks`, `events`: lifecycle and event string keys resolved through the registry. - `transform`: request/response/before-submit transformer keys. - `registry`: declarative list of registry keys expected by the schema. - `persist`: table state persistence config. - `messages`: defaults, source priority, and resolver key. - `feedback`: feedback mode, icons, class names, enabled flag. - `debug`: debug and inspector metadata. - `resources`: child `FluiKitConfig[]` for multi-resource screens. - `ai`: optional metadata only. It does not change runtime behavior. ## Data loading and execution - `endpoint` can be a string or operation map: ```ts endpoint: { list: "/api/users", create: "/api/users", update: { url: "/api/users/:id", method: "PATCH" }, delete: { url: "/api/users/:id", method: "DELETE" } } ``` - Endpoint placeholder values come from `identity`, for example `{ key: "id", param: "id" }`. - Execution priority: `action.handler` -> `schema.handlers[key/operation]` -> `provider` -> `endpoint`. The first source that resolves wins; if none resolve, VibeFlui does not throw — it shows success feedback assuming completion, so always wire a real source. - `provider.type: "rest"` uses core endpoint execution only when `provider.name` is not set; if `name` is set, the named runtime provider is used instead, regardless of `type`. - `provider.type` also accepts `"graphql"`, `"trpc"`, `"supabase"`, `"firebase"`, and `"custom"` as schema values, but core does not automatically implement those backends. Register a runtime provider or use an official/community plugin. - Server-mode tables can use `table.dataPath` and `table.totalPath` for nested responses. - On server load errors, the table wrapper/header should remain visible and the error message is rendered inside the table body. ## Table schema Common keys: `enabled`, `mode`, `dataPath`, `totalPath`, `minWidth`, `columns`, `search`, `filters`, `sort`, `pagination`, `rowSelection`, `rowNumber`, `actionGrouping`, `actionIcon`, `columnVisibility`, `states`, `export`, `className`. - `columns`: string array or column objects. - Column object keys include `key`, `label`, `type`, `width`, `sortable`, `searchable`, `filterable`, `hidden`, `visibleWhen`, `renderer`, `computed`, `className`, `headerClassName`, `cellClassName`, and `classNameWhen`. Of these, only `cellClassName` (applied to ``, merged with the `tableCell` theme slot) and `headerClassName` (applied directly to ``, not a theme slot) are read by the core renderer; plain `className` and `classNameWhen` at the column level are schema metadata only. - Column `type`: text, number, date, datetime, boolean, badge, email, custom, computed. - Use `type: "custom"` plus `renderer: "StatusBadge"` for registry-rendered cells. - `minWidth` keeps the wrapper max-width at 100% and lets the table scroll horizontally. - `columns[].width` supports percentage strings or numbers. If one visible data column has a width, other visible data columns share the remaining percentage after fixed utility widths for row number, action, and selection columns are reserved. - `search`: `{ enabled, placeholder, param }`. - `filters`: `{ key, label, type, options, optionLoader, component, trueLabel, falseLabel, placeholder }[]`. - Filter `type`: text, select, date, boolean, custom. - Custom filters use `component` and a registered component key. - `actionGrouping` defaults to true. When more than three visible row actions exist, up to two priority actions stay visible before overflow actions go behind `lucide:list-collapse`. Priority is view/detail, update/edit, then delete. - `actionIcon`: `{ hoverShape, hoverColor, hoverClassName }`. `hoverShape` is `"rounded"` or `"circle"`. ## Form schema Common keys: `enabled`, `mode`, `fields`, `groups`, `sections`, `width`, `grid`, `submitLabel`, `cancelLabel`, `className`. - `mode`: `modal` (default), `drawer`, `page`, or `inline`. - `grid`: `{ columns, gap, className }`, where columns can be a number or responsive object. - `groups`: presentational grouping over existing `fields`. - `sections`: sectioned form layout when groups are absent. - `fields`: string array or field objects. Field object keys include `name`, `label`, `type`, `valueFrom`, `editValueMode`, `createValueMode`, `defaultValue`, `hidden`, `disabled`, `readonly`, `placeholder`, `helperText`, `component`, `adapter`, `adapterProps`, `validator`, `required`, `min`, `max`, `minLength`, `maxLength`, `pattern`, `validationMessage`, `transformer`, `computed`, `computedFrom`, `visibleWhen`, `options`, `optionsEndpoint`, `optionsDataPath`, `optionLoader`, `optionLabelKey`, `optionValueKey`, and `className`. `adapterProps` (`Record`) is passed through to the field's `adapter`/`component` implementation (e.g. `@vibeflui/editors`'s `editorjs` adapter); core itself does not read it. Field types include text, email, password, number, textarea, select, multiselect, checkbox, checkbox-group, radio, radio-group, switch, date, datetime, time, file, image, hidden, color, range, json, code, richtext, markdown, tags, combobox, autocomplete, and custom. Use `switch` for toggle, on-off, and slide controls. Use `checkbox` for a normal checkbox, `checkbox-group` for multiple selections from options, and `radio` or `radio-group` for single selection from options. Do not generate `checkbox-toggle`; it is not an official field type. Validation: - Built-in: `required`, `minLength`, `maxLength`, `min`, `max`, `pattern`, and email format. - `min`/`max` compare as numbers for number-like fields and as date-like values for `date`/`datetime`; date bounds may be strings such as `"2024-01-01"` or `"2024-01-01T09:00"`. - Registry validator: `validator: "phoneValidator"` for advanced or async validation. Runs only after built-in rules already pass. - Backend still owns final validation. Computed fields: - Use `computed` for the registry resolver key. - Use `computedFrom` as a string or string array dependency list. The runtime reruns computed resolvers when those paths change and preserves the previous computed value when unrelated fields change. ## Actions `actions: true` enables defaults. Or use: ```ts actions: { create: { enabled: true, label: "Add User" }, edit: { enabled: true }, delete: { enabled: true, confirm: true }, view: { enabled: true }, row: [], bulk: [], toolbar: [] } ``` Action keys include `key`, `enabled`, `label`, `icon`, `tooltip`, `ariaLabel`, `display`, `iconOnly`, `variant`, `confirm`, `endpoint`, `method`, `handler`, `permission`, `visibleWhen`, `disabledWhen`, `refreshOnSuccess`, and `className`. - `variant`: default, primary, secondary, danger, ghost. - Icons are Iconify keys, such as `mdi:check` or `lucide:list-collapse`. - Row actions render as borderless icon buttons with tooltip/aria-label and separators between visible icons. - Delete/danger actions keep red danger styling. - Custom row action behavior should usually use `handler`. ```ts actions: { row: [ { key: "approve", label: "Approve", icon: "mdi:check", display: "icon", handler: "users.approve", visibleWhen: { key: "status", operator: "equals", value: "pending" } } ] }, registry: { actionHandlers: ["users.approve"] } ``` Runtime: ```ts import { createRegistry } from "@vibeflui/core" import { approveUser } from "./handlers/users.actions" export const vibefluiRegistry = createRegistry({ actionHandlers: { "users.approve": approveUser } }) ``` ## Confirm dialogs and feedback - `confirm`: `true` or `{ title, description, icon, confirmLabel, cancelLabel, secondConfirm }`. - `secondConfirm` is optional and can be `true` or a second-step config object. - Confirm dialogs use Iconify icons. - Feedback defaults to modal mode. - `feedback.mode: "inline"` renders Tailwind alert-style feedback. - Feedback icons are configured with Iconify keys: `success`, `error`, and `warning`. ## Layout, detail, dashboard, resources - `layout.type`: page, tabs, wizard, sections. - `layout.tabs` and `layout.steps` reference form field names. - `form.sections` is supported. - In single-resource layouts, `layout.tabs` or `layout.sections` items with `table: true` or `form: true` place the table or an always-visible create form in that tab/section. Items with only `fields` remain form layout metadata. `layout.steps` (`type: "wizard"`) does not support this — wizard steps are for form field grouping only. - `resources` renders the root table/form first when present, then nested child schemas as tabs by default (also for `type: "wizard"`) or stacked sections/page layouts when `type` is `"sections"`/`"page"`. - `detail` renders read-only label/value surfaces, not disabled inputs. - `dashboard.cards` render KPI cards above the table or multi-resource body. Card values can come from `valueFrom` or a card endpoint; card endpoints use the configured custom provider before falling back to REST. - `FluiKitCard` and `FluiKitTab` are exported primitives. ## Conditions and permissions Conditions use: ```ts { key: "status", operator: "equals", value: "active" } ``` Operators: equals, notEquals, contains, notContains, exists, notExists, in, notIn, gt, gte, lt, lte. Permissions are UI-level only: ```ts permissions: { delete: ["admin"], update: "canUpdateUser" } ``` Permission configs can be role/permission arrays, registry resolver keys, or declarative conditions. Backend authorization is still required. ## Registry pattern Schema only declares string keys. Runtime supplies implementations: ```tsx ``` Runtime registry slots: - `components` - `renderers` - `fieldAdapters` - `validators` - `transformers` - `actionHandlers` - `handlers` (supported alias; prefer `actionHandlers`) - `providers` - `permissionResolvers` - `optionLoaders` - `hooks` - `events` - `classNameResolvers` - `messageResolvers`: `(key, context) => string | undefined`; context may include `schema`, `row`, `rows`, `values`, `action`, `mode`, `query`, and `value` depending on the caller. - `computedResolvers` ## Ecosystem packages Install only what the app uses. Optional packages require their peer dependencies and plugin/registry setup. - `@vibeflui/shadcn`: shadcn-style preset/adapters where registered. - `@vibeflui/tailadmin`: TailAdmin preset/adapters and TailAdmin CSS tokens. - `@vibeflui/react-select`: React Select field adapter/plugin. - `@vibeflui/editors`: richtext, code, and markdown editor adapters/plugins. - `@vibeflui/react-query`: TanStack Query provider plugin/integration. - `@vibeflui/antd`: Ant Design adapter/plugin. - `@vibeflui/mantine`: Mantine adapter/plugin. - `@vibeflui/material-ui`: Material UI adapter/plugin. Do not claim an adapter feature exists unless it is verified in that package's README/source or the official docs. ## Task routing - Basic table: read https://vibeflui.com/docs/examples/simple-table and https://vibeflui.com/docs/guide/tables - Basic form: read https://vibeflui.com/docs/examples/simple-form and https://vibeflui.com/docs/guide/forms - Form and table CRUD: read https://vibeflui.com/docs/examples/simple-form-and-table and https://vibeflui.com/docs/guide/feedback/response-contract - Data fetched from a backend API (VibeFlui `server` mode, called from the browser): read https://vibeflui.com/docs/guide/providers/server-mode and https://vibeflui.com/docs/guide/providers/endpoint-config - Custom row actions: read https://vibeflui.com/docs/guide/actions/row-actions and https://vibeflui.com/docs/registry/handlers - Custom filters/adapters: read https://vibeflui.com/docs/guide/tables/search-filters-sort and https://vibeflui.com/docs/adapters - Layout/resources/dashboard: read https://vibeflui.com/docs/guide/layout - Code review: read https://vibeflui.com/docs/ai-guide/review-checklist ## Next.js note FluiKit components are client components. Render `` behind a `"use client"` boundary. Keep server logic in route handlers or server modules. ## Exported core helpers Core exports include `FluiKit`, `FluiKitProvider`, `useFluiKitContext`, `FluiKitForm`, `FluiKitTable`, `FluiKitField`, `FluiKitAction`, `FluiKitDetail`, `FluiKitModal`, `FluiKitConfirmDialog`, `FluiKitFeedback`, `FluiKitCard`, `FluiKitTab`, `FluiKitDashboard`, `createRegistry`, `normalizeSchema`, `validateSchema`, `fluiKitConfigSchema`, `generateResource`, `validateFieldValue`, `inspectSchema`, `migrateSchema`, and the `FluiKitConfig` type. Utility exports include `coerceString`, `toNumber`, `isRecord`, `normalizeOptions`, `resolveStatusTone`, `getByPath`, `setByPath`, and `cn`.