Creating a Dynamic Starter Kit for React Native - React Native Infinity
October 02, 2019
Popular libraries (UI, navigation, etc.) and frameworks often provide example projects for educating new users on basic configuration. Some even provide full starter projects to ease initial project setup. However, since modern apps generally require a combination of these libraries, developers are forced to manually configure different types of libraries together.
Starter kits are the obvious next evolutionary step, as they come pre-configured with many popular libraries (react-slingshot, e.g.). However, unless the included libraries match exactly what a new project requires, developers will need to spend time replacing and adding configuration they need. Additionally, actively maintaining starter kits that cover all possible combinations is simply not feasible.
Available starter kits for rendering React Native on different platforms nicely illustrates this problem. Most out-of-tree starter kits only target the web (create-a-react-native-web-app, react-native-web-monorepo) leaving other platforms out. Other starters target all platforms (react-everywhere), requiring developers to manually remove what they don't need.
The problem lies with treating configuration as a static, integrated whole rather than as dynamic, isolated, and individual plugins. Making this switch allows developers to dynamically choose pre-configured libraries, in essence, creating their own starter kits.
In the case of React Native, isolating platform configuration allows developers to dynamically choose what platforms their app supports both during and after project initialization. React Native Infinity is a small, experimental CLI with this goal in mind. Implementing this is surprisingly simple since React Native already isolates platform configuration for Android and iOS.
Isolating Configuration
Broadly speaking, React Native's structure can be broken into three main parts: core
, platform configuration
, and the actual app code
.
Core - Configuration and files that apply across the whole project, for example package.json
, index.js
, and app.json
.
Platform Configuration - Configuration for rendering and building the app on a specific platform.
App Code - Business logic, UI, and everything else that lives in src
.
Out of the box React Native provides Platform Configuration for Android and iOS in their respective folders: android
and ios
. React Native Infinity simply takes this structure and applies it to new platforms by isolating configuration for out-of-tree renders into new platform configuration
folders.
For example, react-native-web
requires configuration (webpack.config.js
), platform files (index.html
), and dependencies (react-dom
) that are specific to rendering React Native on the web but are not required for Android, iOS, MacOS, or Windows. Configuration and platform files can easily go into a separate folder, but core
configuration (dependencies, e.g.), should go in shared files (package.json
) at the project root.
Adding support for more platforms to React Native, then, is a simple process:
- Identify and isolate the bare essential configuration for each platform.
- Identify core files and changes required for each platform.
- Bundle all platform configuration into a separate folders.
- Merge shared core configuration.
This process can be expanded beyond platforms to other React Native libraries, such as navigation, state management, and UI libraries. A simple example is implemented in React Native Infinity with two UI Libraries: Material Bread and UI Kitten.
The last step, after all configuration has been isolated and merge functions created, is to build a simple CLI that asks users what platforms and libraries they want to add.
React Native Infinity CLI
React Native Infinity CLI generates React Native projects that target any combination of platforms (Mobile, Web, Electron, Windows, and MacOS). Platforms can also be added later on with the add-platform
command. Finally, two UI libraries can be added at initialization. Built with Commander.js and Enquirer.js.
1.npm i -g react-native-infinity
Note: This is an experiment in the early stages, if you find a bug, please consider contributing with an issue or PR.
Init
Command to initializes a new project with a series of questions.
1.npx react-native-infinity init
Add-Platform
Command to add platform configuration to an existing project. Platforms are provided as lowercase, simple strings.
1.npx react-native-infinity add-platform <platform>
Please visit the docs for more information.