Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 148 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
</a>

<p align="center">
Set of helpers to make your brownfield integration smooth and easy.
A set of helpers to make your brownfield integration smooth and easy.
</p>

---
Expand All @@ -19,94 +19,206 @@

[![tweet][tweet-badge]][tweet]

> [!TIP]
> Download a free copy of an ebook that goes step-by-step through [incremental React Native adoption in native apps](https://www.callstack.com/ebooks/incremental-react-native-adoption-in-native-apps?utm_campaign=brownfield&utm_source=github&utm_medium=referral&utm_content=react-native-brownfield).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could get an ebook banner? This can be easily missed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hope this works?
image


## Features

- **Easily integrate** React Native with existing native app
- **Easily integrate** React Native with an existing native app
- Start React Native with **one method** and invoke code as soon as it's loaded
- Compatible with **both old and new React Native architecture**!
- Compatible with **both legacy and new React Native architecture**!
- Reuse the same instance of React Native between different components
- Use predefined **native building blocks** - crafted for React Native
- Disable and enable **native gestures and hardware buttons** from JavaScript
- Works well with **any native navigation** pattern, as well as every React Native JavaScript based navigation
- Works well with **any native navigation** pattern, as well as any React Native JavaScript-based navigation
- Compatible with all native languages **Objective-C**, **Swift**, **Java** and **Kotlin**
- Supports UIKit and SwiftUI on iOS and Fragments and Jetpack Compose on Android


## Installation

The React Native Brownfield library is intended to be installed in a React Native app that is later consumed as a framework artifact by your native iOS or Android app.

In your React Native project run:

```sh
npm install @callstack/react-native-brownfield
```

or
## Usage

```sh
yarn add @callstack/react-native-brownfield
### Packaging React Native app as a framework

First, we need to package our React Native app as an XCFramework or Fat-AAR.

#### With RNEF

Follow [Integrating with Native Apps](https://www.rnef.dev/docs/brownfield/intro) steps in RNEF docs and run:

- `rnef package:ios` for iOS
- `rnef package:aar` for Android

#### With custom scripts

Instead of using RNEF, you can create your own custom packaging scripts. Here are base versions for iOS and Android that you'll need to adjust for your project-specific setup:

- [Example iOS script](https://github.com/callstackincubator/modern-brownfield-ref/blob/main/scripts/build-xcframework.sh)
- [Example Android script](https://github.com/callstackincubator/modern-brownfield-ref/blob/main/scripts/build-aar.sh)

### Native iOS app

In your native iOS app, initialize the React Native thread and display it where you like. For example, to display React Native views in SwiftUI, use the provided `ReactNativeView` component:
Comment thread
thymikee marked this conversation as resolved.
Outdated

```swift
import SwiftUI
import ReactBrownfield # exposed by RN app framework

@main
struct MyApp: App {
init() {
ReactNativeBrownfield.shared.startReactNative {
print("React Native bundle loaded")
}
}

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Welcome to the Native App")
.padding()

NavigationLink("Push React Native Screen") {
ReactNativeView(moduleName: "ReactNative")
.navigationBarHidden(true)
}
}
}
}
}
```

## Enabling New Architecture
For more detailed instructions and API for iOS, see docs for:

- [Objective C](docs/OBJECTIVE_C.md)
- [Swift](docs/SWIFT.md)

### Native Android app

In your native Android app, create a new `RNAppFragment.kt`:

### Android
Add the following to your `android/gradle.properties`:
```kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.callstack.rnbrownfield.RNViewFactory # exposed by RN app framework

class RNAppFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? =
this.context?.let {
RNViewFactory.createFrameLayout(it)
}
}
```
# Enable new architecture
newArchEnabled=true

Add a button to your `activity_main.xml`:

```xml
<Button
android:id="@+id/show_rn_app_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show RN App"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
```

### iOS
Install cocoapods with the flag:
Add a fragment container:

```
RCT_NEW_ARCH_ENABLED=1 pod install
```xml
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```

> [!NOTE]
> New Architecture is enabled by default from React Native 0.76
Update your `MainActivity` to initialize React Native and show the fragment:

## Usage
```kt
class MainActivity : AppCompatActivity() {
private lateinit var showRNAppBtn: Button

React Native Brownfield library works with all major native programming languages. Majority of its API is exposed on the native side. Click on the logo to choose the one that interests you:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ReactNativeHostManager.shared.initialize(this.application)

| [<img src="https://user-images.githubusercontent.com/7837457/63374769-cafd1e80-c38a-11e9-9724-e797a199ebab.png" width="100px;" alt="Objective-C"/><br /><sub><b>Objective-C</b></sub>](docs/OBJECTIVE_C.md) | [<img src="https://user-images.githubusercontent.com/7837457/63374778-ce90a580-c38a-11e9-8f37-72a9a5b9a52f.png" width="100px;" alt="Swift"/><br /><sub><b>Swift</b></sub>](docs/SWIFT.md) | [<img src="https://user-images.githubusercontent.com/7837457/63374794-d2bcc300-c38a-11e9-9a7f-d538563b75db.png" width="100px;" alt="Java"/><br /><sub><b>Java</b></sub>](docs/JAVA.md) | [<img src="https://user-images.githubusercontent.com/7837457/63374783-d0f2ff80-c38a-11e9-9790-041cad53b259.png" width="100px;" alt="Kotlin"/><br /><sub><b>Kotlin</b></sub>](docs/KOTLIN.md) |
| :---: | :---: | :---: | :---: |
showRNAppBtn = findViewById(R.id.show_rn_app_btn)
showRNAppBtn.setOnClickListener {
supportFragmentManager
.beginTransaction()
.replace(R.id.fragmentContainer, RNAppFragment())
.commit()
}
}

}
```

For more detailed instructions and API for Android, see docs for:

- [Java](docs/JAVA.md)
- [Kotlin](docs/KOTLIN.md)

### JavaScript Module

Besides native components, we are exposing JavaScript functions to control the behavior of those components.
Besides native components, we are exposing JavaScript functions to control the behavior of those components from React Native app.

To use the module, simply import it:
To use the module, import it:

```js
import ReactNativeBrownfield from '@callstack/react-native-brownfield';
```

### JavaScript API Reference:
and use the available methods:

**setNativeBackGestureAndButtonEnabled(enabled: boolean)**
#### setNativeBackGestureAndButtonEnabled(enabled: boolean)

A method used to toggle iOS native back gesture and Android hardware back button.
A method used to toggle iOS native back gesture and Android hardware back button.

```js
```ts
ReactNativeBrownfield.setNativeBackGestureAndButtonEnabled(true);
```

**popToNative(animated[iOS only]: boolean)**
#### popToNative(animated[iOS only]: boolean)

A method to pop to native screen used to push React Native experience.
A method to pop to native screen used to push React Native experience.

```js
```ts
ReactNativeBrownfield.popToNative(true);
```

> NOTE: Those methods works only with native components provided by this library.

> **Note:** These methods work only with native components provided by this library.

## Made with ❤️ at Callstack

React Native Brownfield is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack](https://callstack.com) is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!

Like the project? ⚛️ [Join the team](https://callstack.com/careers/?utm_campaign=Senior_RN&utm_source=github&utm_medium=readme) who does amazing stuff for clients and drives React Native Open Source! 🔥
Like the project? ⚛️ [Join the team](https://callstack.com/careers/?utm_campaign=Senior_RN&utm_source=github&utm_medium=readme) which does amazing stuff for clients and drives React Native Open Source! 🔥
Comment thread
thymikee marked this conversation as resolved.
Outdated

## Contributors

Expand All @@ -122,6 +234,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

<!-- badges -->

[build-badge]: https://img.shields.io/circleci/build/github/callstack/react-native-brownfield/master.svg?style=flat-square
[build]: https://circleci.com/gh/callstack/react-native-brownfield
[version-badge]: https://img.shields.io/npm/v/@callstack/react-native-brownfield.svg?style=flat-square
Expand Down
Loading