Creating a Dynamic Starter Kit for React Native - React Native Infinity

October 02, 2019

React Native Infinity

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

RN Folders

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:

  1. Identify and isolate the bare essential configuration for each platform.
  2. Identify core files and changes required for each platform.
  3. Bundle all platform configuration into a separate folders.
  4. 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.

Github - Website GUI

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.

npx react-native-infinity init

init

Add-Platform

Command to add platform configuration to an existing project. Platforms are provided as lowercase, simple strings.

npx react-native-infinity add-platform <platform>

add-platform

GUI

Simple tool that generates a CLI command to initialize a project with the platforms and libraries selected. Can be found atreactnativeinfinity.com

React Native Infinity website

Please visit the docs for more information.