Skip to content

react-native-web support聽#812

Open
Open

Description

Proposal

Hi 馃憢

I'm currently targetting the web for some react-native libraries (ex: react-native-localize).
It could be nice to add support for react-native-web, as it's well used.

Alternatives

Using react-native-test-app + keeping a package.json with a bundler (vite? webpack?)

Implementation Details

  • Add vite to the project
// vite.config.js

/** @type {import("vite").UserConfig} */
const config = {
  resolve: {
    alias: {
      "react-native": "react-native-web",
    },
    extensions: [
      "web.mjs",
      "mjs",
      "web.js",
      "js",
      "web.ts",
      "ts",
      "web.jsx",
      "jsx",
      "web.tsx",
      "tsx",
      "json",
    ],
  },
};

export default config;
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>react-native-test-app</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="../../example/index.web.js"></script>
  </body>
</html>

Additional Context

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Activity

  1. tido64 commented on Mar 17, 2022

    @tido64
    Member

    I've had a few people ask me about this in the past and my answer has always been "sure, why not". But reality is that I am not familiar with react-native-web, and we don't have any teams using this internally (that I am aware of). That doesn't mean that I can't add support for it, my concern is whether it'll be a good experience for everyone.

    If this is something that you have strong opinions about, would you be up for contributing web support?

  2. wcandillon commented on Oct 2, 2024

    @wcandillon

    We would be very interested to have Web support for RN WebGPU and Skia

  3. mikehardy commented on Nov 1, 2024

    @mikehardy

    It is possible to do this on the side with vite or similar support as Mathieu mentions but it seems just adding support directly for react-native-web should be "The Way", as this is "react-native-test-app", not "react-test-app" - we want to test all the react-native platforms, not test react on all the bundlers and such.

    react-native-web uses webpack which gets mediocre sentiment scores in state of JS survey but is obviously widely adopted and known, and (most importantly) webpack is just built in to react-native-web as it's default choice, so we can delegate the "adults disagree" arguments to react-native-web and say "they chose it, we use what they chose"

    So, just confirming the "sure, why not" stance, though not committing to doing a PR or any timeline, web support just using react-native-web and all of it's current tech stack choices: would that be of interest + on track for merge?

  4. tido64 commented on Nov 4, 2024

    @tido64
    Member

    So, just confirming the "sure, why not" stance, though not committing to doing a PR or any timeline, web support just using react-native-web and all of it's current tech stack choices: would that be of interest + on track for merge?

    If this is really what one would expect if you were to set up a project with react-native-web yourself, then yes. We want to avoid being "odd" as much as possible in terms of what users expect i.e. the tooling, the commands to execute, etc. are all the same.

    The only thing I want to add is would you be willing to own this part? As I've mentioned above, we do not use this internally. If something breaks, it is unlikely that we will ever notice it.

  5. mikehardy commented on Nov 4, 2024

    @mikehardy

    Agreed 100% on not being "odd", and that is the basis of my thinking, "let's just do it exactly like react-native-web does it". In fact, if any of the details I posted in my "would this work?" comment above are opposite for how react-native-web already directs you to do it in their docs, I'll switch immediately to just doing what they do. KISS principle, basically, no desire to trailblaze here

    I did do some research before posting my comment, and I'll mention one other conditional branch that would direct my work effort here: if react-native-web is agnostic in the area of choosing webpack or next.js or vite or metro whatever, my research indicated that no choice will make everyone happy, but that Vite has largest mindshare currently while being simplest. At same time, Expo uses metro with web support. So I'd have to think carefully there but probably go with a Plan B of metro for it's Expo-related react-native ecosystem presence, with a Plan C of Vite. A truly excellent outcome if possible would be for the bundler to be configurable here, but that might just be a dream.

    I'd be willing to own it at least at the start (which for me, historically means like year+ - I commit and de-commit pretty slowly), so should be a stable experience. Ideally I can get some CI set up for you though so it will be noticeable if it breaks, even if it's just me maintaining this bit, right? You guys are great to collaborate in my experience so should work out

  6. tido64 commented on Nov 4, 2024

    @tido64
    Member

    In fact, if any of the details I posted in my "would this work?" comment above are opposite for how react-native-web already directs you to do it in their docs, I'll switch immediately to just doing what they do. KISS principle, basically, no desire to trailblaze here

    Yes, this! We should be able to point people at the official documentation. Differences should be earned.

    I'd be willing to own it at least at the start (which for me, historically means like year+ - I commit and de-commit pretty slowly), so should be a stable experience. Ideally I can get some CI set up for you though so it will be noticeable if it breaks, even if it's just me maintaining this bit, right? You guys are great to collaborate in my experience so should work out

    CI will definitely be mandatory regardless. I'm a bit concerned about what comes after your commitment is up. I'm under no illusion that anyone will be able to support this for practically forever. But in the worst case, if something happens and it becomes unmaintained, I won't be able to support it. In the best case, it will limp along with no meaningful changes and the occasional breaks that might take a while to address. Worst case, I will probably just axe it. In which case, what would that mean for the current users? Maybe I just worry about nothing and everything will be fine.

    Somewhat related, I opened this issue with the intent to make it possible to provide out-of-tree platform support so that people can provide their own platform without having to contribute directly in this repo: #2211

    Hopefully, after this lands, it means that people can use react-native-web with their favorite bundler.

  7. mikehardy commented on Nov 4, 2024

    @mikehardy

    #2211 is exactly what I thought as you reiterated your concern above about maintenance
    If there was a branch with the basic skeleton for that, perhaps -web and -tvos could be developed at same time - but out-of-tree as plugins to both prove the future-state plugin interface and minimize the risk of unmaintained cruft building up in repo where it seems like it should have first-tier support but was never really planned to?

  8. tido64 commented on Nov 4, 2024

    @tido64
    Member

    If there was a branch with the basic skeleton for that, perhaps -web and -tvos could be developed at same time - but out-of-tree as plugins to both prove the future-state plugin interface and minimize the risk of unmaintained cruft building up in repo where it seems like it should have first-tier support but was never really planned to?

    Yes, I'm mostly thinking about removing RNTA, the repository, as a bottleneck for adding new platforms and enable platforms that are not ready to be unveiled to the public. A nice side-effect of that is that we also minimize the risks. In this world, the current set of platforms (i.e. Android, iOS, macOS, visionOS and Windows) will still live in-repo and be maintained by us.

  9. scottmas commented on Jun 3, 2025

    @scottmas

    FWIW, to get RNTA working for web you simply need to modify your metro.config.js to have the approximate below logic and then make sure you set the appropriate env var IS_WEB_BUILD set to true (e.g. IS_WEB_BUILD=true npm run react-native start):

    const IS_WEB = !!process.env.IS_WEB_BUILD;
    
    const assetRegistryPath = path.resolve(
      process.cwd(),
      "node_modules/react-native-web/dist/modules/AssetRegistry/index",
    );
    
    const rnwPath = path.resolve(process.cwd(), "node_modules/react-native-web");
    
    const config = {
      resolver: {
        platforms: ["ios", "android", "web"],
    
        resolveRequest: (contextRaw, moduleName, platform) => {
          const context = IS_WEB
            ? {
                ...contextRaw,
                preferNativePlatform: false,
              }
            : contextRaw;
    
          if (IS_WEB && moduleName === "react-native") {
            return {
              filePath: path.resolve(rnwPath, "dist/index.js"),
              type: "sourceFile",
            };
          }
    
          return context.resolveRequest(context, moduleName, platform);
        },
      },
    
      transformer: {
        getTransformOptions: async () => ({
          transform: {
            experimentalImportSupport: false,
            inlineRequires: true,
          },
        }),
      },
    };
    
    if (IS_WEB) {
      config.transformer.assetRegistryPath = assetRegistryPath;
    }
    
    module.exports = config;

    Also note that the metro process can ONLY support web once it is started in this mode. This is a limitation of metro bundler.

    Also, your html file (for dev at least) should look approximately like this:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    
        <title>Example</title>
        <!-- The `react-native-web` recommended style reset: https://necolas.github.io/react-native-web/docs/setup/#root-element -->
        <style id="react-native-web-reset">
          /* These styles make the body full-height */
          html,
          body {
            height: 100%;
          }
          /* These styles disable body scrolling if you are using <ScrollView> */
          body {
            overflow: hidden;
          }
          /* These styles make the root element full-height */
          #root {
            display: flex;
            height: 100%;
            flex: 1;
          }
        </style>
      <body>
        <noscript>
          You need to enable JavaScript to run this app.
        </noscript>
        <div id="root"></div>
      <script src="index.bundle?platform=web&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.routerRoot=app&unstable_transformProfile=hermes-stable" defer></script>
    </body>
    </html>
  10. wcandillon commented on Nov 3, 2025

    @wcandillon

    I would like to second Scott Ashton (@scottmas) comment here. B艂a偶ej Kustra (@blazejkustra) has implemented Web support for an RNTA app in a way that is pretty compelling: https://github.com/wcandillon/react-native-webgpu/pull/273/files

  11. tido64 commented on Nov 4, 2025

    @tido64
    Member

    If we only need a change in metro.config.js, the right place to add web support would be in @rnx-kit/metro-config. I can take a look if you're willing to test it out.

    William Candillon (@wcandillon): microsoft/rnx-kit#3838

  12. wcandillon commented on Nov 13, 2025

    @wcandillon

    there is more than a single change in the metro.config.js needed no?

  13. tido64 commented on Nov 13, 2025

    @tido64
    Member

    there is more than a single change in the metro.config.js needed no?

    From the PR you've linked, the only relevant changes I see are in getWebMetroConfig.js and metro.config.js. Correct me if I'm mistaken.

  14. wcandillon commented on Nov 13, 2025

    @wcandillon

    There is the index.html, the react-native-web dependency. Potentially other changes to have the default RNTA run on web by default (脿 la Expo).

  15. tido64 commented on Nov 13, 2025

    @tido64
    Member

    There is the index.html, the react-native-web dependency. Potentially other changes to have the default RNTA run on web by default (脿 la Expo).

    We're not quite there yet as we've not agreed whether Metro, Webpack or Vite should be the primary bundler. The very least we can do for now is to make sure we're not blocking web support: microsoft/rnx-kit#3838

  16. wcandillon commented on Nov 13, 2025

    @wcandillon

    ok thank you for clarifying 馃憤

  17. mikehardy commented on Jan 27, 2026

    @mikehardy

    Resurrecting this a little bit because it's 2026 and I believe a couple items can be generally agreed on by observation:

    • Expo is now dominant - react-native is now an "Expo-first" technology. Specifically, react-native recommends the use of a framework to build apps from the start, and there's only one framework currently, that being Expo. It is now the first choice listed in all react-native docs etc.
    • Expo uses metro for web - https://docs.expo.dev/guides/customizing-metro/#web-support

    Ergo, it seems relatively easy to make the decision now on bundlers. Choose metro. Any other choice necessarily implies choosing something that is not the de facto standard, such that you will not be taking advantage of the collective work of the entire ecosystem.

  18. tido64 commented on Jun 24, 2026

    @tido64
    Member

    FWIW, we've recently landed out-of-tree platform support so web support should now be possible without modifications in RNTA. Let me know if anything comes up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions