Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: React Cross-Platform Strategy #54

Open
lelandrichardson opened this issue Jan 3, 2017 · 24 comments
Open

RFC: React Cross-Platform Strategy #54

lelandrichardson opened this issue Jan 3, 2017 · 24 comments
Labels

Comments

@lelandrichardson
Copy link
Owner

lelandrichardson commented Jan 3, 2017

to: @necolas

This is mostly in response to #31, but also just something I've been thinking about for some time, and is a proposal for a path to building a real production-quality ecosystem for building UI with React across multiple platforms in a single code base.

At the moment this isn't very easy, and there's no standard or agreed upon way to do it. React Native has been the closest thing to accomplishing this, with the two platforms being iOS and Android platforms (and others in the community sprouting up, such as windows, vr, etc.). Projects like react-primitives and react-native-web are attempting to solve this.

I think it's important to come at this with the angle of it not being just "React Native, but running in a web browser". Similarly, I think it's important to come at this thinking more than just "web" and "native", even if we don't know what all of the additional platforms will be. (Though we can make some educated guesses... Windows, VR, desktop, etc.)

I believe there are three main tenets that are needed to accomplish this:

Three Main Tenets

Tenet 1: Platform Extensions

Platform extensions, such as the ones allowed by the React Native Packager, are crucial to creating cross-platform code-bases. It allows for people to create consistent interfaces with different implementations, and make that transparent to the end user.

I believe we should take this convention a step further by creating a webpack resolver plugin that allows for the exact same resolution rules. Additional plugins for other bundlers such as rollup and browserify would also be ideal.

In addition, I'd like to standardize on a module-scoped package.json directive: platformCascade

In an NPM module's package.json, a library author would be able to describe the proper cascade of platform extensions, and it would be scoped to every file inside of the package, but not in any dependencies. An example platformCascade could be defined in this way:

"platformCascade": {
  "ios": ["ios", "native"],
  "android": ["android", "native"],
  "web": ["web"],
  "sketch": ["sketch"]
},

This allows library authors to define cascades that may not be mainstream (i.e., "sketch"), without it having to be standardized (and without causing unknown side-effects in other modules if that extension just happened to be there).

It is critical that this convention works outside of just the RN packager, as it will be required for this ecosystem to extend beyond just RN and the associated tooling.

Tenet 2: Primitives

In order for cross-platform to really work, we need to make a world where if someone wants to build a cross-platform UI component, they don't have to implement it n times for n platforms. This requires at least a few building block components.

  1. StyleSheet: Layout is critical to building dynamic UIs. There are lots of options for layout algorithms, but flex box makes a compelling choice. Yoga is a cross-platform flex box implementation that will likely be applicable to many platforms, and the algorithm is already available in all major web browsers (though with some problems still remaining). React Native's StyleSheet implementation is quite nice to work with, and works extremely well with React.
  2. View: Basic rectangular view. Important for this to take into account layout (through style) as well as accessibility attributes, and the proper event hooks. The API that RN has chosen for view seems to do a pretty good job, and I suspect this is in large part due to the fact that RN was built with cross-platform in mind.
  3. Text: Laying out text is vital to building UI, obviously.
  4. Image: Sometimes you need to display Images in your UI.
  5. Animated: It's important to make UIs dynamic and interactive. Animation is a critical component to this. The Animated API from React Native is a perfect candidate for this. It is declarative, which makes it easier to decouple the API surface area from platform-specific implementation. It is also already has an implementation completely implemented in JavaScript that would work by default, while other "native" implementations could also be implemented with some effort w/ the same APIs.
  6. Touchable: Touching/Pressing ends up being a fairly basic and essential form of interaction.
  7. Platform: This is less of a primitive as much as it's a utility. Pragmatically speaking, it's often needed to do small statement-level switches between different platforms to configure things differently based on the underlying implementations.

We want to be careful in choosing these "primitives". We need enough to be able to build bigger more complex things, but need to keep it minimal enough so that it's reasonable to expect a new platform to be able to implement the full set of them. I believe things like TextInput may be really important in terms of some platforms, but not others, and so should maybe not be a primitive. This will have to be defined over time, but I think being conservative at first is ideal.

To be honest, I'm actually not sure if I'm even confident about the primitives listed above. For instance, if we wanted to add a platform like "console" and create something like react-curses, it's not clear if Image or Touchable actually make sense. These components were mainly chosen because after creating a fairly complete Component Library for Airbnb in React Native, I noticed that almost 95% of it could be implemented with just these primitives. The four that seem really clear to me are StyleSheet, View, Text, and Platform, but it's a balance.

