Building <InputAccessoryView> For React Native

Peter Argany

Peter Argany

Software Engineer at Facebook

Motivation

Three years ago, a GitHub issue was opened to support input accessory view from React Native.

In the ensuing years, there have been countless '+1s', various workarounds, and zero concrete changes to RN on this issue - until today. Starting with iOS, we're exposing an API for accessing the native input accessory view and we are excited to share how we built it.

Background

What exactly is an input accessory view? Reading Apple's developer documentation, we learn that it's a custom view which can be anchored to the top of the system keyboard whenever a receiver becomes the first responder. Anything that inherits from UIResponder can redeclare the .inputAccessoryView property as read-write, and manage a custom view here. The responder infrastructure mounts the view, and keeps it in sync with the system keyboard. Gestures which dismiss the keyboard, like a drag or tap, are applied to the input accessory view at the framework level. This allows us to build content with interactive keyboard dismissal, an integral feature in top-tier messaging apps like iMessage and WhatsApp.

There are two common use cases for anchoring a view to the top of the keyboard. The first is creating a keyboard toolbar, like the Facebook composer background picker.

In this scenario, the keyboard is focused on a text input field, and the input accessory view is used to provide additional keyboard functionality. This functionality is contextual to the type of input field. In a mapping application it could be address suggestions, or in a text editor, it could be rich text formatting tools.


The Objective-C UIResponder who owns the <InputAccessoryView> in this scenario should be clear. The <TextInput> has become first responder, and under the hood this becomes an instance of UITextView or UITextField.

The second common scenario is sticky text inputs:

Here, the text input is actually part of the input accessory view itself. This is commonly used in messaging applications, where a message can be composed while scrolling through a thread of previous messages.


Who owns the <InputAccessoryView> in this example? Can it be the UITextView or UITextField again? The text input is inside the input accessory view, this sounds like a circular dependency. Solving this issue alone is another blog post in itself. Spoilers: the owner is a generic UIView subclass who we manually tell to becomeFirstResponder.

API Design

We now know what an <InputAccessoryView> is, and how we want to use it. The next step is designing an API that makes sense for both use cases, and works well with existing React Native components like <TextInput>.

For keyboard toolbars, there are a few things we want to consider:

  1. We want to be able to hoist any generic React Native view hierarchy into the <InputAccessoryView>.
  2. We want this generic and detached view hierarchy to accept touches and be able to manipulate application state.
  3. We want to link an <InputAccessoryView> to a particular <TextInput>.
  4. We want to be able to share an <InputAccessoryView> across multiple text inputs, without duplicating any code.

We can achieve #1 using a concept similar to React portals. In this design, we portal React Native views to a UIView hierarchy managed by the responder infrastructure. Since React Native views render as UIViews, this is actually quite straightforward - we can just override:

- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex

and pipe all the subviews to a new UIView hierarchy. For #2, we set up a new RCTTouchHandler for the <InputAccessoryView>. State updates are achieved by using regular event callbacks. For #3 and #4, we use the nativeID field to locate the accessory view UIView hierarchy in native code during the creation of a <TextInput> component. This function uses the .inputAccessoryView property of the underlying native text input. Doing this effectively links <InputAccessoryView> to <TextInput> in their ObjC implementations.

Supporting sticky text inputs (scenario 2) adds a few more constraints. For this design, the input accessory view has a text input as a child, so linking via nativeID is not an option. Instead, we set the .inputAccessoryView of a generic off-screen UIView to our native <InputAccessoryView> hierarchy. By manually telling this generic UIView to become first responder, the hierarchy is mounted by responder infrastructure. This concept is explained thoroughly in the aforementioned blog post.

Pitfalls

Of course not everything was smooth sailing while building this API. Here are a few pitfalls we encountered, along with how we fixed them.

An initial idea for building this API involved listening to NSNotificationCenter for UIKeyboardWill(Show/Hide/ChangeFrame) events. This pattern is used in some open-sourced libraries, and internally in some parts of the Facebook app. Unfortunately, UIKeyboardDidChangeFrame events were not being called in time to update the <InputAccessoryView> frame on swipes. Also, changes in keyboard height are not captured by these events. This creates a class of bugs that manifest like this:

On iPhone X, text and emoji keyboard are different heights. Most applications using keyboard events to manipulate text input frames had to fix the above bug. Our solution was to commit to using the .inputAccessoryView property, which meant that the responder infrastructure handles frame updates like this.


Another tricky bug we encountered was avoiding the home pill on iPhone X. You may be thinking, “Apple developed safeAreaLayoutGuide for this very reason, this is trivial!”. We were just as naive. The first issue is that the native <InputAccessoryView> implementation has no window to anchor to until the moment it is about to appear. That's alright, we can override -(BOOL)becomeFirstResponder and enforce layout constraints there. Adhering to these constraints bumps the accessory view up, but another bug arises:

The input accessory view successfully avoids the home pill, but now content behind the unsafe area is visible. The solution lies in this radar. I wrapped the native <InputAccessoryView> hierarchy in a container which doesn't conform to the safeAreaLayoutGuide constraints. The native container covers the content in the unsafe area, while the <InputAccessoryView> stays within the safe area boundaries.


Example Usage

Here's an example which builds a keyboard toolbar button to reset <TextInput> state.

