Born React Native Godot
Born React Native Godot: Embedding the Godot Engine in React Native
In the rapidly evolving world of mobile development, marrying powerful game engines with flexible UI frameworks opens up exciting possibilities. Born React Native Godot is a bridge that lets you embed the Godot Engine directly inside React Native applications. Born teamed up with Migeran to create a stable, scalable solution that brings Godot’s rendering and game logic into the familiar world of React Native, unlocking a cohesive cross-platform experience for Android and iOS. This detailed description walks you through what the project offers, how to get started with the example app, and advanced topics for tailoring LibGodot builds and debugging the engine within your app.
Main Features: What React Native Godot Delivers
- Cross-platform support: Android and iOS, built on LibGodot.
- Stability and scale: A proven implementation used by millions in Born’s own applications.
- Lifecycle control: Start, stop, and restart the Godot Engine on demand, with the ability to reconfigure the engine between restarts to load different Godot apps.
- Pause and resume: Pause the Godot instance and resume later without fully shutting it down.
- Threading separation: Godot runs on its own thread, leaving the main app thread and the React Native JavaScript thread free for UI and business logic.
- Horizontal and vertical embedding: The Godot main window and subwindows can be embedded on the same screen or on separate screens, enabling versatile UI layouts.
- Full Godot API accessibility: The entire Godot API is exposed to TypeScript/JavaScript, including object instantiation, method calls, property access, signal connections, and passing JS functions as Godot callables.
Getting Started with the Example App
The example app is your guided tour. It demonstrates the core features of React Native Godot in action and serves as a reference implementation for projects of any size.
Install Prerequisites
During development, ASDF is employed to manage external dependencies such as Node, Java, Gradle, and Ruby. If you already use ASDF, keep your environment consistent by running:
- asdf install
This ensures dependencies align with the project’s environment. Alternatively, you can set up React Native prerequisites with your preferred method. The key is to provide a stable foundation so that the Godot integration behaves consistently across platforms.
Export the Godot App
To test and package Godot apps within the React Native environment, you’ll need to export the Godot project for each platform. The example includes scripts designed to export both the main test and a second test configuration:
- cd example
- ./exportgodotGodotTest.sh android
- ./exportgodotGodotTest.sh ios
- ./exportgodotGodotTest2.sh android
- ./exportgodotGodotTest2.sh ios
These scripts assume Godot is installed in the system’s standard location (macOS). If your Godot editor resides elsewhere or you’re on Linux, set the GODOT_EDITOR environment variable before running the scripts:
- export GODOTEDITOR=/path/to/godoteditor
Configure and Download LibGodot
React Native Godot relies on prebuilt LibGodot binaries. Use the following commands to resolve dependencies and fetch the prebuilt LibGodot release:
- cd example
- yarn
- yarn download-prebuilt
These commands install React Native dependencies from npm and pull the prebuilt LibGodot release from GitHub, enabling you to keep LibGodot updates independent from the main package.
Run on the iOS Simulator
If you’re targeting iOS, you can run the example in the iOS Simulator with:
- cd example/ios
- bundle install
- bundle exec pod install
- cd ..
- yarn ios
Run on the Android Emulator
For Android testing, use:
- cd example
- yarn android
Use Your Native IDEs
React Native Godot is designed to be approachable with standard iOS and Android development tools. Open:
- iOS: ios/GodotTest.xcworkspace in Xcode
- Android: android in Android Studio
Note: If you use ASDF to manage Java and Node dependencies, start Android Studio from within the react-native-godot or example folder so the tooling can be located properly. For macOS:
- cd example
- open -a "Android Studio"
Convenience Script for Dependency Management
The example app includes an update_deps.sh script to streamline setup for both iOS and Android. It enables you to initialize project dependencies in one step:
- cd example
- ./update_deps.sh
- yarn ios # or yarn android
Your First React Native Godot App
Born React Native Godot ships as an npm package. Adding it to your app is straightforward:
- Update your package.json:
- yarn add @borndotcom/react-native-godot
LibGodot is provided as prebuilt binaries, downloaded separately to keep updates flexible:
- yarn download-prebuilt
Importing and using the Godot view is a matter of wiring the components in your React Native code:
Import:
import { RTNGodot, RTNGodotView, runOnGodotThread } from "@borndotcom/react-native-godot";
Add the Godot View to your app:
For the main Godot window, omit the windowName property.
Initializing the Godot Instance
To bootstrap Godot, you’ll typically incorporate Expo’s FileSystem module to locate Godot resources and pass the correct command-line options to the engine. Install the module:
- yarn add expo-file-system
Then initialize Godot on the Godot thread:
- import * as FileSystem from 'expo-file-system/legacy';
- function initGodot() {
- runOnGodotThread(() => {
- 'worklet';
- console.log("Initializing Godot");
- if (Platform.OS === 'android') {
- RTNGodot.createInstance([ "--verbose", "--path", "/main", "--rendering-driver", "opengl3", "--rendering-method", "gl_compatibility", "--display-driver", "embedded" ]);
- } else {
- RTNGodot.createInstance([ "--verbose", "--main-pack", FileSystem.bundleDirectory + "main.pck", "--rendering-driver", "opengl3", "--rendering-method", "gl_compatibility", "--display-driver", "embedded" ]);
- }
- });
- }
Key Notes for Initialization
- Godot accepts the usual command-line parameters; the embedded display driver is essential for embedding Godot into React Native.
- You can point to a directory or a pack file for your Godot content.
- Android access to a pack file within the main app package is slower; the recommended approach is to place the Godot app as a folder of assets in the asset directory.
- iOS can work with a pack file directly, which is generally simpler.
- Runtime updates to the Godot content are possible by loading different Godot apps, enabling smaller initial app sizes and device-specific builds.
Add the Godot Initialization to the App Component
A typical Hello World approach initializes Godot when the App view is shown:
- const App = () => {
- useEffect(() => {
- initGodot();
- return () => {};
- }, []);
- return (
- );
- };
If you’re looking for a fuller demonstration, check the example app in the repository for more elaborate usage patterns.
Stopping, Pausing, and Resuming Godot
Control the Godot lifecycle directly from JavaScript:
- Stop the Godot instance:
- function destroyGodot() {
- runOnGodotThread(() => {
- "worklet";
- RTNGodot.destroyInstance();
- });
- }
Note: After stopping, you can start a new instance with RTNGodot.createInstance, enabling different configurations or Godot projects.
Pause and resume:
- Pause:
- RTNGodot.pause();
- Resume:
- RTNGodot.resume();
Export Your Godot Project
Godot’s standard export pipeline remains intact. Export to PCK (or ZIP) rather than the entire application for inclusion in the React Native app. The example provides export scripts (exportgodot.sh and exportgodot_GodotTest.sh) that facilitate the process.
To export, use the script with parameters indicating:
- --target: Base directory for exported content
- --project: Directory of the Godot project
- --name: Name of the exported project
- --preset: The export preset
- --platform: iOS or Android
Notes:
- Android projects export as folders; iOS exports as PCK files.
- The export script looks for a Godot installation under the Applications folder by default. If your Godot installation is elsewhere, set GODOT_EDITOR to the path of your Godot editor.
Godot API Usage: Accessing and Controlling the Engine from JavaScript
Once you’ve imported React Native Godot, you can access the Godot API through the RTNGodot class.
Get the API entry point:
let Godot = RTNGodot.API();
Access a singleton:
var engine = Godot.Engine;
Instantiate Godot objects:
var vector = Godot.Vector2();
Access and modify properties:
var vector = Godot.Vector2();
vector.x = 1.0;
vector.y = 2.0;
Call Godot methods:
var sceneTree = engine.getmainloop();
var root = sceneTree.get_root();
Attach to signals:
var button = Godot.Button();
button.set_text("Button");
button.pressed.connect(function() { console.log("Button pressed."); });
Pass JS functions to Godot (callables):
Create a RNInterface Node in Godot that accepts a callable in GDScript, then call back into JavaScript:
- gdscript:
- extends Node
- class_name RNInterface
- func test_callable(c: Callable) -> void:
- c.call("Hello from Godot")
- TypeScript:
- const iface = root.find_child("RNInterface", true, false);
- iface.test_callable(function(s: string) {
- console.log("Received text from Godot: " + s);
- });
Threading and JavaScript in React Native
React Native places the main JavaScript code on a separate thread from the native app UI. Godot, too, runs on its own thread, isolated from the main interfaces. To communicate with the Godot thread safely, React Native Godot uses the react-native-worklets-core library, enabling worklets—JavaScript functions designated with the "worklet" keyword—to execute on the Godot thread.
- A minimal worklet example:
- function worklet() {
- 'worklet';
- }
Worklets and their dependencies are compiled into self-contained bundles that run in separate JavaScript contexts connected to separate threads. For convenience, React Native Godot exposes runOnGodotThread, which allows you to execute such workletized functions on the Godot thread. This approach is generally recommended because direct calls from the main React Native thread to Godot can have caveats, such as thread-safety concerns with the Scene Tree and non-interchangeable object references between JS contexts.
Caveats and Best Practices
- Invoking Godot code from the main JS thread can be problematic because it may run on a background thread that cannot access the entire Godot scene tree directly. Favor runOnGodotThread for interactions that affect Godot state.
- Object references obtained on the main JS thread and in worklets belong to different JS contexts and are not interchangeable. If you need multi-context interoperability, consider more complex patterns or consult the maintainers for guidance.
- If you require cross-context object sharing, discuss your needs with Migeran to evaluate options and performance trade-offs.
Advanced Topics
Using a Custom LibGodot Build
If your project requires a custom LibGodot build, you can follow these steps to generate and integrate it:
1) Clone LibGodot on the libgodotmigeran45 branch (including submodules):
- git clone --recursive https://github.com/migeran/libgodot -b libgodotmigeran45
2) Build LibGodot from source:
- cd libgodot
- ./buildprebuiltrelease.sh # for release libraries
- or ./buildprebuiltdev.sh # for development libraries
Note: You can comment out unneeded lines in the build script if you’re targeting a single platform. The output will be placed in build/prebuilt/release or build/prebuilt/dev.
3) Set environment variables to point to the custom LibGodot artifacts:
- export LIBGODOTXCFRAMEWORKPATH=path/to/libgodot/build/prebuilt/release or dev/libgodot.xcframework.zip
- export LIBGODOTCPPXCFRAMEWORK_PATH=path/to/libgodot/build/prebuilt/release or dev/libgodot-cpp.xcframework.zip
- export LIBGODOTANDROIDPATH=path/to/libgodot/build/prebuilt/release or dev/libgodot-android.zip
- export LIBGODOTCPPANDROID_PATH=path/to/libgodot/build/prebuilt/release or dev/godot-cpp-android.zip
- export SHASUM_CHECK=false
- export REPLACE_EXISTING=true
4) Install the prebuilt artifacts:
- yarn download-prebuilt
5) If you’re using development builds on Android, update the Gradle configuration to include the dev artifact:
- api "com.migeran.libgodot:godot-debug:${libGodotVersion}-SNAPSHOT"
6) Debugging native Godot code:
- Build and install a development LibGodot version.
- On iOS, you can set breakpoints directly in Xcode in the Godot engine.
- On Android, you may need to add a Symbol directory for libgodot_android.so and possibly include Godot’s source in Android Studio to set breakpoints. A practical tip is to create a symbolic link inside your React Native Godot library to point to your LibGodot source.
Debugging Godot Projects in the Godot Editor
Android
1) For remote debugging, add these parameters to RTNGodot.createInstance:
- '--remote-debug', 'tcp://127.0.0.1:6007'
2) Expose port 6007 on your Android device:
- adb reverse tcp:6007 tcp:6007
3) In the Godot Editor, enable Debug -> Keep Debug Server Open, then set breakpoints in the editor and you can run the app and hit those breakpoints.
4) Start debugging by launching your app from Android Studio.
iOS
1) For remote debugging, install and configure LibGodot as described earlier.
2) In the Godot Editor, go to godot -> Editor Settings -> Network -> Debug -> Remote Host and set your Mac’s IP address. Also enable Debug -> Keep Debug Server Open.
3) Add remote-debug parameters to RTNGodot.createInstance:
- '--remote-debug', 'tcp://:6007'
4) Run from Xcode to begin debugging with breakpoints. Ensure that your Mac and iOS device share the same network.
Born: Opportunities and Growth
Born continues to expand, with new positions in Berlin and New York. We’re seeking the best React Native engineers who can influence millions of users daily and push the envelope of technology. If you’re excited by the intersection of React Native and game engines, explore opportunities at born.com.
Commercial Support and Development
Migeran offers commercial support and development services around React Native Godot, LibGodot, and the Godot Engine. If you’re looking for guided implementation, custom integration, or enterprise-grade support, Start Here with describing your requirements at migeran.com/contact.
License
Born React Native Godot is released under the MIT license, inviting developers to adapt, extend, and distribute the library in a wide range of products and projects while keeping robust openness and collaboration.
Closing Thoughts
React Native Godot represents a thoughtful convergence of a high-performance game engine with a flexible, widely adopted mobile UI framework. By enabling embedding of Godot within React Native apps, developers can craft immersive experiences that blend native interface polish with dynamic, graphically rich content. The architecture emphasizes stability through a separate Godot thread, modular export workflows for Android and iOS, and a comprehensive API surface accessible from JavaScript/TypeScript. For teams aiming to deliver cross-platform games, interactive experiences, or data-visualization apps with 2D/3D capabilities, this integration offers a compelling path forward. The combination of community-driven tooling (Godot), modern JavaScript capabilities, and a clear development workflow makes React Native Godot a powerful option to explore in your next mobile project.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/borndotcom/react-native-godot
GitHub - borndotcom/react-native-godot: Born React Native Godot
Born React Native Godot is a bridge that lets you embed the Godot Engine directly inside React Native applications, providing a stable and scalable solution for...
github - borndotcom/react-native-godot
Maintain Born React Native Godot? Add the badge to your README
Show that the project is featured on TechLogHub and send readers to this write-up.
[](https://techloghub.com/open-source/born-react-native-godot?utm_source=techloghub_badge&utm_medium=referral&utm_campaign=readme)
