• This repository has been archived on 15/Feb/2019
  • Stars
    star
    1,003
  • Rank 43,984 (Top 0.9 %)
  • Language
    JavaScript
  • Created almost 8 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Route-centric navigation for React Native

🚨This library is no longer maintained 🚨

Please use "react-navigation", or other alternatives instead.


ExNavigation

A route-centric, batteries-included navigation library for Expo and React Native that works seamlessly on Android and iOS.

A few of our favorite features

  • Android back button handling (it just works, no need to do anything)
  • Tab bar navigation
  • Drawer navigation
  • Sliding tab navigation
  • Optional blurred translucent backgrounds in navigation and tab bar on iOS
  • Alert bars
  • Declarative configuration co-located with your routes
  • Typed with Flow

Help / Support / Questions

We don't provide any realtime support for ExNavigation questions. If you join the Expo Slack and ask a question there, we will direct you to this section of the README. We suggest the following resources:

Installation

As of version 1.9.0, ExNavigation only supports React Native versions >= 0.36.0 due to changes to the css-layout algorithm in React Native core.

  • npm i @expo/ex-navigation babel-preset-react-native-stage-0 --save
  • Change your .babelrc (if you have one, if not, then create one):
{
  "presets": ["react-native-stage-0/decorator-support"]
}

Note: Comprehensive documentation is coming soon! For now, check out the example project in example/. This lib is very much a work in progress.

How to run the example project

or use this link in your mobile phone: https://expo.io/@community/ex-navigation-example

How is this different from what is built into React Native?

NavigationExperimental ships with React Native, it is powerful and flexible, and that comes at the cost of exposing some internals to the app developer. ExNavigation is built on top of NavigationExperimental with the aim of providing a more feature-rich out of the box experience.

A minimal navigation set up

To give you an idea of what the required pieces of are, the following includes only the minimal code necessary to get ExNavigation working.

import React from 'react';
import {
  AppRegistry,
  Text,
  View,
} from 'react-native';

/**
 * If you're using Expo, uncomment the line below to import Exponent
 * BEFORE importing `@expo/ex-navigation`. This sets the status bar
 * offsets properly.
 */
// import Expo from 'expo';

import {
  createRouter,
  NavigationProvider,
  StackNavigation,
} from '@expo/ex-navigation';

/**
  * This is where we map route names to route components. Any React
  * component can be a route, it only needs to have a static `route`
  * property defined on it, as in HomeScreen below
  */
const Router = createRouter(() => ({
  home: () => HomeScreen,
}));

class App extends React.Component {
  render() {
    /**
      * NavigationProvider is only needed at the top level of the app,
      * similar to react-redux's Provider component. It passes down
      * navigation objects and functions through context to children.
      *
      * StackNavigation represents a single stack of screens, you can
      * think of a stack like a stack of playing cards, and each time
      * you add a screen it slides in on top. Stacks can contain
      * other stacks, for example if you have a tab bar, each of the
      * tabs has its own individual stack. This is where the playing
      * card analogy falls apart, but it's still useful when thinking
      * of individual stacks.
      */
    return (
      <NavigationProvider router={Router}>
        <StackNavigation initialRoute={Router.getRoute('home')} />
      </NavigationProvider>
    );
  }
}

class HomeScreen extends React.Component {
  /**
    * This is where we can define any route configuration for this
    * screen. For example, in addition to the navigationBar title we
    * could add backgroundColor.
    */
  static route = {
    navigationBar: {
      title: 'Home',
    }
  }

  render() {
    return (
      <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
        <Text>HomeScreen!</Text>
      </View>
    )
  }
}


AppRegistry.registerComponent('main', () => App);

Push and popping routes

 const Router = createRouter(() => ({
   home: () => HomeScreen,
+  about: () => AboutScreen,
 }));

 class HomeScreen extends React.Component {
    render() {
     return (
       <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
         <Text>HomeScreen!</Text>
+        <Text onPress={this._goToAbout}>
+          Push about route
+        </Text>
       </View>
     )
   }
+
+  _goToAbout = () => {
+    this.props.navigator.push(Router.getRoute('about'));
+  }
 }

+ class AboutScreen extends React.Component {
+  static route = {
+    navigationBar: {
+      title: 'About',
+    }
+  }
+
+  render() {
+    return (
+      <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
+        <Text>AboutScreen!</Text>
+        <Text onPress={this._goBackHome}>
+          Go back home
+        </Text>
+      </View>
+    )
+  }
+
+  _goBackHome = () => {
+    this.props.navigator.pop();
+  }
+}

In the above example you will see that we push and pop routes to and from the stack by calling those functions on the navigator prop. This is a prop that is passed into all components that you registered with the router. If you need to access the navigator on a component that is not a route, you can either pass it in manually from your route component or use withNavigation as a decorator on the component:

import React from 'react';
import { Text } from 'react-native';
import { withNavigation } from '@expo/ex-navigation';

@withNavigation
class BackButton extends React.Component {
  render() {
    return <Text onPress={this._goBack}>Go back</Text>
  }

  _goBack = () => {
    if (this.props.navigator.getCurrentIndex() > 0) {
      this.props.navigator.pop();
    }
  }
}

Alternatively, rather than importing Router each time, you may pass the route's name directly:

_goToAbout = () => {
-  this.props.navigator.push(Router.getRoute('about'));
+  this.props.navigator.push('about');
}

… bearing in mind you will loose the ability to type check the route (if using Flow).