class TextInputAccessoryViewExample extends React.Component<
{},
*
> {
constructor(props) {
super(props);
this.state = { text: 'Placeholder Text' };
}
render() {
const inputAccessoryViewID = 'inputAccessoryView1';
return (
<View>
<TextInput
style={styles.default}
inputAccessoryViewID={inputAccessoryViewID}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
<InputAccessoryView nativeID={inputAccessoryViewID}>
<View style={{ backgroundColor: 'white' }}>
<Button
onPress={() =>
this.setState({ text: 'Placeholder Text' })
}
title="Reset Text"
/>
</View>
</InputAccessoryView>
</View>
);
}
}

Another example for Sticky Text Inputs can be found in the repository.

When will I be able to use this?

The full commit for this feature implementation is here. <InputAccessoryView> will be available in the upcoming v0.55.0 release.

Happy keyboarding :)

Using AWS with React Native

Richard Threlkeld

Richard Threlkeld

Senior Technical Product Manager at AWS Mobile

AWS is well known in the technology industry as a provider of cloud services. These include compute, storage, and database technologies, as well as fully managed serverless offerings. The AWS Mobile team has been working closely with customers and members of the JavaScript ecosystem to make cloud-connected mobile and web applications more secure, scalable, and easier to develop and deploy. We began with a complete starter kit, but have a few more recent developments.

This blog post talks about some interesting things for React and React Native developers:

  • AWS Amplify, a declarative library for JavaScript applications using cloud services
  • AWS AppSync, a fully managed GraphQL service with offline and real-time features

AWS Amplify

React Native applications are very easy to bootstrap using tools like Create React Native App and Expo. However, connecting them to the cloud can be challenging to navigate when you try to match a use case to infrastructure services. For example, your React Native app might need to upload photos. Should these be protected per user? That probably means you need some sort of registration or sign-in process. Do you want your own user directory or are you using a social media provider? Maybe your app also needs to call an API with custom business logic after users log in.

To help JavaScript developers with these problems, we released a library named AWS Amplify. The design is broken into "categories" of tasks, instead of AWS-specific implementations. For example, if you wanted users to register, log in, and then upload private photos, you would simply pull in Auth and Storage categories to your application:

import { Auth } from 'aws-amplify';
Auth.signIn(username, password)
.then(user => console.log(user))
.catch(err => console.log(err));
Auth.confirmSignIn(user, code)
.then(data => console.log(data))
.catch(err => console.log(err));

In the code above, you can see an example of some of the common tasks that Amplify helps you with, such as using multi-factor authentication (MFA) codes with either email or SMS. The supported categories today are:

  • Auth: Provides credential automation. Out-of-the-box implementation uses AWS credentials for signing, and OIDC JWT tokens from Amazon Cognito. Common functionality, such as MFA features, is supported.
  • Analytics: With a single line of code, get tracking for authenticated or unauthenticated users in Amazon Pinpoint. Extend this for custom metrics or attributes, as you prefer.
  • API: Provides interaction with RESTful APIs in a secure manner, leveraging AWS Signature Version 4. The API module is great on serverless infrastructures with Amazon API Gateway.
  • Storage: Simplified commands to upload, download, and list content in Amazon S3. You can also easily group data into public or private content on a per-user basis.
  • Caching: An LRU cache interface across web apps and React Native that uses implementation-specific persistence.
  • i18n and Logging: Provides internationalization and localization capabilities, as well as debugging and logging capabilities.

One of the nice things about Amplify is that it encodes "best practices" in the design for your specific programming environment. For example, one thing we found working with customers and React Native developers is that shortcuts taken during development to get things working quickly would make it through to production stacks. These can compromise either scalability or security, and force infrastructure rearchitecture and code refactoring.

One example of how we help developers avoid this is the Serverless Reference Architectures with AWS Lambda. These show you best practices around using Amazon API Gateway and AWS Lambda together when building your backend. This pattern is encoded into the API category of Amplify. You can use this pattern to interact with several different REST endpoints, and pass headers all the way through to your Lambda function for custom business logic. We’ve also released an AWS Mobile CLI for bootstrapping new or existing React Native projects with these features. To get started, just install via npm, and follow the configuration prompts:

npm install --global awsmobile-cli
awsmobile configure

Another example of encoded best practices that is specific to the mobile ecosystem is password security. The default Auth category implementation leverages Amazon Cognito user pools for user registration and sign-in. This service implements Secure Remote Password protocol as a way of protecting users during authentication attempts. If you're inclined to read through the mathematics of the protocol, you'll notice that you must use a large prime number when calculating the password verifier over a primitive root to generate a Group. In React Native environments, JIT is disabled. This makes BigInteger calculations for security operations such as this less performant. To account for this, we've released native bridges in Android and iOS that you can link inside your project:

npm install --save aws-amplify-react-native
react-native link amazon-cognito-identity-js

We're also excited to see that the Expo team has included this in their latest SDK so that you can use Amplify without ejecting.

Finally, specific to React Native (and React) development, Amplify contains higher order components (HOCs) for easily wrapping functionality, such as for sign-up and sign-in to your app:

import Amplify, { withAuthenticator } from 'aws-amplify-react-native';
import aws_exports from './aws-exports';
Amplify.configure(aws_exports);
class App extends React.Component {
...
}
export default withAuthenticator(App);

The underlying component is also provided as <Authenticator />, which gives you full control to customize the UI. It also gives you some properties around managing the state of the user, such as if they've signed in or are waiting for MFA confirmation, and callbacks that you can fire when state changes.

Similarly, you'll find general React components that you can use for different use cases. You can customize these to your needs, for example, to show all private images from Amazon S3 in the Storage module:

<S3Album
level="private"
path={path}
filter={(item) => /jpg/i.test(item.path)}/>

You can control many of the component features via props, as shown earlier, with public or private storage options. There are even capabilities to automatically gather analytics when users interact with certain UI components:

return <S3Album track/>

AWS Amplify favors a convention over configuration style of development, with a global initialization routine or initialization at the category level. The quickest way to get started is with an aws-exports file. However, developers can also use the library independently with existing resources.

For a deep dive into the philosophy and to see a full demo, check out the video from AWS re:Invent.

AWS AppSync

Shortly after the launch of AWS Amplify, we also released AWS AppSync. This is a fully managed GraphQL service that has both offline and real-time capabilities. Although you can use GraphQL in different client programming languages (including native Android and iOS), it's quite popular among React Native developers. This is because the data model fits nicely into a unidirectional data flow and component hierarchy.

AWS AppSync enables you to connect to resources in your own AWS account, meaning you own and control your data. This is done by using data sources, and the service supports Amazon DynamoDB, Amazon Elasticsearch, and AWS Lambda. This enables you to combine functionality (such as NoSQL and full-text search) in a single GraphQL API as a schema. This enables you to mix and match data sources. The AppSync service can also provision from a schema, so if you aren't familiar with AWS services, you can write GraphQL SDL, click a button, and you're automatically up and running.

The real-time functionality in AWS AppSync is controlled via GraphQL subscriptions with a well-known, event-based pattern. Because subscriptions in AWS AppSync are controlled on the schema with a GraphQL directive, and a schema can use any data source, this means you can trigger notifications from database operations with Amazon DynamoDB and Amazon Elasticsearch Service, or from other parts of your infrastructure with AWS Lambda.

In a way similar to AWS Amplify, you can use enterprise security features on your GraphQL API with AWS AppSync. The service lets you get started quickly with API keys. However, as you roll to production it can transition to using AWS Identity and Access Management (IAM) or OIDC tokens from Amazon Cognito user pools. You can control access at the resolver level with policies on types. You can even use logical checks for fine-grained access control checks at run time, such as detecting if a user is the owner of a specific database resource. There are also capabilities around checking group membership for executing resolvers or individual database record access.

To help React Native developers learn more about these technologies, there is a built-in GraphQL sample schema that you can launch on the AWS AppSync console homepage. This sample deploys a GraphQL schema, provisions database tables, and connects queries, mutations, and subscriptions automatically for you. There is also a functioning React Native example for AWS AppSync which leverages this built in schema (as well as a React example), which enable you to get both your client and cloud components running in minutes.

Getting started is simple when you use the AWSAppSyncClient, which plugs in to the Apollo Client. The AWSAppSyncClient handles security and signing for your GraphQL API, offline functionality, and the subscription handshake and negotiation process:

import AWSAppSyncClient from "aws-appsync";
import { Rehydrated } from 'aws-appsync-react';
import { AUTH_TYPE } from "aws-appsync/lib/link/auth-link";
const client = new AWSAppSyncClient({
url: awsconfig.graphqlEndpoint,
region: awsconfig.region,
auth: {type: AUTH_TYPE.API_KEY, apiKey: awsconfig.apiKey}
});

The AppSync console provides a configuration file for download, which contains your GraphQL endpoint, AWS Region, and API key. You can then use the client with React Apollo:

const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
);

At this point, you can use standard GraphQL queries:

query ListEvents {
listEvents{
items{
__typename
id
name
where
when
description
comments{
__typename
items{
__typename
eventId
commentId
content
createdAt
}
nextToken
}
}
}
}

The example above shows a query with the sample app schema provisioned by AppSync. It not only showcases interaction with DynamoDB, but also includes pagination of data (including encrypted tokens) and type relations between Events and Comments. Because the app is configured with the AWSAppSyncClient, data is automatically persisted offline and will synchronize when devices reconnect.

You can see a deep dive of the client technology behind this and a React Native demo in this video.

Feedback

The team behind the libraries is eager to hear how these libraries and services work for you. They also want to hear what else we can do to make React and React Native development with cloud services easier for you. Reach out to the AWS Mobile team on GitHub for AWS Amplify or AWS AppSync.

Implementing Twitter’s App Loading Animation in React Native

Eli White

Eli White

Software Engineer at Facebook

Twitter’s iOS app has a loading animation I quite enjoy.

Once the app is ready, the Twitter logo delightfully expands, revealing the app.

I wanted to figure out how to recreate this loading animation with React Native.


To understand how to build it, I first had to understand the difference pieces of the loading animation. The easiest way to see the subtlety is to slow it down.

There are a few major pieces in this that we will need to figure out how to build.

  1. Scaling the bird.
  2. As the bird grows, showing the app underneath
  3. Scaling the app down slightly at the end

It took me quite a while to figure out how to make this animation.

