# Core API

> The shared engine and component layers behind every adapter.

Most app code should import from `@symbiote-native/react`, `@symbiote-native/vue`,
`@symbiote-native/angular`, `@symbiote-native/svelte`, or `@symbiote-native/solid`. The core
packages explain why those adapters can stay thin and consistent.

## Installation

```sh
pnpm add @symbiote-native/engine
```

Most apps never install this directly — `@symbiote-native/react`,
`@symbiote-native/vue`, `@symbiote-native/angular`, `@symbiote-native/svelte`,
and `@symbiote-native/solid` all declare it as a peer
dependency, so it arrives with the adapter. Install it by hand only when you are
writing or debugging an adapter yourself. `react-native` (>=0.86) is a peer
dependency and stays your app's own top-level dependency either way.
`@symbiote-native/components` installs the same way — see the
[Components API](/docs/api/components/#installation).

## @symbiote-native/engine

The engine owns the native route:

```txt
adapter mutation → JS command buffer → SymbioteTree (C++) → Fabric clone-on-write commit → native views
```

The retained tree used to live in the JS package itself; it now lives in C++
(`core/engine/cpp`), and the JS side's job is building the buffer and crossing into it once per
commit instead of once per mutation. The public API below is unchanged either way.

Its public surface includes:

- the mutation API used by adapters: `createElement`, `appendChild`,
  `insertBefore`, `removeChild`, `setProp`, `setEventListener`, `commit`-related
  operations through surfaces;
- host instance helpers such as `measure`, `setNativeProps`, and
  `dispatchViewCommand`;
- style utilities such as `StyleSheet`, `flattenStyle`, and native style
  processors;
- platform/runtime utilities such as `Platform`, `PixelRatio`, `Dimensions`,
  `Appearance`, `Alert`, `Share`, `Linking`, and `Keyboard`;
- native-view metadata hooks such as `setNativeViewConfigSource`;
- `createAppRegistry`, the framework-agnostic core of `AppRegistry` (registry
  bookkeeping, sections, the native host-registrar bridge, headless tasks) —
  see [App entry point](#app-entry-point-appregistry) below.

Users normally reach these through adapter re-exports.

## App entry point (`AppRegistry`)

Every adapter exports the same `AppRegistry.registerComponent(appKey, () => App)`
entry point RN apps already use, plus `setHostRegistrar` to hand it RN's own
`AppRegistry` so the native Fabric host can find the registered runnable by app
key:

```ts
import { AppRegistry, setHostRegistrar } from '@symbiote-native/react'; // or '@symbiote-native/vue' / '@symbiote-native/angular' / '@symbiote-native/svelte' / '@symbiote-native/solid'
import { AppRegistry as RNAppRegistry } from 'react-native';

setHostRegistrar(RNAppRegistry);
AppRegistry.registerComponent('MyApp', () => App);
```

`registerSection`, `runApplication`, `unmountApplicationComponentAtRootTag`,
`setWrapperComponentProvider`, and the headless-task methods
(`registerHeadlessTask`, `registerCancellableHeadlessTask`,
`startHeadlessTask`, `cancelHeadlessTask`) round out the same surface RN's
`AppRegistry` exposes. All of this bookkeeping lives once in
`@symbiote-native/engine`'s `createAppRegistry` — the only framework-specific piece
each adapter supplies is `runnableFor`, the function that turns a component
provider into a mount call (`createElement` + `mount` for React, `createApp`/`h`
for Vue, `createComponent` for Angular, its own `mount` for Svelte, and
`solid-js/universal`'s `createComponent` for Solid).

## @symbiote-native/components

The component package owns framework-agnostic component logic:

- pure state machines, for example `Switch`, `Pressable`, `TextInput`, and list
  windowing logic;
- pure render helpers that produce `Descriptor` trees;
- shared accessibility folding and native component-name resolution;
- shared event payload helpers and command helpers.

Adapters provide only lifecycle and element bridges:

| Layer                  | React                | Vue                     | Angular                                                               | Svelte                                                                                                                                                                                                                                                          | Solid                                                                                                                                                                                                             |
| ---------------------- | -------------------- | ----------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| State lifecycle        | hooks / refs         | refs / watches / expose | zoneless change detection (signals / fields)                          | `$state` / `$effect` runes                                                                                                                                                                                                                                      | signals / effects (`createSignal` / `createEffect`)                                                                                                                                                               |
| Render bridge          | `descriptorToReact`  | `descriptorToVue`       | `DescriptorOutlet` (proven on some components, migration in progress) | a DOM shim over stock compiled output (`adapters/svelte/src/dom-shim/`), no generic Descriptor walker; each component hand-authors its fixed host tag(s) and reads props/children off known positions, `mountDescriptorChildren` syncing an already-fixed shape | `descriptorToSolid`: builds a host node once, then re-props it through a `spread` render effect; a component taking live children (`View`, `Pressable`, `Modal`, ...) skips the bridge and emits real JSX instead |
| Public framework shape | callbacks / children | emits / slots           | `@Output()` EventEmitters / `<ng-content>`                            | callback props, same names as React, no emits, no `@Output()`                                                                                                                                                                                                   | callback props (`class` for styling); a render-prop child (`Pressable`, list `renderItem`) takes a Solid `Accessor`, not a snapshot value                                                                         |

## Wrapper authors

Native-view wrapper packages can use the same seam:

- derive native metadata with `setNativeViewConfigSource`;
- keep shared view logic in a framework-agnostic package;
- expose thin React, Vue, Angular, Svelte, and Solid wrappers that map framework
  props/events to engine props and native events.

Do not import a third-party React Native JavaScript component into Vue. Wrap the
native view, not the React component body.
