# Roadmap

> Current status and the next milestones for SymbioteNative.

The goal is not to duplicate React Native's JavaScript surface all at once;
the goal is to harden the renderer seam, then expand adapter and component
parity through shared layers.

## Current milestones

| Area               | Status               | Purpose                                                                                     |
| ------------------ | -------------------- | ------------------------------------------------------------------------------------------- |
| React adapter      | On the live switcher | Reference canary for the engine and Fabric pipe.                                            |
| Vue adapter        | On the live switcher | First non-React proof of the framework-agnostic seam.                                       |
| Angular adapter    | On the live switcher | Second non-React proof: `Renderer2` seam, DOM-less bootstrap, full component parity.        |
| Svelte adapter     | On the live switcher | Third non-React proof: a DOM shim over stock compiled Svelte output, full component parity. |
| Solid adapter      | On the live switcher | Fourth non-React proof: `solid-js/universal`'s `createRenderer`, full component parity.     |
| Engine             | Rewritten in C++, tuning ongoing | Retained tree, clone-on-write commits, tag-keyed platform rules, and event normalization now live in `core/engine/cpp`, reached from JS through one buffered crossing per commit instead of one per mutation. |
| Components         | In progress          | Shared state/view layers so adapters inherit parity.                                        |
| Android host shim  | Active               | Keeps Android at canary parity with iOS.                                                    |
| Navigation package | Shipped              | Native stack/tab/drawer navigator over `react-native-screens`, shared by every adapter.     |
| `@symbiote-native/cli` scaffolder | Beta | `new` scaffolds a full app; `add` extends an existing SymbioteNative app with optional layers — wiring symbiote into a plain RN app isn't automated yet. |

## Engine rewrite

The retained tree used to live in JavaScript; it now lives in C++ (`core/engine/cpp`), with the
JS side reduced to building a command buffer and crossing into it once per commit instead of
once per mutation. Measured headless so far, that trade isn't free in one direction: create- and
append-shaped operations got more expensive, while operations on an already-mounted tree (swap,
remove, select) got substantially cheaper across every non-React adapter. A fresh on-device
benchmark run for this architecture hasn't happened yet — see the
[README's benchmark section](https://github.com/OneEyed1366/symbiote-native#how-fast-against-stock-react-native)
for the actual numbers and what's still missing.

## Next adapter work

Angular validated the second framework-agnostic renderer seam and a more
complex AOT build pipeline (`ngtsc` partial compilation, then the
compiler-cli linker — two phases), and is now on the live framework switcher
alongside React and Vue. Its migration from callback `@Input()` props to
idiomatic `@Output()` `EventEmitter`s for component events is complete, with
one permanent exception: the scroll family (`onScroll`, `onScrollBeginDrag`,
`onScrollEndDrag`, `onMomentumScrollBegin`, `onMomentumScrollEnd`) stays a
callback input on `ScrollView` and the list components, because it must also
accept an `Animated.event(...)` marker for native-driven scroll, which
`@Output()` can't express. Wrapper packages have followed: the Slider package
now ships an Angular build alongside React and Vue.

Svelte is the third non-React adapter, done the same long-term way: a thin
layer over the shared engine — here a DOM shim over stock compiled Svelte
output, so components stay ordinary Svelte markup with no bespoke compiler
output. It reaches the same full component parity as React, Vue, and
Angular, verified on-device on iOS and Android, and the Slider wrapper
package ships a Svelte build too. It's on the landing page's live framework
switcher.

Solid is the fourth non-React adapter, built the same long-term way: a thin
layer over the shared engine, here a Solid custom renderer over
`solid-js/universal`'s own `createRenderer`, the framework's official
agnostic seam for non-DOM targets. It reaches the same component parity as
React, Vue, Angular, and Svelte, including `createPortal`, `createTunnel`,
`Animated`, and `AppRegistry`, and every companion package now ships a
`./solid` build too. It's also on the live switcher now, with its own demo
clip, verified on device like the other four adapters. It doesn't yet share
the Detox `canary-journeys` e2e spec React, Vue, and Svelte carry.

React, Vue, Angular, Svelte, and Solid keep expanding parity in the meantime:
all five now have a portal primitive for same-surface content relocation
(React's `createPortal`, Vue's `Teleport`, Angular's `*portal` directive,
Svelte's and Solid's own `Portal`) plus a `createTunnel` primitive for
cross-surface delivery. Mutation-mode Fabric supports this where stock RN's
persistent-mode renderer can't. Vue also gained `v-model` on controlled components and a
working `v-show` directive; Angular's `[(value)]` two-way binding covers the
same controlled-component case idiomatically. All five adapters now share one
`AppRegistry` entry point over the same `@symbiote-native/engine` core.

## Package parity with Expo

The [navigation package](/docs/navigation/) closed the biggest gap on the "can a real app ship
without React Navigation" list, and a run of small native-module wrapper packages has followed
it — Clipboard, Haptics, Sensors, Battery, Device and a dozen more, each wrapping one
`expo-modules-core` module. Those don't use the autolinking-proxy recipe `@symbiote-native/slider`
and `@symbiote-native/splash-screen` do: they ship a passive manifest, and a single app-level
`@symbiote-native/expo-modules-link` postinstall registers whichever ones are installed (see [How
to: wire up an Expo native module](/docs/howtos/expo-native-module-setup/)). `npx @symbiote-native/cli new`/`add`
picks up each one as its own flag (`--battery`, `--sensors`, ...) and wires the autolinking for
you. Reanimated, a full worklet-driven animation layer, is the largest remaining piece and is
saved for last. The end goal is package-surface parity with Expo's SDK: whatever a real app can
reach for in Expo, a SymbioteNative app can reach for too, off the same untouched native core.

## Styling / CSS compiler

`@symbiote-native/css-parser` compiles plain CSS, CSS Modules, and SCSS/Sass, Less,
and Stylus preprocessor sources at build time into native style objects,
resolved at runtime through a class registry shared by React, Vue, Angular,
Svelte, and Solid, including `box-shadow`, `transform`, `filter`, `transform-origin`,
and `background-image` (gradients). It also ships type safety for
`.module.css` imports: a `css-dts` CLI that generates a narrowed, typo-safe
`.d.ts` next to each CSS Modules file, and a `typescript-plugin` for live
in-editor autocomplete — see the [styling guide](/docs/learn/styling/) for
setup. Svelte's own `<style>` block (scoped by default) compiles through the
same pipeline. Tailwind CSS remains the open seam in this family.

## Component parity rule

A component is done only when it reaches full feature parity across adapters.
The project should not ship a minimal Vue `ScrollView` if React's `ScrollView`
already supports sticky headers, native scroll attach, imperative handles, and
platform-specific behavior. Shared logic moves into the shared layer; adapters
supply lifecycle and framework bridges.

## Non-goals

- Forking React Native native sources.
- Hiding `react-native` as a transitive dependency of apps.
- Making third-party React Native JavaScript components framework-agnostic.
- Replacing Yoga or the native Fabric host.

## Architecture docs

Public architecture notes should be written as standalone reader-facing pages.
Internal repository notes can inform those pages, but should not be linked or
referenced directly from the public docs.