I started with an incorrect assumption that the blue background and Twitter bird were a layer on top of the app and that as the bird grew, it became transparent which revealed the app underneath. This approach doesn’t work because the Twitter bird becoming transparent would show the blue layer, not the app underneath!

Luckily for you, dear reader, you don’t have to go through the same frustration I did. You get this nice tutorial skipping to the good stuff!


The right way

Before we get to code, it is important to understand how to break this down. To help visualize this effect, I recreated it in CodePen (embedded in a few paragraphs) so you can interactively see the different layers.

There are three main layers to this effect. The first is the blue background layer. Even though this seems to appear on top of the app, it is actually in the back.

We then have a plain white layer. And then lastly, in the very front, is our app.


The main trick to this animation is using the Twitter logo as a mask and masking both the app, and the white layer. I won’t go too deep on the details of masking, there are plenty of resources online for that.

The basics of masking in this context are having images where opaque pixels of the mask show the content they are masking whereas transparent pixels of the mask hide the content they are masking.

We use the Twitter logo as a mask, and having it mask two layers; the solid white layer, and the app layer.

To reveal the app, we scale the mask up until it is larger than the entire screen.

While the mask is scaling up, we fade in the opacity of the app layer, showing the app and hiding the solid white layer behind it. To finish the effect, we start the app layer at a scale > 1, and scale it down to 1 as the animation is ending. We then hide the non-app layers as they will never be seen again.

They say a picture is worth 1,000 words. How many words is an interactive visualization worth? Click through the animation with the “Next Step” button. Showing the layers gives you a side view perspective. The grid is there to help visualize the transparent layers.

Now, for the React Native

Alrighty. Now that we know what we are building and how the animation works, we can get down to the code — the reason you are really here.

The main piece of this puzzle is MaskedViewIOS, a core React Native component.

import { MaskedViewIOS } from 'react-native';
<MaskedViewIOS maskElement={<Text>Basic Mask</Text>}>
<View style={{ backgroundColor: 'blue' }} />
</MaskedViewIOS>;

MaskedViewIOS takes props maskElement and children. The children are masked by the maskElement. Note that the mask doesn’t need to be an image, it can be any arbitrary view. The behavior of the above example would be to render the blue view, but for it to be visible only where the words “Basic Mask” are from the maskElement. We just made complicated blue text.

What we want to do is render our blue layer, and then on top render our masked app and white layers with the Twitter logo.

{
fullScreenBlueLayer;
}
<MaskedViewIOS
style={{ flex: 1 }}
maskElement={
<View style={styles.centeredFullScreen}>
<Image source={twitterLogo} />
</View>
}>
{fullScreenWhiteLayer}
<View style={{ flex: 1 }}>
<MyApp />
</View>
</MaskedViewIOS>;

This will give us the layers we see below.

Now for the Animated part

We have all the pieces we need to make this work, the next step is animating them. To make this animation feel good, we will be utilizing React Native’s Animated API.

Animated lets us define our animations declaratively in JavaScript. By default, these animations run in JavaScript and tell the native layer what changes to make on every frame. Even though JavaScript will try to update the animation every frame, it will likely not be able to do that fast enough and will cause dropped frames (jank) to occur. Not what we want!

Animated has special behavior to allow you to get animations without this jank. Animated has a flag called useNativeDriver which sends your animation definition from JavaScript to native at the beginning of your animation, allowing the native side to process the updates to your animation without having to go back and forth to JavaScript every frame. The downside of useNativeDriver is you can only update a specific set of properties, mostly transform and opacity. You can’t animate things like background color with useNativeDriver, at least not yet — we will add more over time, and of course you can always submit a PR for properties you need for your project, benefitting the whole community 😀.

Since we want this animation to be smooth, we will work within these constraints. For a more in depth look at how useNativeDriver works under the hood, check out our blog post announcing it.

Breaking down our animation

There are 4 components to our animation:

  1. Enlarge the bird, revealing the app and the solid white layer
  2. Fade in the app
  3. Scale down the app
  4. Hide the white layer and blue layer when it is done

With Animated, there are two main ways to define your animation. The first is by using Animated.timing which lets you say exactly how long your animation will run for, along with an easing curve to smooth out the motion. The other approach is by using the physics based apis such as Animated.spring. With Animated.spring, you specify parameters like the amount of friction and tension in the spring, and let physics run your animation.

We have multiple animations we want to be running at the same time which are all closely related to each other. For example, we want the app to start fading in while the mask is mid-reveal. Because these animations are closely related, we will use Animated.timing with a single Animated.Value.

Animated.Value is a wrapper around a native value that Animated uses to know the state of an animation. You typically want to only have one of these for a complete animation. Most components that use Animated will store the value in state.

Since I’m thinking about this animation as steps occurring at different points in time along the complete animation, we will start our Animated.Value at 0, representing 0% complete, and end our value at 100, representing 100% complete.

Our initial component state will be the following.

state = {
loadingProgress: new Animated.Value(0)
};

When we are ready to begin the animation, we tell Animated to animate this value to 100.

Animated.timing(this.state.loadingProgress, {
toValue: 100,
duration: 1000,
useNativeDriver: true // This is important!
}).start();

