Skip to content
Frontend
Skill

/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 from JSON, creating mobile component catalogs, or rendering AI-generated specs on mobile.

From plugin
json-render
20k32 skills

Claude Code

$ npx -y skills add vercel-labs/json-render --skill react-native --agent claude-code

SKILL.md

react-native.SKILL.md
name: react-native
description: 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 from JSON, creating mobile component catalogs, or rendering AI-generated specs on mobile.

@json-render/react-native

React Native renderer that converts JSON specs into native mobile component trees with standard components, data binding, visibility, actions, and dynamic props.

Quick Start

import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react-native/schema";
import {
  standardComponentDefinitions,
  standardActionDefinitions,
} from "@json-render/react-native/catalog";
import { defineRegistry, Renderer, type Components } from "@json-render/react-native";
import { z } from "zod";

// 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<typeof catalog>,
});

// Render
function App({ spec }) {
  return (
    <StateProvider initialState={{}}>
      <VisibilityProvider>
        <ActionProvider handlers={{}}>
          <Renderer spec={spec} registry={registry} />
        </ActionProvider>
      </VisibilityProvider>
    </StateProvider>
  );
}

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.
  • Nested lists use `{ "repeat": { "statePath": { "$item": "comments" } } }` inside an enclosing repeat.
  • **`{ "$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

When `store` is provided, `initialState` and `onStateChange` are ignored.

Key Exports

| Export | Purpose | |--------|---------| | `defineRegistry` | Create a type-safe component registry from a catalog | | `Renderer` | Render a spec using a registry | | `schema` | React Native element tree schema | | `standardComponentDefinitions` | Catalog definitions for all standard components | | `standardActionDefinitions` | Catalog definitions for standard actions | | `standardComponents` | Pre-built component implementations | | `createStandardActionHandlers` | Create handlers for standard actions | | `useStateStore` | Access state con

Read more
@vercel-labs-2
Ships withjson-render

The Generative UI framework. Generate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.

Stars on GitHub

Momentum

stars in total
19.6k
Star history of vercel-labs/json-render on GitHub, a chart by star-history.com

Other skills on json-render.

chat

chat

Chat SDK renderer for json-render that turns JSON specs into native chat cards (Block Kit on Slack, Adaptive Cards on Teams, and…

codegen

codegen

Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing…

core

core

Core package for defining schemas, catalogs, and AI prompt generation for json-render. Use when working with @json-render/core,…

More skills from other plugins.

next-bundle-optimizer
Auto-invoked

next-bundle-optimizer

Audit and reduce Next.js browser initial-load work. Use for slow route startup, oversized client bundles, duplicate browser…

nextjs4d143k
@vercel@vercelInstall Skill
migrate-radix-to-base

migrate-radix-to-base

Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert…

ui2w127k
@shadcn-ui@shadcn-uiInstall Skill
chrome-release-cls

chrome-release-cls

Given a Chrome Releases blog post URL (chromereleases.googleblog.com), extract every CVE/bug and find the underlying Gerrit CL…

electron4d124k
@electron@electronInstall Skill
taste-skill
Auto-invoked

taste-skill

tasteskill v2, the anti-slop frontend skill. Art direction for websites, distilled from a study of 247 curated gallery sites (One…

Questions about react-native.

Which coding agents can use react-native?
react-native installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.