Tenet 3: Platform built on Primitives

With the "primitives" now built, now it is our job to figure out what useful crap we can build with them! The idea behind the primitives is that they are the building blocks that other more useful things can be built. Perhaps mediocre versions of things that are general and purely implemented by primitives.

Some components will need to have custom platform-specific implementations that will ensure that they perform as good as they possibly can, but we must always have at least one implementation that only uses the primitives (or other higher-order components that themselves have a primitives-only implementation).

There's some obvious candidates for these components. Since we want to be able to share code between React Native and Web, most of the non-platform-specific APIs exported by React Native make obvious choices, but there are obviously lots more.

Proposal

I haven't really proposed anything yet, as much as I've just talked about what I think is important. Here comes the proposal. Please keep in mind that I'm hoping this just starts the conversation. More than anything I'm interested in feedback and seeing if my ideas align with yours.

At the end of the day, I think there'd be a lot of value in us working together, and this is one way I could see that happening while (i hope) serving each of our slightly different use-cases.

The first proposal would be to move/rename necolas/react-native-web to react-community/react-platform. Alternatively, we could deprecate it and start fresh.

react-platform would become a lerna monorepo. One of the packages in the repo would be react-primitives which would include the primitives mentioned above, with the optimal implementation (whether that's RNW's current implementation, or react-primitive's, or some combination of both). The lelandrichardson/react-primitives repo would also be deprecated.

Various modules that have been written in react-native-web would be refactored to be their own package in the lerna monorepo. For instance, ScrollView and ListView would become react-platform-scrollview and react-platform-listview.

A convention I could see working for this monorepo is a folder structure like this:

- react-platform             // repo root directory
  - packages
    - {package-name}
      - {platform-name}
        {file}.js            // clear that files here are meant for {platform}
    {file}.{platform}.js     // optimized version for {platform}
    {file}.js                // fully cross-platform implementation

We could also export a "grab-bag" package which could just be react-platform, which essentially be what react-native-web currently exports (something that attempts to be API-compatible with RN). Of course, you could also keep react-native-web and just depend on all of the corresponding react-platform-* packages or whatever was needed and export them directly (which may actually make more sense?).

Questions & Answers

What packages belong in the react-platform monorepo?

Of course the whole point of this is for any library authors to also be able to publish cross-platform components/modules by only depending on react-primitives and other fully cross-plat dependencies. So packages don't need to be part of the react-platform monorepo in order to be a primitive.

My thinking is that by something being in the monorepo, we are asserting that no matter what platform you are on (i.e., could be something obscure like "sketch"), we are guaranteeing that there will be at least one primitives-only implementation (functional, even if it's not optimal). Of course we will also have more optimized implementations in the case of the more popular platforms (namely, "native" and "web").

How would new platforms get introduced?

I'm still not 100% sure what the right answer here is. If we lived in a world where there were ~15 platforms and there was source code for each in this monorepo, the maintenance burden could start to get out of hand. On the other hand, the idea should be that a new platform need only implement the primitives, and everything else should "just work" (even if using the non-optimal cross-platform implementations). My feeling is that the criteria ought to be something like:

  1. An implementation for every primitive is reasonably complete
  2. Someone is willing to be a point of contact for maintenance / issues / etc.

Does it have to look like React Native's API?

No, but it doesn't hurt if we follow an already existing API, and React Native's make the most sense, as most of them have already been built with cross-platform interfaces in mind.

Will this be maintainable?

Happo is a CI tool built to detect visual regressions by taking screenshots and diffing them. I've been working on getting happo working for iOS, Android, and Sketch as well.

I believe we should be able to create a bunch of minimal examples with the primitives stressing all of the corner cases of layout as well as styling (box shadows, borders, border radius, transforms, etc.).

We then get two things out of this:

  1. We are able to detect visual regressions of the primitives and other components of the platform.
  2. We are able to directly compare all of the platforms in a straightforward way.

This, in addition to standard stuff like tests, listing, etc. I think will give us a pretty good story in terms of maintenance.

Long Term

React Native

Although this wouldn't have to be an initial goal, I could eventually see implementations of various react native APIs moved into the react-platform repo instead of the react-native one. We have already talked about making RN core more modular and moving it into a similar repo structure. It might make sense for some of these things (like ListView, for example) to live outside of ReactNative as a lot of their optimizations are JS-level optimizations and could benefit all platforms.

Flexbox / Yoga

I know that Sebastian Markbage has been thinking about integrating layout into react for a long time. I think this would bode very well for the concept of "primitives" and also ensure that different platforms would be more consistent. The main thing each platform would then have to provide would be a text measurement API. I'd like to add an emscripten pipeline to Yogo so that there is an optimized and consistent JS implementation of flex box that matches the native implementations. You could also see Web Assembly as a target for Yoga in the long term as well.

Adoption

Imagine if today's most popular react-* and react-native-* libraries depended on react-primitives or react-platform-* packages instead of react-native or "host" DOM components like <div> and <span>. Entirely new platforms could be born overnight by just implementing the primitives, and entire code bases could be made to target those platforms with just the changing the "platform" target of your JS bundler, and potentially implementing a couple of platform-specific interfaces where needed.


I look forward to your thoughts, and hope that we can find a time to talk about this more seriously if you are interested (perhaps next React Wednesday?)

@necolas
Copy link

necolas commented Jan 4, 2017

Hey, thanks for sharing. This sounds good. Internally I've experimented with aliasing to react-platform and using ES6-aware bundlers…so this is very much along the same lines and encouraging. I'm currently getting react-native-web ready for a production test on mobile.twitter.com, and would like to write up some more detailed thoughts, feedback, and questions soon. (Maybe we can move this to a Google doc as they are easier to share and comment on? And I'd be happy to meet up at Airbnb/Twitter to talk and better understand what our teams need.)

@ljharb
Copy link

ljharb commented Jan 4, 2017

I'm concerned about relying on flexbox for this cross-platform effort, because that tightly constrains the lower bound of a supported browser list in a way that will prevent many companies and users, including Airbnb, from adopting it.

While it's possible that in a few years, a lack of flexbox support won't be a problem, it is a problem now, and past history with browser versions suggests that we shouldn't count on that problem going away any time soon.

@necolas
Copy link

necolas commented Jan 4, 2017

I'm concerned about relying on flexbox for this cross-platform effort, because that tightly constrains the lower bound of a supported browser list in a way that will prevent many companies and users, including Airbnb, from adopting it.

Fair enough. That's not really a problem for Twitter – I think the browser support matrix for both twitter.com and mobile.twitter.com includes only flexbox-supporting browsers.

@skevy
Copy link

skevy commented Jan 4, 2017

@ljharb I believe the problem of browser support is what @lelandrichardson was referring to when he said

I'd like to add an emscripten pipeline to Yoga so that there is an optimized and consistent JS implementation of flex box that matches the native implementations

I don't know if we know how fast that implementation would be, the size, etc...but I feel like it'd be worth a try to get a decent polyfill across ie8/9/etc

@skevy
Copy link

skevy commented Jan 4, 2017

Also, evidently this emscripten'd Yoga implementation now exists as of 2 days ago: https://github.com/facebook/yoga/tree/master/javascript

@ljharb
Copy link

ljharb commented Jan 4, 2017

If we had a reliable and performant way to fully polyfill/transpile/compile a subset of flexbox (and easily prohibit/lint against whatever's not polyfilled) down to all ES5 browsers, that'd be plenty good enough I think. If we can include any ES3 browsers (like IE 8) I think we've got an unstoppable juggernaut of standardization going.

@ericvicenti
Copy link

Awesome writeup @lelandrichardson!

These tenets are critical pieces of the dream of making one app work effortlessly on any platform. I would encourage you to emphasize one more tenet: feature detection over platform gating.

In a world with feature detection, we can encourage competition in the platform ecosystem. Take TouchID encryption, for a random example: if I assume that it is forever an iOS-only feature, I should put it behind a platform gate. But if we want other platforms to implement that awesome functionality, I would put it behind a feature check. Then Microsoft and Google can compete to implement it and get better-featured apps for their stores. (Plus, you'd need to implement that check anyways in order to properly support older iOS devices.)

I also think we should always support platform checks as an escape hatch. Just like how we allow escaping to native code in RN, there are tons of real world cases where we need to let the developers drop down and handle something in the DOM when they need to.

We could stimulate a ton of competition in the ecosystem: from camera features and other sensors, to GPU optimizations, home automation, VR, and native/OS navigation. If we want to live in a world where our portable code just works in more places, I think we should emphasize feature detection.

@lelandrichardson
Copy link
Owner Author

I would encourage you to emphasize one more tenet: feature detection over platform gating.

Interesting. This is a good point, and I haven't given it a lot of thought. This is kind of inline with something that @vjeux wrote up a while ago with deciding the right interfaces for RN. I can't find it right now, but the main point of it was we should try to match the web standard's specs first (ie, fetch, geolocation, etc.), but deviate if it's objectively not a good choice for a cross-platform API, and only then decide on a new one.

I'm not sure I fully understand how these principals apply to things like Touch ID which aren't web APIs. I know you just picked it as an example, but I'm not sure what the right way to share that would be.

How do you envision "encourage feature detection" being pulled into this proposal? Are you envisioning this as something instead of the Platform API?

@ericvicenti
Copy link

I'm not sure I fully understand how these principals apply to things like Touch ID which aren't web APIs. I know you just picked it as an example, but I'm not sure what the right way to share that would be.

I specifically picked that example because it isn't a web API yet. Basically I'm suggesting that the JS app should check for presence of native features and opts in to them when available. Instead of specifying behavior for each platform, an app would specify behavior for cases where different native features are available.

Another practical example may be the camera. If I adopt a camera library in my app, I should check with the library to determine if there is a camera on the device, rather than assuming certain platforms have cameras. And I should check with the library to see if the camera has a LED, to determine if the flash buttons should appear. The standards web API may not support flash settings, but if my app checks with the library, then the library can later add LED support for new environments, even though the standards support lags behind.

How do you envision "encourage feature detection" being pulled into this proposal? Are you envisioning this as something instead of the Platform API?

I think the platform API should be available as an escape hatch for when you absolutely need to override based on the platform. This should be used when the product requirements are different, designs are different, or in cases where probing the native modules for feature detection causes instability.

Maybe the three tenets can be reworked as such:

  1. Build a lowest-common-denominator implementation with primitives
  2. Use feature detection where possible to utilize native features, regardless of platform
  3. Fork based on platform (and use platform extensions) as a fallback, or for product reasons

@lelandrichardson
Copy link
Owner Author

lelandrichardson commented Jan 4, 2017

As I'm thinking about this more.... what does "Feature Detection" look like that doesn't work through globals? Typically feature detection is something like "does this thing exist" or "if i do this thing, does this result look right". The problem is I don't know how this maps to user-land modules? How do I say "If "react-platform-fancy-button" works for me, then use it. Otherwise use this"?

@ericvicenti
Copy link

You make a good point- it would be nice if we had a standard for safe feature detection. As you point out, only standard-ish way of doing it right now is checking for the presence of a global.

@benmvp
Copy link

benmvp commented Jan 5, 2017

First of all, I wanna say that this is AWESOME*! I really love where this is going. The better we can all pool our individual efforts, the better the overall ecosystem will be.

As I start digging into the nitty gritty, a couple of things come up, however:

I believe things like TextInput may be really important in terms of some platforms, but not others, and so should maybe not be a primitive.

I'm confused why this isn't a primitive. Is it because of view-only Sketch? IMO all UIs boil down to viewing info, interacting with info and modifying info. How awesome would it be if react-select, react-dates or even draft-js were automatically cross platform because a generic component was built using primitives. I think TextInput would be needed.

Some components will need to have custom platform-specific implementations that will ensure that they perform as good as they possibly can, but we must always have at least one implementation that only uses the primitives (or other higher-order components that themselves have a primitives-only implementation).

Have we given any thought about where semantic markup goes in this world. I'm guessing TouchableText would be a <span> with an onClick instead of a <button>. But a <button> is needed for a11y. Similarly you can really easily create a radio/checkbox using <View> components, but really it should be a "web native" checkbox or radio on the web.

And where do <a> tags live? Sure you can have <Text> with large font (like you'd do in RN), but really you have an <h1> for SEO purposes. And of course we have <header>, <main>, <section>, etc. which would all be <div> soup with everything as View components.

As I see things, in order to build a realistic web app, you would end up having to use "web native" tags in order to build for SEO and A11Y. And as a result the need to build versions for each platform moves higher and higher upwards.

The only thing I can think of is that there is another layer on top of the primitives for things like <Link>, <HeadingText>, <Checkbox>, etc. that most composite components would actually use. On the web, these would map to semantic tags, but for other platforms they could just be direct wrappers of the primitives.

Does that make sense?

@necolas
Copy link

necolas commented Jan 5, 2017

Perhaps React Native can start by moving the platform-specific APIs and components out of the main library's export. These problems are harder once the RN ecosystem is built around the assumption that there are only 2 platforms, forcing other platforms to stub or implement iOS/Android modules like ToolbarAndroid and SegmentedControlIOS.

I'm confused why this isn't a primitive.

Agreed. I think it should be; it's part of the "core" exports we need and use on mobile.twitter.com.

Have we given any thought about where semantic markup goes in this world.

This is factored into react-native-web.

  • accessibilityRole can be used to specify the ARIA-role, which also produces the equivalent DOM node. For example, <View accessibilityRole='main'/> => <main role='main'>.
  • Touchables are button[type=button] by default
  • Radio and checkboxes can be built using ReactNative.createDOMElement, which takes a DOM element and RN props, mapping them to DOM props. Using View is not the best tool for this job.
  • Links are supported on either View or Text using accessibilityRole and href...or custom link components can still be built from a using createDOMElement.

If you have any ideas on how to improve this, I'm interested to hear them.

@benmvp
Copy link

benmvp commented Jan 5, 2017

Agreed all around! Thanks for the response.

So if the primitives come with an accessibilityRole prop then the web versions of the primitive can do special things as necessary but the other platforms can potentially do nothing. I like it.

I first read ReactNative.createDOMElement feels weird to me because DOM === web in my head. But really nothing about the Document Object Model is inherently web-specific. Is the idea that render() returns createDOMElement instead of JSX? What does this do in React Native?

So for a component like Checkbox, the generic version would be built from View but the web version would use createDOMElement?

@necolas
Copy link

necolas commented Jan 5, 2017

I first read ReactNative.createDOMElement feels weird to me

It would probably feel less weird if React Native had been called something like React Platform: ReactPlatform.createDOMElement / ReactPlatform.requireNativeModule. But I'm open to createDOMElement being called something else or the end result being achieved with a different API.

So for a component like Checkbox, the generic version would be built from View but the web version would use createDOMElement?

Well, there would only be one Checkbox and each platform might have a custom implementation. If some platforms can get away with a pure JS implementation using View, then they should. But if the implementation needs access to platform-specific APIs or components (for performance, ease, accessibility, etc.) then we use the escape hatches to do that.

The long-term objective / hypothesis is that we'd use the various escape hatches as infrequently as possible, for low-level building blocks, so that the rest of the ecosystem above is built on a unified, platform-agnostic, JavaScript-only API. But at the moment even RN has a lot of iOS/Android-specific deviations exposed in the APIs of its core components and features :)

@ekryski
Copy link

ekryski commented Jul 10, 2017

First off! Amazing work! This is so great! 🙌

Privately, at our company we've been building cross platform components on top of react-native and react-native-web and came to the very same conclusion that we needed a bit more of a layered approach with a minimal "core" set of cross platform components to build off of. Our abstract components were getting super messy and cluttered. As the components grew we had lots of platform specific forks in order to keep them performant and have good UX, SEO, etc.

@necolas @lelandrichardson are you guys still planning on moving forward with react-platform? Re-reading through this when I've had ☕️ I agree that keeping the set of primitives small makes a lot of sense! It's hard to plan for platforms that may not exist yet but depending on which platform you spend most of your time working it's easy to forget about the others. cough Sketch cough

FWIW I think @ericvicenti's core tenet revisions are pretty bang on.

  1. Build a lowest-common-denominator implementation with primitives
  2. Use feature detection where possible to utilize native features, regardless of platform
  3. Fork based on platform (and use platform extensions) as a fallback, or for product reasons

I'm also not sure how you do feature detection other than having a mapping for each supported platform much like do with Platform already. Possibly extend it with a list of Platform.features and we come up with a feature matrix with consistent naming? What those are I'm not sure....

Which leads me to another question. Is the goal of react-primitives meant to exclusively be UI components or should it also include common APIs? For example:

  • UI, Layout, or Dimensions (which already seems to be in the works)
  • Linking
  • i18n
  • Network
  • etc.

Personally, I think that it probably makes sense to also have a small set of common APIs. If that becomes the case I see some parallels with ReactXP. Although IMHO I think what they have done could probably be broken down into 2 layers as some of the components seem to be a bit more meta.

@teabyii
Copy link

teabyii commented Sep 30, 2017

I'm late. This issue excites me. I wanna to know any progress about the react-platform now?

@jhampton
Copy link

jhampton commented Mar 3, 2018

@mathieudutour @lelandrichardson and @necolas I've been doing some work recently that involves additional platforms, and I'm moving toward standardizing around primitives, Webpack, and Lerna for React Native development. I heard there are some plans within the RN project itself around creating an abstraction, "primitives", and platform-support.

I agree with the original post as well as the need for TextInput – I can't think of a platform that doesn't support TextInput in one way or another (we're using React Sketch.app, and the Text object (editable in Sketch) essentially maps directly into Sketch:

  • User pulls React Primitives-based component(s) with TextInput into Sketch
  • User changes text on a symbol
  • Plugin receives the change and initiates an action or changes "state" in response

We're looking at TextInput and names in Sketch to provide metadata and operations within Sketch, so I think it may warrant trying to find a platform that doesn't have TextInput (even if the input is made via speech). If RN had an <Input />, I might argue that INPUT is the real primitive here.

Regardless, is react-platform still moving forward? If not, where do you feel primitives and RNW are today, and what are your plans?

Thanks in advance, and thank you all for your incredible work!

@adamcee
Copy link

adamcee commented Mar 5, 2018

@jhampton I would love to see a repo with a basic setup, if you have one - I was trying to work with Primitives recently (using webpack-blocks for build) and running into trouble. Sorry for being a bit off-topic.

@jhampton
Copy link

jhampton commented Mar 7, 2018

@adamcee Thanks for mentioning webpack-blocks – I hadn't seen that one before. I'm doing some investigation around adding multiple platforms, and I'll be in touch if it yields any value.

@LaloHao
Copy link

LaloHao commented Jun 12, 2018

Are you currently developing this on a repo we can contribute?

@jhampton
Copy link

It looks like Lona is the sibling project in making x-platform possible. I’m investigating that ATM.

@TheSavior
Copy link

A related discussion has come up recently as we have been working on Fabric for React Native. With Fabric, the native definitions of props are moving to C++ and platforms like iOS and Android will implement that interface. That means we are getting to a set of primitives that are the common denominator across multiple platforms and trying to figure out how platforms can extend that with custom functionality.

I wrote up a bunch of stuff over in the RN proposals repo and would like some eyes on it from people who’ve participated in this React-primitives conversation in the past. I think we are starting to move in this direction.

react-native-community/discussions-and-proposals#50 (comment)

@macintoshhelper
Copy link
Contributor

macintoshhelper commented May 15, 2020

Hi, I've implemented a proof-of-concept/experimental repository based on some of the ideas discussed in this RFC, as a community-led/open-source project, to help push forward progress, as it's been a while since these proposals have been made.

I've created a @react-platform npm org/namespace that is a mono-repo of packages that help people develop cross-platform apps, mainly being abstractions/polyfills for react-native APIs and popular npm packages, like @react-native-community: https://github.com/elemental-design/react-platform . I've published a @react-platform/native package which exists as an alternative to react-native-web for other platforms such as react-native-windows, react-sketchapp and react-figma.

My repo builds on top of the work that I've been doing lately with react-sketchapp and my cross-platform UI library: elemental-react.

The plan is for @react-platform/native to export most React Native APIs such as <TextInput>, <ScrollView>, Dimensions, useWindowDimensions, etc, defaulting to platform specific imports e.g. import { useWindowDimensions } from 'react-native-web' or import { useWindowDimensions } from 'react-sketchapp'. There are JS/React only implementations of APIs/components for which there is no platform compatible substitution. I've created a @types/flow-typed inspired system for npm package polyfills (@react-platform/<package-name> imports that resolve the correct npm package).

I think one of the coolest applications of the repo, is having packages like @react-platform/async-storage, which re-export @react-native-community/async-storage for React Native or React Native Web, but provide a JS only fallback that'll work on any platform (async session/JS object storage, mainly existing as a stub) and a Sketch implementation/polyfill of @react-native-community/async-storage that uses the Sketch Settings.settingForKey API 🎉.

I'm planning to develop cross-platform wrappers for SVG, Lottie, date pickers, etc for it too.

This can already be used today to help make React Native apps be able to render to react-sketchapp or other platforms.

Would love your thoughts @lelandrichardson @necolas @mathieudutour . And should this discussion/proposal be migrated over to react-native-community/discussions-and-proposals#50 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests