跳转到内容

How to build a React Native renderer backend

How to build a React Native renderer backend

Section titled “How to build a React Native renderer backend”

Official docs still say creating a platform from scratch is “not very well documented,” and that New Architecture / Fabric exists partly to make that easier (Out-of-Tree Platforms).


PathWhen to useWhat you getCost
A. Fabric host platformYou want real RN apps (View/Text/TurboModules/codegen/Hermes) on a new OS or UI toolkitShared shadow tree, Yoga, diffing, JSI; you own mount + host viewsLarge: C++, run-loop, text, a11y, images, CLI/Metro
B. react-reconciler host configCustom React target (canvas, terminal, Three.js, PDF) without RN APIsYour own host tree; no RN ecosystem by defaultMedium: JS host config; unstable API
C. Fork / extend an existing OOT platformClosest stack already exists (Windows Composition, GTK, Skia, GPUI)Reuse mounting patterns, build, CLIStill large; version-track upstream RN

Rule of thumb: if the goal is “React Native on X,” pick A or C. If the goal is “React JSX driving X,” pick B (ink, react-three-fiber, react-pdf, Skia’s own reconciler, gtkx-style ports).


2. Fabric architecture (what a backend actually owns)

Section titled “2. Fabric architecture (what a backend actually owns)”

From Cross Platform Implementation: Fabric’s C++ APIs have two sides—(i) talk to React, (ii) talk to the host platform. Shared C++ owns shadow tree construction, Yoga layout (most of it), view flattening, and tree diffing. The host owns mounting host views and host events.

Grounded tree under packages/react-native/ReactCommon/react/renderer/ (facebook/react-native):

LayerPathRole for a backend
Core / shadow nodesrenderer/coreImmutable shadow nodes, props, events
Component registryrenderer/componentregistryComponentDescriptorRegistry maps names → descriptors
Componentsrenderer/componentsBuilt-in View/Text/… descriptors (codegen-fed)
Schedulerrenderer/schedulerScheduler, SurfaceHandler, SurfaceManager
Mounting (shared)renderer/mountingMountingCoordinator, Differentiator, ShadowTree, ShadowViewMutation
UIManagerrenderer/uimanagerBinding toward JS / surface APIs
Textrenderer/textlayoutmanagerPlatform hooks for measure
Imagesrenderer/imagemanagerPlatform image pipeline
Runtime schedulerrenderer/runtimeschedulerEvent-loop / priority scheduling
DOM helpersrenderer/domLayout/DOM-ish queries used by newer Web-aligned APIs

Note on “MountingManager”: docs and older platform code use that name for the host UI applicator. In shared ReactCommon (2026 main), the cross-platform pieces are MountingCoordinator + ShadowViewMutation; platforms implement SchedulerDelegate and apply mutations to native views (RNW: ComponentView / FabricUIManagerModule).

From Render pipeline and Threading model:

Mutation types (from ShadowViewMutation.h): Create, Delete, Insert, Remove, Update.

Platform callback surface (from SchedulerDelegate.h):

  • schedulerDidFinishTransaction / schedulerShouldRenderTransactions (flush via MountingCoordinator)
  • schedulerDidRequestPreliminaryViewAllocation
  • schedulerDidDispatchCommand
  • schedulerDidSendAccessibilityEvent
  • schedulerDidSetIsJSResponder
  • schedulerShouldSynchronouslyUpdateViewOnUIThread / schedulerDidUpdateShadowTree
  • View-transition snapshot hooks
  • UI/main: only thread that mutates host views; mount runs here.
  • JS: React render phase; can also run full pipeline synchronously for high-priority UI events.
  • Layout mostly C++; Text / TextInput still call into the host for measurement (render pipeline).
  • JSI — direct C++ ↔ JS (no JSON bridge) (Fabric)
  • Hermes — default engine; host embeds and drives its run loop
  • TurboModules — lazy native modules + codegen
  • Codegen — JS component/module specs → C++ props/structs; mismatches fail at build time

3. Implementation checklist (new Fabric platform)

Section titled “3. Implementation checklist (new Fabric platform)”

