Documentation
React Native

React Native

This is a guide for setting up React Cosmos in a React Native project, with or without Expo.

Getting Started

Install the required packages:

npm i -D react-cosmos react-cosmos-native

Add cosmos script to package.json:

package.json
"scripts": {
  "cosmos": "cosmos-native"
}

Create a basic fixture at Hello.fixture.js:

Hello.fixture.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
 
export default () => (
  <View style={styles.container}>
    <Text style={styles.text}>Hello World!</Text>
  </View>
);
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    fontSize: 24,
  },
});

Start React Cosmos:

npm run cosmos

You'll notice Cosmos generated a cosmos.imports.js module, which becomes relevant next. You can add this file to .gitignore.

🚀 Open localhost:5000 (opens in a new tab) in your browser.

The Hello fixture will show up in your React Cosmos UI.

Nice, almost done 👍

At this point Cosmos should successfully read your fixtures. One more step before you can render them.

Set Up React Native Renderer

This is very similar to a custom bundler setup. Cosmos cannot plug itself automatically into React Native's build pipeline (Metro), but you can do it with minimal effort.

Here's a basic file structure to get going. You can tweak this after everything's working.

    • App.cosmos.js
    • App.main.js
    • App.js
    1. Your production app entry point: App.main.js.
    2. Your Cosmos renderer entry point: App.cosmos.js.
    3. The root entry point that decides which to load: App.js.

    If you're using TypeScript replace .js file extensions with .tsx.

    First, rename your existing App.js to App.main.js.

    Then add the Cosmos renderer under App.cosmos.js:

    App.cosmos.js
    import React, { Component } from 'react';
    import { NativeFixtureLoader } from 'react-cosmos-native';
    import { rendererConfig, moduleWrappers } from './cosmos.imports';
     
    export default class CosmosApp extends Component {
      render() {
        return (
          <NativeFixtureLoader
            rendererConfig={rendererConfig}
            moduleWrappers={moduleWrappers}
          />
        );
      }
    }

    Finally, create a new App.js that routes between your main and Cosmos entry points based on enviromnent:

    App.js
    module.exports = global.__DEV__
      ? require('./App.cosmos')
      : require('./App.main');

    That's it!

    Open your app in the simulator and the Cosmos renderer should say "No fixture selected". Go back to your React Cosmos UI, click on the Hello fixture and it will render in the simulator.

    Congratulations 😎

    You've taken the first step towards designing reusable components. You're ready to prototype, test and interate on components in isolation.

    App Fixture

    You'll often want to load the entire app in development. The simplest way to do this without disconnecting the Cosmos entry point is to create an App fixture:

    App.fixture.js
    import App from './App.main';
     
    export default () => <App />;

    Initial Fixture

    You can configure the Cosmos Native renderer to auto load a fixture on init.

    <NativeFixtureLoader
      rendererConfig={rendererConfig}
      moduleWrappers={moduleWrappers}
      initialFixtureId={{ path: 'src/__fixtures__/HelloWorld.ts' }}
    />

    initialFixtureId expects a fixture path relative to the project root. You'll find the exact path in cosmos.imports.js as a key in the fixtures object.

    Troubleshooting

    React Native for Web

    You can get Cosmos to mirror your fixtures on both DOM and Native renderers (opens in a new tab) using the following steps:

    1. Set up Cosmos for Native using the steps above.
    2. Set up react-cosmos-plugin-webpack as described here.
    3. Start Cosmos with the cosmos --expose-imports command.