Passing params to a route

  class HomeScreen extends React.Component {

   _goToAbout = () => {
-    this.props.navigator.push(Router.getRoute('about'));
+    this.props.navigator.push(Router.getRoute('about', {name: 'Brent'}));
   }
 }

 class AboutScreen extends React.Component {
   static route = {
     navigationBar: {
-      title: 'About',
+      title(params) {
+        return `Greeting for ${params.name}`;
+      },
     }
   }

   render() {
     return (
       <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
-        <Text>AboutScreen!</Text>
+        <Text>AboutScreen! Hello {this.props.route.params.name}</Text>
         <Text onPress={this._goBackHome}>
           Go back home
         </Text>

Updating route params

Sometimes you don't have all of the data that you need to set the navigation bar title when you mount the route - for example, if you navigate to a user profile screen by user id and need to fetch the profile data before you know what the name is. In this case, one solution is to use the updateCurrentRouteParams function available on StackNavigation navigators.

 class AboutScreen extends React.Component {
   static route = {
     navigationBar: {
       title(params) {
-        return `Greeting for ${params.name}`;
+        if (typeof params.isCool === 'undefined') {
+          return '';
+        }
+
+        return params.isCool ? `Hey cool person!` : `zzz`;
       },
     }
   }

+  componentDidMount() {
+    setTimeout(() => {
+      this.props.navigator.updateCurrentRouteParams({
+        isCool: this.props.route.params.name === 'Brent'
+      })
+    }, 1000);
+  }
+

Make navigation bar buttons update based on route or app state

See the following example for details on how to connect your buttons to the navigator or Redux to perform actions: https://github.com/brentvatne/ex-navigation-conditional-buttons-example

StackNavigation actions

As you saw above, you can push and pop routes. The following is a full list of functions that can be called on StackNavigation navigators.

  • push: add a route to the top of the stack
  • pop(n): remove n routes from the top of the stack, defaults to 1
  • popToTop: remove all but the first route from the stack
  • replace: replace the current route with a given route
  • showLocalAlert: show an alert bar with given text and styles
  • hideLocalAlert: hide an active alert bar
  • immediatelyResetStack: reset the current stack to the given stack
  • updateCurrentRouteParams: update route params as in the above example

Working with the navigation bar

The navigation bar configuration exposes a set of useful options that should allow you to do most things that you will want to do with it.

You specify the configuration for the navigationBar on the route component, or on a StackNavigation component.

On a route component

When you configure the navigationBar on a route component, the configuration only applies to that specific component. This is usually useful for specifying the title or components to render on the left or right of the title.

 class HomeScreen extends React.Component {
   _goToAbout = () => {
     this.props.navigator.push(Router.getRoute('about', {name: 'Brent'}));
   }
 }

 class AboutScreen extends React.Component {
   static route = {
     navigationBar: {
       title: 'Title goes here',
       renderRight: (route, props) => <SignOutButton name={route.params.name} />
     }
   }

   // ...
 }

 @connect()
 class SignOutButton extends React.Component {
   render() {
      return (
        <TouchableOpacity onPress={this.props.dispatch(Actions.signOut())}>
          <Text>Sign out {this.props.name}</Text>
        </TouchableOpacity>
      );
   }
 }

On StackNavigation

You can configure the defaultRouteConfig for all routes within a StackNavigation to save you needing to specify properties like the navigationBar backgroundColor and tintColor (color to use for the title and back button or drawer menu hamburger button).

class App extends React.Component {
  render() {
    return (
      <NavigationProvider router={Router}>
        <StackNavigation
          defaultRouteConfig={{
            navigationBar: {
              backgroundColor: '#000',
              tintColor: '#fff',
            }
          }}
          initialRoute={Router.getRoute('home')}
        />
      </NavigationProvider>
    );
  }
}

navigationBar properties

  • title - a string or a function that returns a string. The function is provided with the route params as the first argument.
  • titleStyle - Text.propTypes.style object to use for the title.
  • backgroundColor - the background color to use for the navigationBar.
  • tintColor - the color to use for the title text and back button or drawer button icons.
  • visible - boolean that indicates whether the navigationBar should be visible for this route.
  • translucent - iOS and Expo only, use background blur on the navigationBar, like in the Apple Podcasts app, for example.
  • borderBottomWidth - the width of the bottom border
  • borderBottomColor - the color of the bottom border
  • renderLeft - a function that should return a React component that will be rendered in the left position of the navigationBar.
  • renderTitle - a function that should return a React component that will be rendered in the title position of the navigationBar.
  • renderRight - a function that should return a React component that will be rendered in the right position of the navigationBar.
  • renderBackground - a function that should return a React component that will be rendered in the background of the navigationBar.

TabNavigation

A minimal example using tabs:

import {
  StackNavigation,
  TabNavigation,
  TabNavigationItem as TabItem,
} from '@expo/ex-navigation';


// Treat the TabScreen route like any other route -- you may want to set
// it as the initial route for a top-level StackNavigation
class TabScreen extends React.Component {
  static route = {
    navigationBar: {
      visible: false,
    }
  }

  render() {
    return (
      <TabNavigation
        id="main"
        navigatorUID="main"
        initialTab="home">
        <TabItem
          id="home"
          title="Home"
          selectedStyle={styles.selectedTab}
          renderIcon={(isSelected) => <Image source={require('./assets/images/home.png')} /> }>
          <StackNavigation
            id="home"
            navigatorUID="home"
            initialRoute={Router.getRoute('home')}
          />
        </TabItem>

        <TabItem
          id="posts"
          title="Posts"
          selectedStyle={styles.selectedTab}
          renderIcon={(isSelected) => <Image source={require('./assets/images/posts.png')} /> }>
          <StackNavigation
            id="posts"
            initialRoute={Router.getRoute('posts')}
          />
        </TabItem>

        <TabItem
          id="profile"
          title="Profile"
          selectedStyle={styles.selectedTab}
          renderIcon={(isSelected) => <Image source={require('./assets/images/profile.png')} /> }>
          <StackNavigation
            id="profile"
            initialRoute={Router.getRoute('profile')}
          />
        </TabItem>
      </TabNavigation>
    );
  }
}

See an example of TabNavigation in a real app here.

If you'd like to switch tabs programmatically (eg: a notification arrives and you want to jump to a notifications tab, or you tap on a button to open your profile but within another tab) you can use jumpToTab. For the code below to work, we need the navigatorUID prop to be set on TabNavigator, as with the example above.

<TouchableOpacity
  onPress={() => {
    this.props.navigation.performAction(({ tabs, stacks }) => {
      tabs('main').jumpToTab('profile');
      stacks('home').push(route);
    });
  }}
/>

DrawerNavigation

A minimal example using the DrawerNavigation:

import {
  StackNavigation,
  DrawerNavigation,
  DrawerNavigationItem,
} from '@expo/ex-navigation';

// Treat the DrawerNavigationLayout route like any other route -- you may want to set
// it as the intiial route for a top-level StackNavigation

class DrawerNavigationLayout extends React.Component {
  static route = {
    navigationBar: {
      visible: false,
    }
  };

  render() {
    return (
      <DrawerNavigation
        id='main'
        initialItem='home'
        drawerWidth={300}
        renderHeader={this._renderHeader}
      >
        <DrawerNavigationItem
          id='home'
          selectedStyle={styles.selectedItemStyle}
          renderTitle={isSelected => this._renderTitle('Home', isSelected)}
        >
          <StackNavigation
            id='home'
            initialRoute={Router.getRoute('home')}
          />
        </DrawerNavigationItem>

        <DrawerNavigationItem
          id='about'
          selectedStyle={styles.selectedItemStyle}
          renderTitle={isSelected => this._renderTitle('About', isSelected)}
        >
          <StackNavigation
            id='about'
            initialRoute={Router.getRoute('about')}
          />
        </DrawerNavigationItem>

      </DrawerNavigation>
    );
  }

  _renderHeader = () => {
    return (
      <View style={styles.header}>
      </View>
    );
  };

  _renderTitle(text: string, isSelected: boolean) {
    return (
      <Text style={[styles.titleText, isSelected ? styles.selectedTitleText : {}]}>
        {text}
      </Text>
    );
  };
}

const styles = StyleSheet.create({
  header: {
    height: 20
  },

  selectedItemStyle: {
    backgroundColor: 'blue'
  },

  titleText: {
    fontWeight: 'bold'
  },

  selectedTitleText: {
    color: 'white'
  }
});

Integrate with your existing Redux store

Behind the scenes ExNavigation manages your navigation state using Redux in its own store. If you'd like to store the navigation state on your app's store, you can use the createStoreWithNavigation function when creating the store and then manually provide the NavigationContext, initialized with your app's store.

/* Your store definition, let's say state/Store.js */

import { createNavigationEnabledStore, NavigationReducer } from '@expo/ex-navigation';
import { combineReducers, createStore } from 'redux';

const createStoreWithNavigation = createNavigationEnabledStore({
  createStore,
  navigationStateKey: 'navigation',
});

const store = createStoreWithNavigation(
  /* combineReducers and your normal create store things here! */
  combineReducers({
    navigation: NavigationReducer,
    // other reducers
  })
);

export default store;
/* Your routes, Router.js */

import { createRouter } from '@expo/ex-navigation';
import HomeScreen from './HomeScreen';

export const Router = createRouter(() => ({
  home: () => HomeScreen,
}));
 /* The top level of your app, often in main.js or index.[ios/android].js */

 import {
   NavigationContext,
   NavigationProvider,
   StackNavigation,
 } from '@expo/ex-navigation';

 import Store from './state/Store';
 import Router from './Router';

+const navigationContext = new NavigationContext({
+  router: Router,
+  store: Store,
+})

 return (
   <Provider store={Store}>
+    <NavigationProvider context={navigationContext}>
       <StackNavigation yourUsualPropsHere />
     </NavigationProvider>
   </Provider>
 )

Perform navigation actions from outside of a component

You might be using some Redux middleware like saga, thunk, promise, or effex (we recommend effex because we love async/await). Whatever you're using, you no longer have access to this.props.navigator and the like. What to do? Well as long as you include your navigation state inside of your Redux store, you can dispatch a NavigationAction to it -- after all, this is what this.props.navigator.push etc. do behind the scenes.

In the following example we call getState and dispatch directly on your store -- feel free to change this to whatever the equivalent is for your context (eg: if this was effex, dispatch and getState would be passed in to the goHome function).

import { NavigationActions } from '@expo/ex-navigation'
import Store from '../state/Store';
import Router from './Router'

export default function goHome() {
  let navigatorUID = Store.getState().navigation.currentNavigatorUID;
  Store.dispatch(NavigationActions.push(navigatorUID, Router.getRoute('home')))
}

Screen Tracking / Analytics

You might want to do some screen tracking in your apps. Since the entire navigation state is in redux, screen tracking is as simple as writing a redux middleware. Below is a simple middleware that uses routeName as the screen name for tracking screens.

import SegmentIO from 'react-native-segment-io-analytics';

const navigationStateKey = 'navigation';

// gets the current screen from navigation state
function getCurrentScreen(getStateFn) {
  const navigationState = getStateFn()[navigationStateKey];
  // navigationState can be null when exnav is initializing
  if (!navigationState) return null;

  const { currentNavigatorUID, navigators } = navigationState;
  if (!currentNavigatorUID) return null;

  const { index, routes } = navigators[currentNavigatorUID];
  const { routeName } = routes[index];
  return routeName;
}

const screenTracking = ({ getState }) => next => action => {
  if (!action.type.startsWith('EX_NAVIGATION')) return next(action);
  const currentScreen = getCurrentScreen(getState);
  const result = next(action);
  const nextScreen = getCurrentScreen(getState);
  if (nextScreen !== currentScreen) {
    SegmentIO.screen(nextScreen);
  }
  return result;
}

export default screenTracking;

Android back button handling

React Native includes a global BackHandler module. Rather than using this module directly, include the AndroidBackButtonBehavior component in routes where you'd like to control the back button. AndroidBackButtonBehavior accepts isFocused and onBackButtonPress. If isFocused is true, the onBackButtonPress will fire when the user presses the back button. You need to make sure that onBackButtonPress returns a promise that wraps the function you want to be called. Eg.

<AndroidBackButtonBehavior isFocused={someboolean}
   onBackButtonPress={()=>Promise.resolve(fireMeWhenSomeBooleanIsTrue)}>
   ...
</AndroidBackButtonBehavior>

More Repositories

1

expo

An open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.
TypeScript
28,995
star
2

create-react-native-app

Create React Native apps that run on iOS, Android, and web
TypeScript
13,151
star
3

expo-cli

Tools for creating, running, and deploying universal Expo and React Native apps
TypeScript
2,590
star
4

examples

Example projects that demonstrate how to use Expo APIs and integrate Expo with other popular tools
JavaScript
1,567
star
5

router

[ARCHIVE]: Expo Router has moved to expo/expo -- The File-based router for universal React Native apps
TypeScript
1,358
star
6

react-native-action-sheet

A cross-platform ActionSheet for React Native
TypeScript
1,301
star
7

xde

The Expo Development Environment
JavaScript
1,168
star
8

google-fonts

Use any of the 1000+ fonts (and their variants) from fonts.google.com in your Expo app.
JavaScript
739
star
9

expo-github-action

Expo GitHub Action makes it easy to automate EAS builds or updates
TypeScript
714
star
10

expo-server-sdk-node

Server-side library for working with Expo using Node.js
TypeScript
674
star
11

fyi

Little bits of information that you may find useful when interacting with Expo tools and service. Append the markdown filename to https://expo.fyi/ to get a quick link to it.
667
star
12

eas-cli

Fastest way to build, submit, and update iOS and Android apps
TypeScript
648
star
13

vector-icons

JavaScript
638
star
14

expo-three

Utilities for using THREE.js on Expo
TypeScript
619
star
15

react-native-read-more-text

JavaScript
572
star
16

ex-navigator

Route-centric navigation built on top of React Native's Navigator
JavaScript
522
star
17

react-native-infinite-scroll-view

An infinitely scrolling view that notifies you as the scroll offset approaches the bottom
JavaScript
520
star
18

awesome-expo

Useful resources for creating apps with Exponent
468
star
19

exp

JavaScript
465
star
20

react-native-invertible-scroll-view

An invertible ScrollView for React Native
JavaScript
460
star
21

config-plugins

Out-of-tree Expo config plugins for packages that haven't adopted the config plugin system yet.
TypeScript
401
star
22

turtle

Standalone app builder service
TypeScript
386
star
23

vscode-expo

Expo Tools keep you productive with debugging, IntelliSense, and prebuild previews
TypeScript
377
star
24

orbit

Accelerate your development workflow with one-click build launches and simulator management from your macOS menu bar
TypeScript
346
star
25

snack

Expo Snack lets you run Expo in the browser.
TypeScript
340
star
26

react-native-appearance

Access operating system appearance information (currently only light/dark mode) on iOS, Android, and web
Java
337
star
27

expo-pixi

Tools for using pixi.js in Expo
JavaScript
300
star
28

use-unmount-signal

A React Hook to cancel promises when a component is unmounted
TypeScript
289
star
29

web-examples

Examples of using Expo in the browser.
JavaScript
273
star
30

image-upload-example

Demonstration of how to upload images from the ImagePicker, using a node backend to upload to S3
JavaScript
228
star
31

snack-web

TypeScript
214
star
32

expo-phaser

Use Phaser.js on mobile with Expo GL
JavaScript
212
star
33

sentry-expo

TypeScript
197
star
34

custom-expo-updates-server

TypeScript
194
star
35

fluxpybird

some ideas involving games and Redux
JavaScript
179
star
36

stripe-expo

Use the Stripe HTTP API in Expo without the DOM, node, or native deps
JavaScript
160
star
37

react-native-responsive-image

A responsive Image component that chooses the best-resolution image for the current screen
JavaScript
160
star
38

react-native-loading-container

A container component that takes care of loading/catching timeouts/retrying
JavaScript
156
star
39

camerja

JavaScript
156
star
40

playlist-example

JavaScript
151
star
41

match-media

Universal polyfill for match media API using Expo APIs on mobile
TypeScript
131
star
42

dev-plugins

Out-of-tree Expo devtools plugins for packages that haven't adopted the Expo devtools plugin system yet.
TypeScript
119
star
43

react-native-fade-in-image

JavaScript
118
star
44

entity

Entity is a privacy-aware data layer for defining, caching, and authorizing access to application data models.
TypeScript
116
star
45

eslint-config-universe

Moved to https://github.com/expo/expo/tree/master/packages/eslint-config-universe
JavaScript
110
star
46

audio-recording-example

Audio Recording Example
TypeScript
109
star
47

redux-effex

Spin off async functions to perform side effects
JavaScript
108
star
48

auth0-example

This example has moved
JavaScript
108
star
49

expo-2d-context

A pure-js implementation of the W3C's Canvas-2D Context API that can be run on either Expo Graphics or WebGL
HTML
103
star
50

results

An efficient, standards-compliant library for representing results of successful or failed operations
TypeScript
102
star
51

firebase-storage-upload-example

This example has moved
JavaScript
98
star
52

sqlite-example

This example has moved
JavaScript
97
star
53

react-native-scrollable-mixin

A standard interface for your scrollable React Native components, making it easier to compose components.
JavaScript
94
star
54

expo-processing

Utilities for using Processing.js on Expo
JavaScript
93
star
55

videoplayer

Customizable controls for Expo video
JavaScript
83
star
56

snack-sdk

Snack SDK
JavaScript
83
star
57

react-apple-easing

Apple's default Core Animation easing functions for React
JavaScript
83
star
58

turtle-cli-example

Turtle CLI usage example (CircleCI & Travis CI)
Shell
81
star
59

dire-dire-ducks

Flood your room with water and rubber duckies!
JavaScript
77
star
60

status-bar-height

Listen to status bar changes during incoming calls and other multi-tasking events
JavaScript
73
star
61

expo-preview-action

With this preview action, you can test changes made in pull requests via Expo Go or custom development client (created with expo-dev-client) just by scanning QR code.
JavaScript
72
star
62

react-native-image-gallery

JavaScript
71
star
63

pomodoroexp

https://expo.io/@community/pomodoro
JavaScript
70
star
64

expo-three-ar

Utilities for using Expo AR with THREE.js
TypeScript
70
star
65

eas-build

TypeScript
61
star
66

react-native-refreshable-scroll-view

A ScrollView that supports pull-to-refresh. You can customize it with the RefreshIndicator and type of ScrollView (ex: ListView) of your choice.
JavaScript
61
star
67

spawn-async

A Promise-based interface into processes created by child_process.spawn
TypeScript
59
star
68

react-native-for-curious-people

Available through the Exponent iPhone or Android app:
JavaScript
59
star
69

browser-polyfill

Browser polyfill for making React Native compatible with web libs like pixi.js, three.js, phaser.js
JavaScript
52
star
70

xdl

The Expo Development Library
TypeScript
47
star
71

UpdatesAPIDemo

Demo app showing the useUpdates() API
TypeScript
46
star
72

harvard-cs50-app

Harvard's mobile application for CS50.
JavaScript
46
star
73

hello-graphql

JavaScript
44
star
74

expo-graphics

Tools to help simplify working with three, pixi, phaser, ect...
JavaScript
44
star
75

detox-expo-helpers

JavaScript
43
star
76

expo-asset-utils

Utilities for parsing files references, and Expo Assets.
TypeScript
42
star
77

styleguide

Foundational styles for Expo interfaces.
TypeScript
42
star
78

hackathon-examples

40
star
79

with-detox-tests

This template is no longer maintained! See https://github.com/yaron1m/expo-detox-typescript-example instead
JavaScript
39
star
80

react-native-scrollable-decorator

A standard interface for your scrollable React Native components, making it easier to compose components.
JavaScript
38
star
81

react-native-url-handler

Navigate to external URLs, handle in-app URLs, and access system URLs
Objective-C
36
star
82

rnplay

THIS REPOSITORY IS QUITE OLD AND NOT MAINTAINED! React Native Playground has been replaced by https://snack.expo.io. Look at this repository like you might look at tools in a museum, and don't touch it or actually use it
JavaScript
36
star
83

expo-twitter-login-example

This example has moved
JavaScript
34
star
84

react-native-image-picker-android

A camera and gallery image picker native module for Android, giving a subset of the API of https://github.com/marcshilling/react-native-image-picker
Java
34
star
85

react-loading-indicator

A loading indicator written purely in React that uses SVG and no images.
JavaScript
32
star
86

socket-io-example

This example has moved
29
star
87

koa-graphiql

Koa middleware to display GraphiQL, the interactive GraphQL UI
JavaScript
27
star
88

video-background-example

This example has moved
JavaScript
27
star
89

expo-electron-adapter

This package wraps `electron-webpack` and adds support for Expo web and other universal React packages.
TypeScript
27
star
90

eas-tests-example

Demo of running E2E tests on EAS Build
Java
26
star
91

gl-test

Examples and tests for OpenGL rendering in Expo.
JavaScript
26
star
92

three-ar-test

Using Expo's AR functionality with THREE.js
JavaScript
25
star
93

BrightSky

Learn how to use Expo with this simple weather app!
TypeScript
24
star
94

expo-postpublish-slack-notify

JavaScript
24
star
95

breakout

why not?
JavaScript
24
star
96

hyperinstall

Runs "yarn" and "npm install" in several directories with extreme speed when possible
JavaScript
23
star
97

pound-random

Expo Blue - a discussion app for small groups
JavaScript
22
star
98

electron-cookies

Provides document.cookie support for Electron
JavaScript
22
star
99

instapromise

Promisify node style async functions by putting a `.promise` after them (or after the object for methods)
JavaScript
21
star
100

floatyplane

JavaScript
21
star