react-native

React Native renderer for json-render that turns JSON specs into native mobile UIs. Use when working with @json-render/react-native, building React Native UIs…

INSTALLATION
npx skills add https://github.com/vercel-labs/json-render --skill react-native
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

// Create catalog with standard + custom components

const catalog = defineCatalog(schema, {

components: {

...standardComponentDefinitions,

Icon: {

props: z.object({ name: z.string(), size: z.number().nullable(), color: z.string().nullable() }),

slots: [],

description: "Icon display",

},

},

actions: standardActionDefinitions,

});

// Register only custom components (standard ones are built-in)

const { registry } = defineRegistry(catalog, {

components: {

Icon: ({ props }) => <Ionicons name={props.name} size={props.size ?? 24} />,

} as Components,

});

// Render

function App({ spec }) {

return (

);

}

## Standard Components

### Layout

- `Container` - wrapper with padding, background, border radius

- `Row` - horizontal flex layout with gap, alignment

- `Column` - vertical flex layout with gap, alignment

- `ScrollContainer` - scrollable area (vertical or horizontal)

- `SafeArea` - safe area insets for notch/home indicator

- `Pressable` - touchable wrapper that triggers actions on press

- `Spacer` - fixed or flexible spacing

- `Divider` - thin line separator

### Content

- `Heading` - heading text (levels 1-6)

- `Paragraph` - body text

- `Label` - small label text

- `Image` - image display with sizing modes

- `Avatar` - circular avatar image

- `Badge` - small status badge

- `Chip` - tag/chip for categories

### Input

- `Button` - pressable button with variants

- `TextInput` - text input field

- `Switch` - toggle switch

- `Checkbox` - checkbox with label

- `Slider` - range slider

- `SearchBar` - search input

### Feedback

- `Spinner` - loading indicator

- `ProgressBar` - progress indicator

### Composite

- `Card` - card container with optional header

- `ListItem` - list row with title, subtitle, accessory

- `Modal` - bottom sheet modal

## Visibility Conditions

Use `visible` on elements. Syntax: `{ "$state": "/path" }`, `{ "$state": "/path", "eq": value }`, `{ "$state": "/path", "not": true }`, `[ cond1, cond2 ]` for AND.

## Pressable + setState Pattern

Use `Pressable` with the built-in `setState` action for interactive UIs like tab bars:

{

"type": "Pressable",

"props": {

"action": "setState",

"actionParams": { "statePath": "/activeTab", "value": "home" }

},

"children": ["home-icon", "home-label"]

}


## Dynamic Prop Expressions

Any prop value can be a data-driven expression resolved at render time:

- **`{ "$state": "/state/key" }`** - reads from state model (one-way read)

- **`{ "$bindState": "/path" }`** - two-way binding: use on the natural value prop (value, checked, pressed, etc.) of form components.

- **`{ "$bindItem": "field" }`** - two-way binding to a repeat item field. Use inside repeat scopes.

- **`{ "$cond": <condition>, "$then": <value>, "$else": <value> }`** - conditional value

{

"type": "TextInput",

"props": {

"value": { "$bindState": "/form/email" },

"placeholder": "Email"

}

}


Components do not use a `statePath` prop for two-way binding. Use `{ "$bindState": "/path" }` on the natural value prop instead.

## Built-in Actions

The `setState` action is handled automatically by `ActionProvider` and updates the state model directly, which re-evaluates visibility conditions and dynamic prop expressions:

{ "action": "setState", "actionParams": { "statePath": "/activeTab", "value": "home" } }


## Providers

Provider
Purpose

`StateProvider`
Share state across components (JSON Pointer paths). Accepts optional `store` prop for controlled mode.

`ActionProvider`
Handle actions dispatched from components

`VisibilityProvider`
Enable conditional rendering based on state

`ValidationProvider`
Form field validation

### External Store (Controlled Mode)

Pass a `StateStore` to `StateProvider` (or `JSONUIProvider` / `createRenderer`) to use external state management:

import { createStateStore, type StateStore } from "@json-render/react-native";

const store = createStateStore({ count: 0 });

<StateProvider store={store}>{children}</StateProvider>

store.set("/count", 1); // React re-renders automatically

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card