Crafting Multi-Platform Apps: Your Guide to React Native Web Development

Crafting Multi-Platform Apps: Your Guide to React Native Web Development

At the beginning of a new project, the hardest decisions to be made often concern the development stack. With so many libraries and solutions out there, it can be hard to navigate through the possibilities.
One of the best questions to ask yourself, when it comes to choosing a development stack, is whether this choice is compatible with the future growth and scalability of your app.

It can be an interesting strategic choice to support web platforms from the start, and integrating React Native Web in the early stages is a good practice.

But what if the app's requirements suddenly change mid-way through the project, and the app now needs to be accessed from web browsers? While it can seem like a big, daunting task with countless days of porting the code over to another framework, there is a way with React Native to add support for such significant structural changes at any point in the project lifecycle.

Here comes React Native Web, bringing React Native components and APIs to the web.

Bridging the gap: Mobile and Web app under one umbrella

React Native's main objective is to simplify mobile app development to the point where a unified, single codebase, can be used to compile on different mobile app platforms. For our clients, this means a gain of time and budget. For our developers, this means one single language has to be used and all best practices can be kept and shared throughout projects.

The idea behind RN Web is pretty simple: It leverages this unified framework idea and adds a new compilation target - towards Web browsers - on top of the existing framework.


Why consider React Native Web for your app or business? Some of its benefits include:

  • Cost-Efficiency: Develop once, run everywhere
  • Speed: Faster time to market
  • Consistency: Uniform look and feel across platforms

Features and Capabilities

For RN Web to ensure that the typical React Native components fit seamlessly into the web ecosystem, it had to reimagine them. Components that developers are used to using in React Native, such as <View> and <Text>, don't naturally exist in the web ecosystem. So, RN Web takes these components and, under the hood, translates them to their web counterparts.

Let's take the <View> component, for instance. In React Native, <View> serves as a foundational building block for UI design, offering a container that can house other components and manage layout using a flexbox design. When you're developing for mobile using React Native, you'll utilize a set of styling properties that might seem distinct from conventional web styling.

However, when this same <View> component is translated to the web via RN Web, it morphs into the familiar <div> element.
While React offers multiple styling options like CSS, Sass, and CSS-in-JS, React Native mostly uses a CSS-in-JS approach through the StyleSheet class (Other alternatives might include third-parties like Styled Components).
React Native Web converts the StyleSheet syntax into standard CSS, ensuring consistent appearance of your app across both mobile and web platforms.

For instance, this text element will get translated into correct CSS.

 <Text 
     style={{
      fontSize: 20,
      textAlign: 'center',
      fontWeight: 'bold',
      fontFamily: 'Helvetica'
     }}>
   	React Native for Web
  </Text>
 {
  font-size: 20px;
  text-align: center;
  font-weight: bold;
  font-family: Helvetica;
}

Let's create a small React Native app with an interaction and a simple animation. We will use the Animated API for the animation and some familiar APIs from the React Native core.

Here we will use Expo, a versatile toolchain built around React Native to quickly start RN projects without dealing with too much project configuration.

Let's start first by creating a new Expo project, then installing react-native-web as a package dependency.

npx create-expo-app RNWebApp
cd RNWebApp
npx expo install react-dom react-native-web @expo/webpack-config

Then go on to implement the requirements for our small application.

import React, { useState, useRef } from "react";
import {
  StyleSheet,
  Text,
  View,
  useWindowDimensions,
  TouchableOpacity,
  Animated,
} from "react-native";

export default function App() {
  const { windowHeight } = useWindowDimensions();
  const [isDarkTheme, setIsDarkTheme] = useState(false);

  const backgroundColorAnim = useRef(new Animated.Value(0)).current;

  function toggleTheme() {
    setIsDarkTheme((prevTheme) => !prevTheme);

    Animated.timing(backgroundColorAnim, {
      toValue: isDarkTheme ? 0 : 1,
      duration: 200,
      useNativeDriver: false,
    }).start();
  }

  const backgroundColor = backgroundColorAnim.interpolate({
    inputRange: [0, 1],
    outputRange: ["#fff", "#333"],
  });
  const buttonBackgroundColor = isDarkTheme ? "#049" : "#7BF";
  const fontColor = isDarkTheme ? "#fff" : "#000";

  return (
    <Animated.View
      style={[styles.mainContainer, { backgroundColor, height: windowHeight }]}
    >
      <View style={styles.spacingBlock} />
      <TouchableOpacity
        style={[
          styles.themeToggleButton,
          { backgroundColor: buttonBackgroundColor },
        ]}
        onPress={toggleTheme}
      >
        <Text style={[styles.buttonText, { color: fontColor }]}>
          Toggle Theme
        </Text>
      </TouchableOpacity>
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  mainContainer: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
  },
  spacingBlock: {
    height: 12,
  },
  themeToggleButton: {
    padding: 10,
    borderRadius: 20,
  },
  buttonText: {
    color: "#fff",
  },
});

Your React Native app will work on the browser by rendering DOM elements thanks to React Native for Web:

0:00
/0:04

The same app will also work on mobile devices with native UI elements:

0:00
/0:04

Use the command below to create a deployable web application:
npx expo export:web

This command will generate static resources, which will be located in the ./web-build directory. To test using serve, navigate to the directory and initiate it with the following commands:

cd web-build
npx serve

Challenges and Considerations when using React Native Web

React Native for Web is an open-source initiative separate from the official React Native framework, this means that various challenges may arise depending on the use case.
Expo, a framework that enables the creation of native apps using web technologies, leverages this community-driven project to facilitate web platform capabilities for React Native applications. Despite the project maintainers' efforts to align React Native for Web with the most recent versions of React Native, certain constraints warrant attention prior to its use:

  • Some packages from the React Native community might not work properly on the web, be sure to evaluate all of them independently or check the documentation for a mention of React Native Web.
  • The implementation of all React Native APIs, components, and respective features is not guaranteed on the web platform, leading to possible discrepancies in functionality, such as the unavailability of Alert and RefreshControl.
  • React Native Web employs a DOM-based methodology with conventional CSS. This difference may necessitate additional adjustments for certain native styles when displayed in a browser. Additionally, some specific situations might need further HTML handling by conditionally targeting the web platform using the Platform API from React Native.

For an exhaustive overview of compatibility, refer to the official documentation of React Native for Web.

Conclusion

Throughout this article, we've looked into the conceptual idea behind React Native Web and how it solves a very specific use case. We built a small app with a few lines of code, building subsequently to both the web and mobile platforms. It is clear that using this technology is not only innovative but also incredibly advantageous in numerous ways.

Leveraging React Native Web, we streamline our development process, thanks to a unified codebase. The provision to write code once and deploy it across various platforms – web, iOS, and Android – allows us to reduce redundancy, thereby cutting down development hours substantially. This approach arising from a consolidated codebase, facilitates easier maintenance and quicker implementation of new features or changes.

Moreover, for developers accustomed to React Native patterns, adopting React Native Web is a seamless transition, enhancing their productivity. The underlying principles, workflows, and components are similar, meaning that developers can build web applications without a steep learning curve. This carries the profound benefit of being cost-effective as the need to hire different teams for web and mobile development is significantly diminished.

Do you want to know more about this topic? Then check out this blogpost about OneGreen, one of the projects we used React Native web development for!

Are you working on your own mobile or web app? Contact us at Hybrid Heroes and we would love to work with you and make your vision come true!