npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@mgcrea/react-native-swiftui

v0.12.0

Published

SwiftUI components for React Native

Downloads

381

Readme

This library integrates SwiftUI components into React Native using the Fabric renderer. This project enables developers to define native iOS UI elements with SwiftUI, controlled via React Native’s JSX syntax, creating a hybrid UI where React drives a dynamic SwiftUI view hierarchy.

Motivation

React Native excels at cross-platform development, but its UI components can sometimes lack the polish and performance of native iOS frameworks like SwiftUI. This PoC bridges that gap by:

  • Leveraging SwiftUI’s declarative, high-performance UI toolkit for iOS.
  • Using React Native’s Fabric renderer for modern, efficient native integration.
  • Enabling a familiar JSX workflow to manage native views.

Ideal for developers seeking native iOS aesthetics and behavior within a React Native app, this project explores a hybrid paradigm for enhanced UI flexibility.

Demo

demo

You can try it yourself using the Rxd AppStore application

Features

  • Supported Components: We plan to support as many SwiftUI components as possible.
  • Two-Way Data Binding: Syncs state between JavaScript and SwiftUI (e.g., text input updates via onChange).
  • Event Support: Handles events like change, focus, blur, press across the JS-native boundary.
  • Visual Feedback: Disabled fields (e.g., TextField with disabled={true}) are grayed out and faded for clarity.
  • Type Safety: TypeScript definitions for props and events, ensuring a robust developer experience.
  • Form Library Compatibility: Works seamlessly with libraries like react-hook-form and formik via passthrough component support.

Installation

Prerequisites

  • Node.js ≥ 18
  • React Native 0.78.0+
  • iOS 15.1+ (SwiftUI requirement)
  • pnpm (package manager, version 10.5.2 recommended per package.json)

Steps

Installation steps:

npm install @mgcrea/react-native-swiftui --save
# or
pnpm add @mgcrea/react-native-swiftui
# or
yarn add @mgcrea/react-native-swiftui

Usage Example

Basic Example

import { SwiftUI } from "@mgcrea/react-native-swiftui";
import { useState, type FunctionComponent } from "react";
import { Alert, View } from "react-native";

export const BasicFormExample: FunctionComponent = () => {
  const [firstName, setFirstName] = useState("John");
  const [lastName, setLastName] = useState("Doe");
  const [birthDate, setBirthDate] = useState(new Date("2019-06-03T00:00:00Z"));
  const [gender, setGender] = useState<"Male" | "Female">("Male");

  const handleSubmit = () => {
    const data = {
      firstName,
      lastName,
      birthDate,
      gender,
    };
    Alert.alert("Submitted", JSON.stringify(data, null, 2));
  };

  return (
    <View style={{ flex: 1 }}>
      <SwiftUI style={{ flex: 1 }}>
        <SwiftUI.Text text="BasicFormExample" />
        <SwiftUI.Form>
          <SwiftUI.Section header="Personal Information">
            <SwiftUI.TextField placeholder="First name" onChange={setFirstName} text={firstName} />
            <SwiftUI.TextField placeholder="Last name" onChange={setLastName} text={lastName} />
          </SwiftUI.Section>
          <SwiftUI.Section header="Additional Details">
            <SwiftUI.Picker
              options={["Male", "Female"]}
              label="Gender"
              onChange={setGender}
              selection={gender}
            />
            <SwiftUI.DatePicker
              label="Birth date"
              selection={birthDate}
              onChange={(value) => setBirthDate(value)}
              displayedComponents="date"
            />
          </SwiftUI.Section>
          <SwiftUI.Button title="Submit" onPress={handleSubmit} />
        </SwiftUI.Form>
      </SwiftUI>
    </View>
  );
};

Supported Components

Below is a list of components currently supported by @mgcrea/react-native-swiftui. These components leverage SwiftUI's native iOS capabilities while being controlled via React Native's JSX syntax.

SwiftUI Tree Components

