# mythik-react-native

The React Native and Expo rendering surface for Mythik contracts. Turn
validated JSON from your store into native UI, embed a single spec via
`MythikRenderer`, wire native screens through the app shell, and keep
the same runtime contract used by the web renderer.

> See [the framework README on GitHub](https://github.com/mldixdev/mythik#readme)
> for the full Mythik architecture and design philosophy. This file
> documents what `mythik-react-native` gives you and how to use it.

---

## What Mythik is, briefly

Mythik is an **AI-first JSON-native app framework**. Most of your app
lives as validated JSON specs loaded at runtime from your database,
not source code that must be regenerated and redeployed for every
change. AI agents compose those specs from a documented vocabulary;
Mythik validates the shape, references, actions, state paths, and
cross-contract assumptions before the change reaches runtime. This
package is the React Native rendering surface: it turns those same
validated JSON contracts into native app screens.

## Install

`mythik-react-native` follows the same version line as the rest of
Mythik, but remains a public preview while native primitive parity and
smoke coverage continue to expand. Expo SDK 52, 53, and 54 are the
tested SDK line. Expo SDK 55 support is pending React Native 0.82 /
Reanimated 4.2 alignment.

For Expo apps, install the native peer packages first so Expo chooses
versions that match your SDK:

```bash
npx expo install react-native-svg react-native-reanimated react-native-worklets react-native-safe-area-context react-native-screens react-native-gesture-handler expo-linear-gradient expo-haptics expo-blur @react-native-community/slider
```

Then install Mythik and the native renderer:

```bash
npm install mythik mythik-react-native
```

Keep the Reanimated Babel plugin last in your app's Babel config:

```js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['react-native-reanimated/plugin'],
  };
};
```

Your Expo or React Native host still owns native project setup, app
registration, navigation container wiring, permissions, and app-store
packaging. Mythik owns the spec contract and renderer.

## What you get

- **`<MythikRenderer>`** - single-spec native renderer for embedding
  Mythik screens inside an Expo or React Native app.

- **Native primitive registry** - 27 supported primitives covering
  layout, text/media, forms, interactive surfaces, app structure,
  overlays, and loading states.

- **Explicit support matrix** -
  `REACT_NATIVE_PRIMITIVE_SUPPORT` and
  `getReactNativePrimitiveSupport(name)` tell you whether a primitive
  is supported natively or belongs to a future native milestone.

- **Shared Mythik contract** - the renderer consumes the same `Spec`
  shape, expression system, state bindings, action chains, transactions,
  tokens, and validation model used by `mythik-react`.

- **Native runtime hardening** - RN-safe background SVG sanitization,
  portable notification IDs, `$platform` render-cache invalidation,
  native-safe motion helpers, and Android overlay behavior tested
  against a real emulator.

## Minimal example

```tsx
import { MythikRenderer } from 'mythik-react-native';

const spec = {
  root: 'main',
  elements: {
    main: {
      type: 'stack',
      props: { gap: 12, padding: 24 },
      children: ['title', 'subtitle'],
    },
    title: {
      type: 'text',
      props: {
        content: {
          $platform: {
            web: 'Hello web',
            native: 'Hello native',
          },
        },
        variant: 'heading',
      },
    },
    subtitle: {
      type: 'text',
      props: {
        content: 'Rendered from the same Mythik spec contract.',
      },
    },
  },
};

export default function App() {
  return <MythikRenderer spec={spec} />;
}
```

Keep `root` as a stable string element id. Use `$platform` only inside
localized props, styles, children, or values. `$platform` matches the
exact platform key first, then falls back from `ios`/`android` to
`native`; it does not support a `default` key.

When using `<MythikApp>`, pass `apiBaseUrl` to resolve relative runtime
fetch URLs before URL guards and fetch execution, so specs can use
`/api/...` across web and native hosts. Single-spec `<MythikRenderer>`
embeds can pass `fetcher` and `urlResolver` directly when they need the
same behavior. This package does not claim full web-auth parity in the
native slice: native hosts should pass the credentials/session transport
they need through the host fetcher and keep auth/session state out of specs.

## Supported primitive contract

The native package publishes the support matrix as runtime data:

```ts
import {
  REACT_NATIVE_PRIMITIVE_SUPPORT,
  getReactNativePrimitiveSupport,
} from 'mythik-react-native';

console.log(getReactNativePrimitiveSupport('button')?.status);
```

Supported in the current native renderer:

- Layout: `box`, `stack`, `grid`, `scroll`, `divider`, `spacer`
- Text and media: `text`, `image`, `icon`
- Forms: `input`, `textarea`, `select`, `checkbox`, `toggle`,
  `slider`, `button`
- Interactive: `touchable`, `list`, `modal`, `drawer`, `tabs`,
  `accordion`, `wizard`
- App structure: `screen`, `screen-outlet`, `toast-container`,
  `skeleton`

Native milestone primitives are intentionally visible as unsupported
rather than silently pretending parity: `bar-chart`, `line-chart`,
`pie-chart`, `area-chart`, `table`, `kanban-board`, `spatial-map`,
`file-upload`, `camera`, `signature`, and `audio-player`.

If a native spec references a milestone primitive, the renderer should
surface diagnostics instead of rendering broken UI. Treat the matrix as
part of the public contract.

## Platform parity

`mythik-react-native` consumes the same design tokens as the web
renderer where the platform can express them: surface treatments,
radius, border and elevation, typography hierarchy, heading color,
icon defaults, image defaults, motion recipes, and layered
backgrounds.

Some platform differences are real. React Native uses `expo-blur` for
glass surfaces and `react-native-svg` for SVG background layers. Web
CSS-only effects should be guarded with `$platform`. If the platform
experience is fundamentally different, prefer separate screen specs;
do not make `root` dynamic.

## Authoring workflow

Specs should be edited through the same CLI loop used by web apps:

```bash
mythik manifest <spec-id>
mythik elements <spec-id> <element-id>
mythik patch <spec-id> --from-file patch.json --author <agent>
mythik validate <spec-id>
```

Do not rewrite whole specs when a small RFC 6902 patch is enough. This
is especially important for AI agents: inspect the live contract,
patch the smallest valid change, then verify.

For the CLI surface, see
[`mythik-cli`](https://github.com/mldixdev/mythik/tree/main/packages/cli#readme).
For the web renderer, see
[`mythik-react`](https://github.com/mldixdev/mythik/tree/main/packages/react#readme).

## Mythik Reveal in native apps

React Native hosts also support the `reveal` prop. This is important
for native debugging because screenshots and Metro logs rarely explain
which spec branch, state path, or unsupported primitive caused the
runtime behavior.

```tsx
const reveal = React.useMemo(() => ({
  enabled: __DEV__,
  appName: 'field-app',
  bridgeUrl: 'http://127.0.0.1:17373',
  token: process.env.EXPO_PUBLIC_MYTHIK_REVEAL_TOKEN,
  environment: { id: 'android-emulator', source: 'host' as const },
  includeStatePaths: ['/ui', '/form'],
  redactStatePaths: ['/auth', '/secrets'],
}), []);

<MythikRenderer spec={spec} reveal={reveal} />;
```

For Android emulator smoke, map the bridge port to the emulator before
loading the app:

```bash
adb reverse tcp:17373 tcp:17373
npx mythik reveal start --port 17373
npx mythik reveal context --app field-app
```

**Reveal** context includes `runtime.platform`, the native renderer kind,
render errors, the explicit native support diagnostics, selected state
paths, and action/dataSource events. Use it before assuming a native
issue is a spec problem or a renderer problem.

Keep **Reveal** development-only and redact sensitive paths. Native apps
often carry auth/session state in memory; expose only what the agent
needs.

## Related packages

- [`mythik`](https://github.com/mldixdev/mythik/tree/main/packages/core#readme) - the runtime this renderer consumes
- [`mythik-react`](https://github.com/mldixdev/mythik/tree/main/packages/react#readme) - render the same specs as a React app
- [`mythik-cli`](https://github.com/mldixdev/mythik/tree/main/packages/cli#readme) - author and patch the specs you render
- [`mythik-server`](https://github.com/mldixdev/mythik/tree/main/packages/server#readme) - declarative REST server from an `ApiSpec`

## Status

Public preview release line. The package is published with an explicit
support matrix and real Expo/Android smoke coverage, while native
milestone primitives remain intentionally outside the supported
surface until their platform adapters are complete.

## Releases

Release notes and patch details are published in the
[CHANGELOG](https://github.com/mldixdev/mythik/blob/main/CHANGELOG.md)
and on
[GitHub Releases](https://github.com/mldixdev/mythik/releases).

## License

Apache-2.0.