I then try to figure out a rough estimate of the different pieces of the animations and the values I want them to have at different stages of the overall animation. Below is a table of the different pieces of the animation, and what I think their values should be at different points as we progress through time.

The Twitter bird mask should start at scale 1, and it gets smaller before it shoots up in size. So at 10% through the animation, it should have a scale value of .8 before shooting up to scale 70 at the end. Picking 70 was pretty arbitrary to be honest, it needed to be large enough that the bird fully revealed the screen and 60 wasn’t big enough 😀. Something interesting about this part though is that the higher the number, the faster it will look like it is growing because it has to get there in the same amount of time. This number took some trial and error to make look good with this logo. Logos / devices of different sizes will require this end-scale to be different to ensure the entire screen is revealed.

The app should stay opaque for a while, at least through the Twitter logo getting smaller. Based on the official animation, I want to start showing it when the bird is mid way through scaling it up and to fully reveal it pretty quickly. So at 15% we start showing it, and at 30% through the overall animation it is fully visible.

The app scale starts at 1.1 and scales down to its regular scale by the end of the animation.

And now, in code.

What we essentially did above is map the values from the animation progress percentage to the values for the individual pieces. We do that with Animated using .interpolate. We create 3 different style objects, one for each piece of the animation, using interpolated values based off of this.state.loadingProgress.

const loadingProgress = this.state.loadingProgress;
const opacityClearToVisible = {
opacity: loadingProgress.interpolate({
inputRange: [0, 15, 30],
outputRange: [0, 0, 1],
extrapolate: 'clamp'
// clamp means when the input is 30-100, output should stay at 1
})
};
const imageScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 10, 100],
outputRange: [1, 0.8, 70]
})
}
]
};
const appScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 100],
outputRange: [1.1, 1]
})
}
]
};

Now that we have these style objects, we can use them when rendering the snippet of the view from earlier in the post. Note that only Animated.View, Animated.Text, and Animated.Image are able to use style objects that use Animated.Value.

const fullScreenBlueLayer = (
<View style={styles.fullScreenBlueLayer} />
);
const fullScreenWhiteLayer = (
<View style={styles.fullScreenWhiteLayer} />
);
return (
<View style={styles.fullScreen}>
{fullScreenBlueLayer}
<MaskedViewIOS
style={{ flex: 1 }}
maskElement={
<View style={styles.centeredFullScreen}>
<Animated.Image
style={[styles.maskImageStyle, imageScale]}
source={twitterLogo}
/>
</View>
}>
{fullScreenWhiteLayer}
<Animated.View
style={[opacityClearToVisible, appScale, { flex: 1 }]}>
{this.props.children}
</Animated.View>
</MaskedViewIOS>
</View>
);

Yay! We now have the animation pieces looking like we want. Now we just have to clean up our blue and white layers which will never be seen again.

To know when we can clean them up, we need to know when the animation is complete. Luckily where we call, Animated.timing ,.start takes an optional callback that runs when the animation is complete.

Animated.timing(this.state.loadingProgress, {
toValue: 100,
duration: 1000,
useNativeDriver: true
}).start(() => {
this.setState({
animationDone: true
});
});

Now that we have a value in state to know whether we are done with the animation, we can modify our blue and white layers to use that.

const fullScreenBlueLayer = this.state.animationDone ? null : (
<View style={[styles.fullScreenBlueLayer]} />
);
const fullScreenWhiteLayer = this.state.animationDone ? null : (
<View style={[styles.fullScreenWhiteLayer]} />
);

Voila! Our animation now works and we clean up our unused layers once the animation is done. We have built the Twitter app loading animation!

But wait, mine doesn’t work!

Don’t fret, dear reader. I too hate when guides only give you chunks of the code and don’t give you the completed source.

This component has been published to npm and is on GitHub as react-native-mask-loader. To try this out on your phone, it is available on Expo here:

More Reading / Extra Credit

  1. This gitbook is a great resource to learn more about Animated after you have read the React Native docs.
  2. The actual Twitter animation seems to speed up the mask reveal towards the end. Try modifying the loader to use a different easing function (or a spring!) to better match that behavior.
  3. The current end-scale of the mask is hard coded and likely won’t reveal the entire app on a tablet. Calculating the end scale based on screen size and image size would be an awesome PR.

React Native Monthly

Tomislav Tenodi

Tomislav Tenodi

Product Manager at Shoutem

At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.

Monthly meetings

We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: improve the React Native community. Presenting teams' efforts eases collaboration between teams done offline.

Teams

On the first meeting, we had 8 teams join us:

We hope to have more core contributors join the upcoming sessions!

Notes

As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:

Airbnb

  • Plans to add some A11y (accessibility) APIs to View and the AccessibilityInfo native module.
  • Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.
  • Have been investigating potential initialization performance improvements.
  • Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".

Callstack

  • Looking into improving the release process by using Detox for E2E testing. Pull request should land soon.
  • Blob pull request they have been working on has been merged, subsequent pull requests coming up.
  • Increasing Haul adoption across internal projects to see how it performs compared to Metro Bundler. Working on better multi-threaded performance with the Webpack team.
  • Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.
  • The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!
  • Stepped back from react-navigation for a while to investigate alternatives (especially native navigations).

Expo

Facebook

  • React Native's packager is now Metro Bundler, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.
  • In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.
  • The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.