Official Metro/platform registration only covers JS bundling (out-of-tree platforms): rnpm.haste.platforms, providesModuleNodeModules, .platform.js suffixes. Everything below is the native side the docs leave underspecified—filled from RNW Fabric + ReactCommon.

  1. App / instance bootstrap — Hermes + JSI runtime, call into Fabric Scheduler / SurfaceHandler, surface size/constraints.
  2. SchedulerDelegate implementation — receive transactions; apply ShadowViewMutation list on UI thread.
  3. Host component views — map shadow components to toolkit widgets (RNW: vnext/Microsoft.ReactNative/Fabric/Composition/*ComponentView.cpp).
  4. ComponentDescriptor registration — platform + third-party descriptors into ComponentDescriptorRegistry / provider registry (RNW: WindowsComponentDescriptorRegistry, AbiComponentDescriptor).
  5. Text measurement — implement host side of TextLayoutManager (RNW uses DirectWrite helpers: DWriteHelpers.*).
  6. Event emitters — touch/pointer/keyboard → Fabric event system (RNW: AbiEventEmitter, Composition event handlers).
  7. Run-loop / RuntimeScheduler integration — pump JS microtasks, mount flushes, animations on the right threads (RFC0744 event loop).
  8. Image loading — platform ImageManager (RNW: WindowsImageManager.cpp).
  9. Accessibility — map props + schedulerDidSendAccessibilityEvent to OS a11y (RNW Composition root automation providers).
  10. TurboModules + codegen — PlatformConstants, Linking, Appearance, AsyncStorage, …; wire @react-native/codegen.
  11. Metro / CLI — platform name, react-native.config.js, run-<platform>, autolinking story.
  12. Core primitives parity — View, Text, Image, ScrollView, TextInput, Modal, Switch, Pressable at minimum before claiming “RN on X.”

Shadow tree, Yoga, Differentiator, MountingCoordinator, ComponentDescriptor machinery, attributed strings, bridging, UIManager bindings, most of renderer/components. Do not reimplement diffing in the host.

  • Unit-test mutation application and layout against golden trees (RN ships renderer/mounting/tests, scheduler/tests).
  • Smoke / playground app (RNW playground-composition, linux apps/playground).
  • E2E against RN Tester–like galleries; track parity matrices (RNW issue #12042).
  • Third-party library canaries (Paper, Reanimated, gesture-handler) early—ecosystem breakages dominate schedule.

4. Path B — react-reconciler host config

Section titled “4. Path B — react-reconciler host config”

From react-reconciler README: experimental; API does not follow React’s semver.

Enough when: you do not need RN component APIs, TurboModules, or Metro’s RN resolution—e.g. react-three-fiber, ink, react-pdf, Skia canvas reconcilers, native-surface (Yoga+CanvasKit via reconciler), gtkx-style GTK ports.

Not enough when: you want unmodified RN apps / libraries—those assume Fabric host components + JSI modules.

Modes

  • supportsMutation: true — DOM-like (React DOM, classic RN, R3F)
  • supportsPersistence: true — immutable trees (Fabric’s React host config style)

Core methods (mutation mode, incomplete but stable-ish): createInstance, createTextInstance, appendInitialChild, appendChild, appendChildToContainer, removeChild, insertBefore, commitUpdate, commitTextUpdate, finalizeInitialChildren, prepareUpdate, getRootHostContext, getChildHostContext, getPublicInstance, shouldSetTextContent, scheduleTimeout / cancelTimeout, noTimeout, plus commit hooks (commitMount, etc.). Full list: ReactFiberConfig (linked from the README).


5. Existing backends to study (status as of 2026-10)

Section titled “5. Existing backends to study (status as of 2026-10)”
ProjectRepoStatus (2026)Notes
react-native-windowsmicrosoft/react-native-windowsProduction path; New Arch default for new apps since 0.80; Old Arch deprecated with RN 0.82Fabric on Windows App SDK Composition (not WinUI XAML). Study vnext/Microsoft.ReactNative/Fabric/. Docs: new-architecture. Hub: #12042
react-native-macosmicrosoft/react-native-macosPartner OOT (listed on reactnative.dev)Cocoa / AppKit lineage
react-native-visionoscallstack/react-native-visionosPartnervisionOS
react-native-tvosreact-native-tvos/react-native-tvosCommunityApple TV / Android TV
react-native-webnecolas/react-native-webMatureRN API → DOM; not Fabric C++
React Native Skia (OOT)listed on out-of-tree platformsLinux/macOS Skia rendererDistinct from Shopify’s in-app Skia graphics lib
react-native-linux (GTK4)lucid-softworks/react-native-linuxAlpha (created 2026-05); Hermes + Fabric-only; modeled on RNW vnext/TurboModule codegen not fully wired; good structural reference
react-native-gtkxitsmepetrov/react-native-gtkxActive experimentRN API via react-reconciler → GTK4/Adwaita (web-like alias), not full Fabric C++
react-native-gpuiAnnounced by @ammarahm_ed (2026-10-02)Pre-alpha / coming soonFabric → Zed GPUI (Rust); positioned like RNW (“reuse RN architecture, add platform”)
ProjectApproach
shopify/react-native-skiaSkia drawing inside RN (Fabric/JSI), not a full OOT platform
pmndrs/react-three-fiberreact-reconciler → Three.js
vadimdemedes/inkReconciler → terminal
native-surfaceReconciler + Yoga WASM + CanvasKit; RN-compat layer in browser
roman01la/cljs-static-hermesStatic Hermes AOT + Skia/Yoga custom reconciler (HN-adjacent experiments)

  1. Text layout — hardest host dependency; every platform reinvents measurement (Core Text, DirectWrite, Pango, Skia text). Yoga defers here.
  2. Threading — mounting off the UI thread = crashes; JS↔UI priority interrupts must match RuntimeScheduler / event-loop RFC.
  3. Upstream drift — OOT platforms pin an RN version and chase every release; New Arch is default since 0.76 (blog).
  4. Codegen / autolinking — without it, third-party Fabric components and TurboModules do not appear (linux alpha explicitly lacks full codegen wiring).
  5. Maintenance cost — RNW’s multi-year Fabric port (Composition, XAML islands, custom component ABI) is the honesty check; “hello View” is weeks, ecosystem parity is years.
  6. Lean Core — more modules leave core; your platform must ship or stub what apps expect (see RFC0836 Lean Core JSC and ongoing lean-core direction).
  7. DOM APIs on Fabric — RFC0607 + shipping IntersectionObserver (canary/experimental docs) assume Fabric’s intermediate tree; Paper-only or reconciler-only backends will not get these “for free.” Shared helpers live under renderer/dom.
  8. Static Hermes — AOT / native compilation experiments exist (cljs-static-hermes, Attar on HN); not a drop-in replacement for embedding Hermes in a new OOT platform yet—plan for standard Hermes first.
  9. C++ API stability — prefer documented / Strict API surfaces (RFC1018); private ReactCommon headers will break you.

  • @ammarahm_ed on X (2026-10-02): react-native-gpui “is an out-of-tree react-native renderer much like react-native-windows that reuses the complete react-native architecture as-is, only adding a new gpui platform… RN’s core is platform agnostic.” Follow-up demos claim Reanimated/worklets on the UI thread (2106314150070948015).
  • @theultdev (2026-10-03): argues GPUI-style one renderer is preferable on Linux because “react-native-gtk and react-native-qt failed”—tension with native-widget purity vs shared GPU UI.
  • RNW Fabric authors (e.g. Composition PRs by acoates-ms): host XAML islands inside Composition, expose (un)MountChildComponentView to 3P components—pattern for custom host views without inheriting across DLL boundaries (PR #13603, commit exposing mount APIs).
  • Official stance: partners list macOS / Windows / visionOS; community list tvOS / web / Skia; “from scratch still not very well documented” (docs).
  • discussions-and-proposals: use RFC496 React DOM for Native, RFC0607, RFC0744 event loop, RFC1018 C++ Strict API—not a single “how to build a platform” RFC.
  • HN / experiments: custom reconciler + Static Hermes / Skia remain niche (romanliutikov writeup); little HN traffic specifically on “Fabric OOT platform how-to” as of search on 2026-10-06.


  • No single official “implement MountingManager” tutorial; platform mounting is inferred from ReactCommon + RNW.
  • GitHub code search for MountingManager returned incomplete/empty in this session; claims use MountingCoordinator / SchedulerDelegate / RNW ComponentView instead.
  • Reddit site:reddit.com Exa queries returned noise / empty for OOT Fabric; field notes leaned on X + GitHub.
  • Static Hermes doc path on static_h branch did not fetch cleanly; treated as experimental only.
  • Exact production readiness of “React Native Skia” as listed on reactnative.dev vs Shopify’s library should be re-checked before depending on it.