@declarion/react
v0.12.4
Published
React SDK for Declarion, the schema-driven business apps platform.
Downloads
8,149
Readme
@declarion/react
React SDK for Declarion, the schema-driven business apps platform.
Declarion lets you build production business apps from YAML schemas: entities, screens, navigation, actions, and handlers. This package is the React client that renders those schemas into working UIs against a Declarion API backend.
Install
pnpm add @declarion/react
# peer deps:
pnpm add react react-domSubpath exports
| Import | Purpose |
|---|---|
| @declarion/react | Main React entry — components, hooks, types |
| @declarion/react/icons | Lightweight icon rendering — DynamicIcon + setIconRegistry + built-in glyphs + lazy Lucide, WITHOUT the eager UI bundle (~5 kB gzip). For host/embed apps that render nav from /api/schema. |
| @declarion/react/styles.css | Pre-compiled Tailwind output; import once at the SPA root |
| @declarion/react/vite | Node-only Vite plugin — opt into client staleness handling at build time |
Icons
A DSL icon: value is a NAME resolved against Lucide (the default icon
library, ~1500 glyphs) by name. Resolution order: a consumer-declared icons:
entry served on /api/schema (svg / url / lucide-alias) → the curated built-in
set (src/components/primitives/Icons.tsx, thin wrappers over Lucide, bundled
eagerly for instant render) → Lucide by name (lazy) → folder. A host renders
any icon with one component:
import { setIconRegistry, DynamicIcon } from "@declarion/react/icons";
// once, after the /api/schema fetch (it carries any custom icons):
setIconRegistry(schema.icons ?? {});
// anywhere, any depth - the registry is a module singleton:
<DynamicIcon name={navItem.icon} size={16} />setIconRegistry is a module-level store (mirrors registerScreen); DynamicIcon
subscribes via useSyncExternalStore, so replacing the registry (identity switch)
re-renders every icon. Bare names resolve from Lucide - no registry entry needed.
Lucide's per-icon dynamicIconImports map is loaded only via import() and stays
out of the eager bundle (the curated Icons.tsx set is tree-shaken named imports).
See examples/embed-host for a working host.
The curated built-in set is just a name→Lucide-component map with the SDK's
{ size, cls, style } prop adapter; there is no hand-drawn SVG and no codegen.
To add a name to the eager set, add an entry to Icons.tsx; anything not in it
resolves lazily from Lucide regardless.
Vite plugin: build identity for client staleness handling
The SDK ships with a tiny Vite plugin that emits bundle-fingerprint.txt next to index.html after every production build. The Declarion server reads it at boot and folds it into the build identity stamped on every /api/* response (X-Declarion-Version). The SDK's built-in version watcher detects drift on every API response, on focus/online/60s probe, and either silently invalidates the schema query (schema-only changes) or prompts the user to reload (asset/binary changes). Cross-tab coordination via BroadcastChannel.
Add the plugin to your consumer app's vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { declarionFingerprintPlugin } from "@declarion/react/vite";
export default defineConfig({
plugins: [react(), declarionFingerprintPlugin()],
});That's it — there is no client API to wire by hand. The version watcher mounts itself inside <App>, the response-header observer is built into apiFetch, and the toast slot reuses the existing Sonner <Toaster/>. The plugin works in every Declarion deployment mode (local SDK link, npm-pinned, prebuilt prod image) since it runs at consumer build time regardless of where the SDK itself comes from.
Consumers that haven't adopted the plugin yet degrade gracefully: the server logs once at boot, falls back to binary-only drift detection, and the rest of the system continues working — drift still gets detected, just classified more conservatively as "asset/binary" so the user gets a reload prompt rather than a silent invalidation.
Browser support requires BroadcastChannel for cross-tab coordination — Chrome 54+, Firefox 38+, Safari 15.4+. In environments without it, in-tab detection still works; cross-tab fan-out is silently skipped.
See docs/architecture.md (section "Build identity & client staleness handling") for the full design rationale, fingerprint composition, RFC 7232 details (auth-variant ETag, weak-ETag handling), and the no-persistence invariant that prevents reload loops.
License
MIT. See LICENSE.
Runtime
The SDK talks to a Declarion runtime server. The runtime is proprietary commercial software - contact [email protected] for licensing.