GeekyAnts

  • The team is working on a UI/UX design app (codename: Builder) which directly works with .js files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.
  • The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.
  • Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.
  • Also, NativeBase recently reached 5,000 GitHub stars.

Microsoft

  • CodePush has now been integrated into Mobile Center. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement here.
  • VSCode has a bug with debugging, they are working on fixing that right now and will have a new build.
  • Investigating Detox for Integration testing, looking at JSC Context to get variables alongside crash reports.

Shoutem

  • Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on Shoutem.
  • Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.
  • Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.

Wix

  • Working internally to adopt Detox to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.
  • Working to add support to the Metro Bundler for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called react-native-repackager, now working on a PR.
  • Investigating automation of performance tests. This is a new repo called DetoxInstruments. You can take a look, it's being developed open source.
  • Working with a contributor from KPN on Detox for Android and supporting real devices.
  • Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is Storybook for React Native or Ram's idea for integration testing.

Next session

Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me on Twitter if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.

React Native Monthly

Tomislav Tenodi

Tomislav Tenodi

Product Manager at Shoutem

At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.

Monthly meetings

We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: improve the React Native community. Presenting teams' efforts eases collaboration between teams done offline.

Teams

On the first meeting, we had 8 teams join us:

We hope to have more core contributors join the upcoming sessions!

Notes

As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:

Airbnb

  • Plans to add some A11y (accessibility) APIs to View and the AccessibilityInfo native module.
  • Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.
  • Have been investigating potential initialization performance improvements.
  • Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".

Callstack

  • Looking into improving the release process by using Detox for E2E testing. Pull request should land soon.
  • Blob pull request they have been working on has been merged, subsequent pull requests coming up.
  • Increasing Haul adoption across internal projects to see how it performs compared to Metro Bundler. Working on better multi-threaded performance with the Webpack team.
  • Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.
  • The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!
  • Stepped back from react-navigation for a while to investigate alternatives (especially native navigations).

Expo

Facebook

  • React Native's packager is now Metro Bundler, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.
  • In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.
  • The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.

GeekyAnts

  • The team is working on a UI/UX design app (codename: Builder) which directly works with .js files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.
  • The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.
  • Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.
  • Also, NativeBase recently reached 5,000 GitHub stars.

Microsoft

  • CodePush has now been integrated into Mobile Center. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement here.
  • VSCode has a bug with debugging, they are working on fixing that right now and will have a new build.
  • Investigating Detox for Integration testing, looking at JSC Context to get variables alongside crash reports.

Shoutem

  • Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on Shoutem.
  • Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.
  • Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.

Wix

  • Working internally to adopt Detox to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.
  • Working to add support to the Metro Bundler for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called react-native-repackager, now working on a PR.
  • Investigating automation of performance tests. This is a new repo called DetoxInstruments. You can take a look, it's being developed open source.
  • Working with a contributor from KPN on Detox for Android and supporting real devices.
  • Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is Storybook for React Native or Ram's idea for integration testing.

Next session

Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me on Twitter if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.

React Native Monthly

Tomislav Tenodi

Tomislav Tenodi

Product Manager at Shoutem

At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.

Monthly meetings

We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: improve the React Native community. Presenting teams' efforts eases collaboration between teams done offline.

Teams

On the first meeting, we had 8 teams join us:

We hope to have more core contributors join the upcoming sessions!

Notes

As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:

Airbnb

  • Plans to add some A11y (accessibility) APIs to View and the AccessibilityInfo native module.
  • Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.
  • Have been investigating potential initialization performance improvements.
  • Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".

Callstack

  • Looking into improving the release process by using Detox for E2E testing. Pull request should land soon.
  • Blob pull request they have been working on has been merged, subsequent pull requests coming up.
  • Increasing Haul adoption across internal projects to see how it performs compared to Metro Bundler. Working on better multi-threaded performance with the Webpack team.
  • Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.
  • The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!
  • Stepped back from react-navigation for a while to investigate alternatives (especially native navigations).

Expo

Facebook

  • React Native's packager is now Metro Bundler, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.
  • In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.
  • The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.

GeekyAnts

  • The team is working on a UI/UX design app (codename: Builder) which directly works with .js files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.
  • The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.
  • Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.
  • Also, NativeBase recently reached 5,000 GitHub stars.

Microsoft

  • CodePush has now been integrated into Mobile Center. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement here.
  • VSCode has a bug with debugging, they are working on fixing that right now and will have a new build.
  • Investigating Detox for Integration testing, looking at JSC Context to get variables alongside crash reports.

Shoutem

  • Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on Shoutem.
  • Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.
  • Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.

Wix

  • Working internally to adopt Detox to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.
  • Working to add support to the Metro Bundler for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called react-native-repackager, now working on a PR.
  • Investigating automation of performance tests. This is a new repo called DetoxInstruments. You can take a look, it's being developed open source.
  • Working with a contributor from KPN on Detox for Android and supporting real devices.
  • Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is Storybook for React Native or Ram's idea for integration testing.

Next session

Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me on Twitter if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.

React Native Monthly

Tomislav Tenodi

Tomislav Tenodi

Product Manager at Shoutem

At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.

Monthly meetings

We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: improve the React Native community. Presenting teams' efforts eases collaboration between teams done offline.

Teams

On the first meeting, we had 8 teams join us:

