After giving RedwoodJS a shot in a personal project, it got me excited and made me think about the possibility of RedwoodJS having support for building mobile apps too. I think the idea is having one command, yarn rw dev
, that runs the API and the Web is awesome and could be extended to include mobile too.
This topic is a brain-dump around that idea. If it aligns with RedwoodJS long-term plans I’ll be happy to contribute this feature.
1. Zero-config
Like RedwoodJS does for web and API, I think the configuration required for underlying tools such as the Metro bundler should be abstracted away. Users would have a mobile
directory with the sources:
mobile/
├── js/
│ └── App.tsx
├── android/
│ ├── Foo.kotlin
└── ios/
└── Bar.swift
RedwoodJS could be opinionated about where the native iOS and Android code and resources live, as well as how the Javascript-side (React) is structured.
2. Network and navigation
import { useQuery, NavigationContainer } from '@redwoodjs/mobile'
Two building blocks that most apps will need are navigation and networking. In the case of networking, mobile apps could reuse the same stack used for the web (unless there are dependencies with browser-specific APIs). In the case of navigation, RedwoodJS could wrap the react-native-navigation. It’s a widely used and extensively-tested library so I don’t think it should re-invent the wheel with a new implementation.
The equivalent of the navigation primitives for Web would be the router.
3. Auto-linking
Auto-linking and the build pipeline, which are required for building the native apps, are provided by the community’s react-native-cli. I think re-using that from RedwoodJS would worsen the great user-experience that RedwoodJS provides. The reason being is that react-native-cli has an implicit dependency with CocoaPods (Ruby) in order to link the native code of React Native dependencies pulled by NPM/Yarn.
Adding a dependency between RedwoodJS and the React Native CLI would add Ruby & CocoaPods as a transitive dependency and it’d require RedwoodJS users to install Ruby & CocoaPods as well.
I propose building a pure Javascript utility that acts as Webpack but for React Native project. It’d have three responsibilities:
- Auto-link: Without depending on CocoaPods. In the case of iOS, it’d generate Xcode projects with the right linking settings (I have a lot of experience with this one ), and in case of Android, we’d provide a Gradle task that resolves the dependencies at load time.
- Build pipeline: The Android and iOS projects would trigger Metro through this component. It’d make sure that we are calling Metro with the right configuration.
-
Passing variables: That can be accessed from React Native. We could provide components along the lines of
useAuth
, to access variables that are passed by RedwoodJS. For example:
import { useVersion } from "@redwoodj/mobile"
Note that the tool would make Xcode and Android projects an implementation detail. Unlike react-native-cli that keeps those in the repository, and thus complicating RN upgrades, projects are generated when needed. For example, let’s say the user wants to work on the iOS app. They could run yarn rw dev ios
, and the following would happen behind the scenes:
- Generate a
build.gradle
orApp.xcodeproj
in a .gitignored directory. - Compile the app using
xcodebuild
(iOS), orgradle
(Android) - Launch the simulator (iOS) / emulator (Android) with the app and the bundler.
- Run the API.
Since RedwoodJS knows that the app is running in development, it’d pass the right variable to the build pipeline so that internally the network stack points to the right IP address.
4. Shared components
The introduction of mobile, creates the opportunity for sharing components between mobile and the web. There are libraries like react-native-web that provide cross-platform components. RedwoodJS users could reuse those, or implement new ones under a shared/
directory at the root of the project:
shared/
└── components/
└── MyButton.jsx
Final thoughts
Since working on the component that provides auto-linking and a build-pipeline without the CocoaPods dependency has been in my mind for a long time, I’ll start working on that. I think the official react-native-cli could leverage this implementation, and also RedwoodJS if they decide to include mobile in the scope of the project.