These components are used within the <SwiftUI> tree and accessed via SwiftUI.*:

| Component | Description | Key Props | Notes | | ------------ | ------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | Button | A clickable button with customizable styles | title, buttonStyle, disabled, style, onPress | Supports styles like default, plain, bordered, etc. | | DatePicker | A date/time selection picker | selection, label, datePickerStyle, displayedComponents, onChange | Options include compact, wheel, etc.; supports date, hourAndMinute components | | Form | A container for grouping form elements | Children (nested components) | No specific props; acts as a layout container | | Group | A logical grouping of views | Children (nested components) | No specific props; used for hierarchy organization | | HStack | Horizontal stack layout | alignment, spacing, style, Children | Alignments: top, center, bottom, etc. | | Image | Displays an image (named, system, or local) | name, source, sourceUri, resizeMode, style | Supports system: prefix for SF Symbols, asset names, and bundled assets via require | | Picker | A dropdown or segmented selection | options, selection, label, pickerStyle, onChange | Styles: menu, segmented, wheel, etc. | | Rectangle | A simple rectangular shape | style | Used for basic shapes with customizable styling | | Section | A collapsible section within a form | header, footer, isCollapsed, Children | Useful for organizing form content | | Sheet | A modal sheet presentation | isPresented, detents, onDismiss, Children | Detents: medium, large, or custom values | | Slider | A continuous value slider | value, minimum, maximum, step, label, onChange | Adjustable range with step increments | | Spacer | A flexible space filler | minLength | Expands to fill available space | | Stepper | An increment/decrement control | value, label, minimum, maximum, step, onChange | For numeric adjustments | | Text | Displays static text | text, alignment, style | Alignments: leading, center, trailing | | TextField | An editable text input | text, label, placeholder, keyboardType, onChange | Supports various keyboard types and text content types | | Toggle | A switch for boolean values | isOn, label, onChange | Simple on/off control | | VStack | Vertical stack layout | alignment, spacing, style, Children | Alignments: leading, center, trailing | | ZStack | Overlapping stack layout | alignment, style, Children | Alignments: topLeading, center, bottomTrailing, etc. |

Standalone Native Components

These components are standalone native views that can be used anywhere in your React Native app:

| Component | Description | Key Props | Notes | | --------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | SFSymbol | Renders SF Symbols with full customization | name, size, color, weight, scale, renderingMode, variableValue, colors | Supports all SF Symbol features including hierarchical and palette rendering | | SwiftUIPicker | A native picker modal with search functionality | isPresented, title, searchPlaceholder, options, selectedValue, autoDismiss, onSelect | Full-screen native picker with search and categorization support | | SwiftUISheet | A native modal sheet presentation | isPresented, detents, onDismiss, Children | Standalone sheet that can be used outside of SwiftUI tree | | SwiftUISheetPicker | A native picker presented as a bottom sheet | isPresented, title, searchPlaceholder, options, selectedValue, autoDismiss, onSelect | Combines sheet presentation with picker functionality for a native iOS experience |

SFSymbol Examples

import { SFSymbol } from "@mgcrea/react-native-swiftui";

// Basic usage
<SFSymbol name="star.fill" />

// With color and size
<SFSymbol name="heart.fill" color="#FF3B30" size={24} weight="semibold" />

// With text style sizing
<SFSymbol name="gear" size="title" style={{ color: "#007AFF" }} />

// Hierarchical rendering (automatic shading)
<SFSymbol name="folder.fill.badge.plus" renderingMode="hierarchical" color="#007AFF" />

// Palette rendering (multiple colors)
<SFSymbol
  name="person.crop.circle.badge.checkmark"
  renderingMode="palette"
  colors={["#FF3B30", "#34C759", "#007AFF"]}
/>

// Variable value (for symbols that support it)
<SFSymbol name="speaker.wave.3.fill" variableValue={0.5} />

Contribute

We welcome contributions! If you have ideas for new components, optimizations, or bug fixes, please fork the repository and submit a pull request. We also encourage you to open issues for any bugs or feature requests.

Prerequisites

  • Xcode: Ensure you have Xcode installed for iOS development.
  • CocoaPods: Install CocoaPods if you haven't already. You can do this by running:
    sudo gem install cocoapods
  • pnpm: Install pnpm globally if you haven't already:
    npm install --global corepack@latest
    corepack enable pnpm

Example Project

To run the example project, follow these steps:

git clone https://github.com/mgcrea/react-native-swiftui.git
cd react-native-swiftui

pnpm install # install Node.js dependencies
pnpm run codegen:ios # generate codegen files

bundle install # setup Ruby environment

cd example
pnpm install # install example Node.js dependencies
pnpm run install:ios # install project native dependencies

pnpm run ios # run the example project

If the build fails, you should try to build from XCode directly using npm run open:ios and then run the app from XCode.

Notes

  • Props: Most components accept a style prop for layout and appearance customization (e.g., width, height, backgroundColor).
  • Events: Components like Button, TextField, and Picker support event handlers (e.g., onPress, onChange) for interactivity.
  • Children: Layout components (Form, HStack, VStack, etc.) accept nested components as children.
  • Image Sources: The Image component supports:
    • Named assets from Assets.xcassets (e.g., name="logo").
    • System images with a system: prefix (e.g., name="system:star.fill").
    • Local bundled assets via source={require('../path/to/image.png')}.

How It Works

  1. Component-Level Tree Building: Each SwiftUI.* component (e.g., <SwiftUI.TextField>) registers itself with a viewTree during React’s render phase, using a context-based system.
  2. Native Rendering: The aggregated viewTree is serialized as JSON and sent to iOS, where SwiftUI renders it via Fabric’s native bridge. Components use a unified Decodable approach for prop initialization.
  3. Two-Way Binding: State updates (e.g., text input) sync between React and SwiftUI via event handlers, with props merged efficiently on updates.
  4. Event Handling: Native events (e.g., onChange, onPress) are bubbled back to JavaScript through a custom event system.

Architecture

  • React Native (JS/TS):
    • Defines UI structure in JSX.
    • Uses SwiftUIContext for event handling and node registration.
    • Uses SwiftUIParentContext to maintain parent-child hierarchy.
    • Components register their ViewTreeNode dynamically during render.
  • Fabric: Facilitates communication between JavaScript and native code.
  • SwiftUI (iOS):
    • Renders the UI using native components (e.g., TextField, Button) based on the viewTree.
    • Props classes (e.g., PickerProps) conform to Decodable for initialization and use merge(from:) for updates, unifying prop handling.
  • Bridge: Custom Objective-C++ and Swift files (e.g., RCTSwiftUIRootView.mm, SwiftUIRootView.swift) manage data flow and event propagation.

Key Implementation Details

  • Dynamic viewTree Generation: Components register themselves via SwiftUIContext.registerNode, with hierarchy tracked using SwiftUIParentContext. This supports passthrough components (e.g., <Controller /> from react-hook-form) without explicit prop forwarding.
  • Context System:
    • SwiftUIContext: Manages event handlers and the nodeRegistry.
    • SwiftUIParentContext: Provides parentId to child components via ParentIdProvider, ensuring correct tree structure.
  • Prop Initialization: Native Props classes use Decodable to initialize from JSON, reducing redundancy and ensuring consistency across viewTree and Fabric flows.
  • Rendering: Components return null in JSX, as the UI is fully handled by SwiftUI on the native side.

Notes

  • State Management: The library is agnostic to state management. Use React state, react-hook-form, formik, or any other library to manage form values.
  • Events: Pass callbacks like onChange or onPress to handle native events in JavaScript.
  • Disabled Fields: Set disabled={true} on components like TextField to disable interaction, with visual feedback (grayed-out text and reduced opacity).

Contributing

Feel free to fork the repo, experiment with new components, or suggest optimizations! Open issues or PRs on GitHub.