We hope to have more core contributors join the upcoming sessions!

Notes

As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:

Airbnb

  • Plans to add some A11y (accessibility) APIs to View and the AccessibilityInfo native module.
  • Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.
  • Have been investigating potential initialization performance improvements.
  • Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".

Callstack

  • Looking into improving the release process by using Detox for E2E testing. Pull request should land soon.
  • Blob pull request they have been working on has been merged, subsequent pull requests coming up.
  • Increasing Haul adoption across internal projects to see how it performs compared to Metro Bundler. Working on better multi-threaded performance with the Webpack team.
  • Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.
  • The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!
  • Stepped back from react-navigation for a while to investigate alternatives (especially native navigations).

Expo

Facebook

  • React Native's packager is now Metro Bundler, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.
  • In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.
  • The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.

GeekyAnts

  • The team is working on a UI/UX design app (codename: Builder) which directly works with .js files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.
  • The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.
  • Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.
  • Also, NativeBase recently reached 5,000 GitHub stars.

Microsoft

  • CodePush has now been integrated into Mobile Center. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement here.
  • VSCode has a bug with debugging, they are working on fixing that right now and will have a new build.
  • Investigating Detox for Integration testing, looking at JSC Context to get variables alongside crash reports.

Shoutem

  • Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on Shoutem.
  • Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.
  • Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.

Wix

  • Working internally to adopt Detox to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.
  • Working to add support to the Metro Bundler for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called react-native-repackager, now working on a PR.
  • Investigating automation of performance tests. This is a new repo called DetoxInstruments. You can take a look, it's being developed open source.
  • Working with a contributor from KPN on Detox for Android and supporting real devices.
  • Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is Storybook for React Native or Ram's idea for integration testing.

Next session

Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me on Twitter if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.

React Native Performance in Marketplace

Aaron Chiu

Software Engineer at Facebook

React Native is used in multiple places across multiple apps in the Facebook family including a top level tab in the main Facebook apps. Our focus for this post is a highly visible product, Marketplace. It is available in a dozen or so countries and enables users to discover products and services provided by other users.

In the first half of 2017, through the joint effort of the Relay Team, the Marketplace team, the Mobile JS Platform team, and the React Native team, we cut Marketplace Time to Interaction (TTI) in half for Android Year Class 2010-11 devices. Facebook has historically considered these devices as low-end Android devices, and they have the slowest TTIs on any platform or device type.

A typical React Native startup looks something like this:

Disclaimer: ratios aren't representative and will vary depending on how React Native is configured and used.

We first initialize the React Native core (aka the “Bridge”) before running the product specific JavaScript which determines what native views React Native will render in the Native Processing Time.

A different approach

One of the earlier mistakes that we made was to let Systrace and CTScan drive our performance efforts. These tools helped us find a lot of low-hanging fruit in 2016, but we discovered that both Systrace and CTScan are not representative of production scenarios and cannot emulate what happens in the wild. Ratios of time spent in the breakdowns are often incorrect and, wildly off-base at times. At the extreme, some things that we expected to take a few milliseconds actually take hundreds or thousands of milliseconds. That said, CTScan is useful and we've found it catches a third of regressions before they hit production.

On Android, we attribute the shortcomings of these tools to the fact that 1) React Native is a multithreaded framework, 2) Marketplace is co-located with a multitude of complex views such as Newsfeed and other top-level tabs, and 3) computation times vary wildly. Thus, this half, we let production measurements and breakdowns drive almost all of our decision making and prioritization.

Down the path of production instrumentation

Instrumenting production may sound simple on the surface, but it turned out to be quite a complex process. It took multiple iteration cycles of 2-3 weeks each; due to the latency of landing a commit in master, to pushing the app to the Play Store, to gathering sufficient production samples to have confidence in our work. Each iteration cycle involved discovering if our breakdowns were accurate, if they had the right level of granularity, and if they properly added up to the whole time span. We could not rely on alpha and beta releases because they are not representative of the general population. In essence, we very tediously built a very accurate production trace based on the aggregate of millions of samples.

One of the reasons we meticulously verified that every millisecond in breakdowns properly added up to their parent metrics was that we realized early on there were gaps in our instrumentation. It turned out that our initial breakdowns did not account for stalls caused by thread jumps. Thread jumps themselves aren't expensive, but thread jumps to busy threads already doing work are very expensive. We eventually reproduced these blockages locally by sprinkling Thread.sleep() calls at the right moments, and we managed to fix them by:

  1. removing our dependency on AsyncTask,
  2. undoing the forced initialization of ReactContext and NativeModules on the UI thread, and
  3. removing the dependency on measuring the ReactRootView at initialization time.

Together, removing these thread blockage issues reduced the startup time by over 25%.

Production metrics also challenged some of our prior assumptions. For example, we used to pre-load many JavaScript modules on the startup path under the assumption that co-locating modules in one bundle would reduce their initialization cost. However, the cost of pre-loading and co-locating these modules far outweighed the benefits. By re-configuring our inline require blacklists and removing JavaScript modules from the startup path, we were able to avoid loading unnecessary modules such as Relay Classic (when only Relay Modern was necessary). Today, our RUN_JS_BUNDLE breakdown is over 75% faster.

