mirror of
https://github.com/kennethnym/jrx.git
synced 2026-03-19 19:31:17 +00:00
c9d4ff28e36e70b53b031bb2ef73cd96d1bafd07
Requires NPM_TOKEN secret. Builds, tests, then publishes with provenance. Co-authored-by: Ona <no-reply@ona.com>
jfx
JSX factory for json-render. Write JSX, get Spec JSON.
Install
bun add jfx @json-render/core
Setup
Configure your tsconfig.json to use jfx as the JSX source:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "jfx"
}
}
Or use a per-file pragma:
/** @jsxImportSource jfx */
Usage
Define components
Create wrapper functions that map JSX tags to json-render component type names:
import { jsx } from "jfx/jsx-runtime";
import type { JfxNode } from "jfx";
export function Stack(props: Record<string, unknown>): JfxNode {
return jsx("Stack", props);
}
export function Text(props: Record<string, unknown>): JfxNode {
return jsx("Text", props);
}
export function Button(props: Record<string, unknown>): JfxNode {
return jsx("Button", props);
}
Render JSX to Spec JSON
import { render } from "jfx";
import { Stack, Text, Button } from "./components";
const spec = render(
<Stack>
<Text content="Hello from jfx!" />
<Button label="Click me" />
</Stack>
);
This produces:
{
"root": "stack-1",
"elements": {
"text-1": {
"type": "Text",
"props": { "content": "Hello from jfx!" }
},
"button-1": {
"type": "Button",
"props": { "label": "Click me" }
},
"stack-1": {
"type": "Stack",
"props": {},
"children": ["text-1", "button-1"]
}
}
}
State, events, visibility, and watchers
Pass json-render bindings as JSX props:
const spec = render(
<Stack>
<Text content={{ $state: "/count" }} />
<Button
label="Increment"
on={{
press: {
action: "increment",
params: { statePath: "/count" },
},
}}
/>
<Text
content="Hidden until toggled"
visible={{ $state: "/showDetails", eq: true }}
/>
</Stack>,
{
state: {
count: 0,
showDetails: false,
},
}
);
The render() function accepts an options object with state to include initial state in the Spec output.
Reserved props
These props are extracted from JSX and mapped to Spec fields rather than passed through as component props:
| Prop | Spec field | Description |
|---|---|---|
key |
element key | Explicit element key (overrides auto-generation) |
visible |
visible |
Visibility condition |
on |
on |
Event bindings |
repeat |
repeat |
Repeat configuration |
watch |
watch |
State watchers |
children |
children |
Child element references |
Example
The example/ directory contains a Bun HTTP server that demonstrates jfx in action. It shows JSX source, live rendered UI (via @json-render/react), and JSON output side by side.
cd example
bun install
bun dev
This starts a dev server with HMR at http://localhost:3000.
Development
bun install # install dependencies
bun run build # build dist/
bun test # run tests
bun run typecheck # type check
License
MIT
Description
Languages
TypeScript
96.9%
HTML
2.5%
Dockerfile
0.6%