We also found wins by investigating product-specific native modules. For example, by lazily injecting a native module's dependencies, we reduced that native module's cost by 98%. By removing the contention of Marketplace startup with other products, we reduced startup by an equivalent interval.

The best part is that many of these improvements are broadly applicable to all screens built with React Native.

Conclusion

People assume that React Native startup performance problems are caused by JavaScript being slow or exceedingly high network times. While speeding up things like JavaScript would bring down TTI by a non-trivial sum, each of these contribute a much smaller percentage of TTI than was previously believed.

The lesson so far has been to measure, measure, measure! Some wins come from moving run-time costs to build time, such as Relay Modern and Lazy NativeModules. Other wins come from avoiding work by being smarter about parallelizing code or removing dead code. And some wins come from large architectural changes to React Native, such as cleaning up thread blockages. There is no grand solution to performance, and longer-term performance wins will come from incremental instrumentation and improvements. Do not let cognitive bias influence your decisions. Instead, carefully gather and interpret production data to guide future work.

Future plans

In the long term, we want Marketplace TTI to be comparable to similar products built with Native, and, in general, have React Native performance on par with native performance. Further more, although this half we drastically reduced the bridge startup cost by about 80%, we plan to bring the cost of the React Native bridge close to zero via projects like Prepack and more build time processing.

React Native Monthly

Tomislav Tenodi

Tomislav Tenodi

Product Manager at Shoutem

At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.

Monthly meetings

We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: improve the React Native community. Presenting teams' efforts eases collaboration between teams done offline.

Teams

On the first meeting, we had 8 teams join us:

We hope to have more core contributors join the upcoming sessions!

Notes

As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:

Airbnb

  • Plans to add some A11y (accessibility) APIs to View and the AccessibilityInfo native module.
  • Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.
  • Have been investigating potential initialization performance improvements.
  • Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".

Callstack

  • Looking into improving the release process by using Detox for E2E testing. Pull request should land soon.
  • Blob pull request they have been working on has been merged, subsequent pull requests coming up.
  • Increasing Haul adoption across internal projects to see how it performs compared to Metro Bundler. Working on better multi-threaded performance with the Webpack team.
  • Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.
  • The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!
  • Stepped back from react-navigation for a while to investigate alternatives (especially native navigations).

Expo

Facebook

  • React Native's packager is now Metro Bundler, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.
  • In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.
  • The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.

GeekyAnts

  • The team is working on a UI/UX design app (codename: Builder) which directly works with .js files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.
  • The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.
  • Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.
  • Also, NativeBase recently reached 5,000 GitHub stars.

Microsoft

  • CodePush has now been integrated into Mobile Center. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement here.
  • VSCode has a bug with debugging, they are working on fixing that right now and will have a new build.
  • Investigating Detox for Integration testing, looking at JSC Context to get variables alongside crash reports.

Shoutem

  • Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on Shoutem.
  • Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.
  • Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.

Wix

  • Working internally to adopt Detox to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.
  • Working to add support to the Metro Bundler for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called react-native-repackager, now working on a PR.
  • Investigating automation of performance tests. This is a new repo called DetoxInstruments. You can take a look, it's being developed open source.
  • Working with a contributor from KPN on Detox for Android and supporting real devices.
  • Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is Storybook for React Native or Ram's idea for integration testing.

Next session

Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me on Twitter if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.

React Native Monthly

Tomislav Tenodi

Tomislav Tenodi

Product Manager at Shoutem

At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.

Monthly meetings

We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: improve the React Native community. Presenting teams' efforts eases collaboration between teams done offline.

Teams

On the first meeting, we had 8 teams join us:

We hope to have more core contributors join the upcoming sessions!

Notes

As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:

Airbnb

  • Plans to add some A11y (accessibility) APIs to View and the AccessibilityInfo native module.
  • Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.
  • Have been investigating potential initialization performance improvements.
  • Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".

Callstack

  • Looking into improving the release process by using Detox for E2E testing. Pull request should land soon.
  • Blob pull request they have been working on has been merged, subsequent pull requests coming up.
  • Increasing Haul adoption across internal projects to see how it performs compared to Metro Bundler. Working on better multi-threaded performance with the Webpack team.
  • Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.
  • The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!
  • Stepped back from react-navigation for a while to investigate alternatives (especially native navigations).

Expo

Facebook

  • React Native's packager is now Metro Bundler, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.
  • In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.
  • The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.

GeekyAnts

  • The team is working on a UI/UX design app (codename: Builder) which directly works with .js files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.
  • The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.
  • Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.
  • Also, NativeBase recently reached 5,000 GitHub stars.

Microsoft

  • CodePush has now been integrated into Mobile Center. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement here.
  • VSCode has a bug with debugging, they are working on fixing that right now and will have a new build.
  • Investigating Detox for Integration testing, looking at JSC Context to get variables alongside crash reports.

Shoutem

  • Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on Shoutem.
  • Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.
  • Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.

Wix

  • Working internally to adopt Detox to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.
  • Working to add support to the Metro Bundler for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called react-native-repackager, now working on a PR.
  • Investigating automation of performance tests. This is a new repo called DetoxInstruments. You can take a look, it's being developed open source.
  • Working with a contributor from KPN on Detox for Android and supporting real devices.
  • Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is Storybook for React Native or Ram's idea for integration testing.

Next session

Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me on Twitter if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.