react-native-community/discussions-and-proposals

React Native Fabric (UI-Layer Re-architecture)

kelset opened this issue Β· 171 comments

Intro

With this issue I'd like to try and create a "one stop" for all the information available around the future re-architecture of the UI-Layer of React Native, codenamed "Fabric".

Terminology

  • JSI: JavaScript Interface, it's a unified lightweight general purpose API for (theoretically) any JavaScript virtual machine. It enables every other piece of the rearchitecture. (dedicated issue)
  • TurboModules: re-architecture of NativeModules, also using JSI. (dedicated issue)
  • CodeGen: a tool to "automate" the compatibility between JS and native side. (dedicated issue)

TL;DR

From @axe-fb's blogpost, here's a temporary description of Fabric (please consider that this is not yet finalized, it may change in the future)

In the current architecture, all UI operations (like creating native views, managing children, etc). are handled by a native module called UIManagerModule. The React Reconciller sends UI commands over the bridge, which are eventually handled by this module and delegated to UIImplementation. This in turn creates shadow nodes that represent the layout tree and are passed to Yoga to determine the relative co-ordinates based on the Flex box styles that are passed in from JS.
In the new system, the UI operations are directly exposed to JavaScript as functions using the JSI interface described above. The new UI manager can then create ComponentDescriptors and the Shadow Nodes for specific view types (like Text, View or Images), and then communicate with Java/ObjC to draw platform specific UI.

Available Materials

It was first announced in the "State of React Native 2018" blogpost by @sophiebits.

In July, @hramos linked a broadcast of a tech talk that happened in FB, which covered the ongoing work on the new React Native architecture codenamed "Fabric": facebook.com/hramos/videos/10101317533036249 (go to 8:18 for the presentation start - audio is a bit bad)

Further down the line, it was presented at ChainReact Conf 2018 by @axe-fb in the talk "The State of React Native".

At ReactConf 2018 @axe-fb did a talk about React Native's New Architecture, which also explains the 3 concepts above: JSI, Fabric, TurboModule.

On twitter, @shergin shared a presentation about View Flattening -> https://twitter.com/shergin/status/1058393187079704576?s=09

On twitter, @kmagiera shown a early stage implementation of Fabric working on the RNTester app -> https://twitter.com/kzzzf/status/1064891715457294337

IN Q1 2019, @kelset published a high-level/beginner friendly blogpost about it: https://formidable.com/blog/2019/fabric-turbomodules-part-3/ and did a talk about the whole rearchitecture in April 2019 at React Edinburgh.

@kelset also did a more in-depth talk at React Advanced London in Oct 2019: youtube recording & slides.

As of early Jan 2022, a first version of the docs about Fabric are on the main reactnative.dev website.

SWM published a blogpost on how they added Fabric to one of their libraries: https://blog.swmansion.com/introducing-fabric-to-react-native-screens-fd17bf18858e

Q&A

This is also a place for questions related to this effort and its direction.

Kevin's talk about Fabric internals

React Wednesday (July 25 2018)

Recording - https://www.facebook.com/hramos/videos/10101317533036249/

Video - https://www.slideshare.net/axemclion/react-native-fabric-review20180725

We can start a Q&A here where anyone involved can share knowledge and ideas. πŸ˜„

I see Fabric as an effort aimed to modernize the rendering layer of React Native. Fabric relies on some new strategies, such as:

  • Using C++ for cross-platform "shadow" layer;
  • Immutable data structures (Shadow Trees, Props, Events);
  • Shared memory ownership (between JS and native);
  • JSI as an interop layer between JavaScript and native;
  • Type-safe data structures;
  • Opt-in synchronous execution where it benefits performance, the UI responsiveness and simplifying inherently-synchronous interop APIs.

Fabric is all about modern, easy-to-interop and performant UI.

This sounds really cool. :)

  1. What's the timeline for Fabric's first stable release? Is there an issue tracking the progress of development? Will there be an in-depth blog post on the internals?

    edit: I see the overview stream covers the timeline and internal concepts, but a text version would be great, too! Also, could you improve the audio quality of streams like this one by using an external microphone in the future?

  2. What does Fabric mean for developers of native modules?

  3. What problems are solved by shared memory ownership between JS and native?

  4. How does the "JSI" differ from the React Native bridge?

  5. Can you provide more details on the removal of ViewManager modules?

  6. Will the reconciler eventually be in C++?

Thanks!

@aleclarson Thank you for your question!

What's the timeline for Fabric's first stable release?

We don't have any public deadline or timeline. It's also hard to define what stable actually means for Facebook and for external users. We have quite ambitious (but realistic) plan to enable Fabric for some of the most popular RN screens in the main app.
To me, the most important mark will be when we enable Fabric for all screens in all Facebook apps. It's unclear when we will hit this point, but I am pretty optimistic about that.

What does Fabric mean for developers of native modules?

Fabric doesn't affect native modules API directly (this is a separate effort), except special kind of NativeModules called ViewManagers. Fabric does not use this approach anymore, any component-specific View Managers have to be rewritten. See also below.

What problems are solved by shared memory ownership between JS and native?

Technically, this problem does not exist in the current architecture, because the shadow tree is not shared between JS and native, each side maintains own copy of the same tree.
In Fabric, we have to be able to support multiple versions of (partially) immutable shadow trees, which can be created by both sides. To make this performant we have to "share ownership" of every node in those trees. So, if some particular node is not needed by both sides, it can be automatically deallocated; there is no need to maintain hash tables and send the information between worlds. JSI makes it possible exposing API that allows to call finalizes when GC collects objects.

How does the "JSI" differ from the React Native bridge?

They are similar but... totally different. They both connect JS machine with the native world.

Bridge is part of React Native.
Bridge includes:

  • Serializing/Deserializing pipeline;
  • Queueing;
  • Native Module API;
  • Asynchronous calling API;
  • (kinda special) Synchronous calling API;
  • Something else; Bridge is huge.

JSI is not a part of React Native, it's a unified lightweight general purpose API for (theoretically) any JavaScript virtual machine. Now there is only one implementation of that - for JavaScriptCore VM.
JSI has/allows:

  • Expose some native objects as JS objects and vice-versa;
  • Expose API for synchronous calling on this object in both directions.
    Everything else should be built on top of that.

Can you provide more details on the removal of ViewManager modules?

In the current architecture, ViewModules almost always contain only props mapping; in Fabric this information is described as *Prop classes in C++. So, there is no need for ViewManager.

Will the reconciler eventually be in C++?

Probably. Probably not. We are thinking that something like this might be valuable and feasible in a couple of years. But, personally, I think if we are thinking about this now, we can figure out something even smarter than that. :)

Thanks for the Q&A πŸ˜ƒ

Will the JNI work like NativeScript does it?

I read they don't need bridges written in ObjC/Java.

@kay-is

Will the JNI work like NativeScript does it?

Do you mean JSI? I don't know how NativeScript works, so I cannot say.

Yes, JSI, sorry.

AFAIK NativeScript exposes all native APIs in JS, so you don't need to write native code to interact with them.

@kay-is It is similar, but there are differences. Unlike NativeScript, we would not have a binary file that registers ALL methods on the outset. It is more like HostObjects, which can have getters/setters.

What side effects can we expect? Decreased build times? Decreased binary sizes?

How much of Java/ObjC code will become C++ in the end?

aljs commented
  1. Can you share any benchmark results? I know, it's still a WIP - but it's interesting how Fabric compares to an old realisation in terms of performance.

  2. Does this affect native Obj-C modules that aren't running on the main thread?

@AlicanC

What side effects can we expect? Decreased build times? Decreased binary sizes?

Probably, but that's not our goal. The main goal is to make the code more modern, flexible and maintainable.

How much of Java/ObjC code will become C++ in the end?

The goal is to have as small amount of platform-specific code as possible. It's hard to estimate exact amount though.

@aljs

Can you share any benchmark results? I know, it's still a WIP - but it's interesting how Fabric compares to an old realisation in terms of performance.

At this point, we don't have numbers in which we are confident enough to share. I expect to have them relatively soon though.

Does this affect native Obj-C modules that aren't running on the main thread?

(At least on iOS) All native modules which are view managers should be rewritten/adopted to Fabric, eventing else is covered by separated effort called TurboModules.

msand commented
  1. How will the removal of ViewManagers affect Animated and useNativeDriver?
  2. What differences are there between iOS and Android? (previous message suggests only iOS needs rewriting of view managers)
    Seems the removal might simplify native animation of e.g. react-native-svg. I've had to introduce property setters in the ViewManagers and Views/ViewGroups (just to contain a reference to the shadow node, in order to be able to set the properties) in addition to the shadow nodes, for all Svg elements on Android, to allow animation using the native driver.
    https://github.com/react-native-community/react-native-svg/pull/757/files#diff-4514e2800c86c3d034626a608dce25b2
    facebook/react-native#18187
    software-mansion/react-native-svg#757
  3. Will there be improved support for writing native modules in C++?

@msand For native modules (3) - note that you can already write native modules in C++.
We are also working on a parallel proposal for a new architecture for native modules - #11

msand commented

@axe-fb Do you have any good examples? I've seen expo-gl and just now found
https://github.com/sulewicz/djinni-react-native
https://github.com/sulewicz/djinni-react-native/tree/master/example-react-native/ExampleProject
which seems to simplify things.

msand commented

I'm thinking for react-native-svg the text layout algorithm from the SVG 2.0 spec might make sense to attempt implementing in c++ instead of both obj-c and java. Would be easier to maintain a single implementation.

@msand

How will the removal of ViewManagers affect Animated and useNativeDriver?

Native Animation Driver has to be rewritten, we plan to invest in it this year. Classic Animated implementation will work out of the box because it relies on setNativeProps which will fully support by Fabric soon. This is true for iOS and Android implementations.

I'm thinking for react-native-svg the text layout algorithm from the SVG 2.0 spec might make sense to attempt implementing in c++ instead of both obj-c and java. Would be easier to maintain a single implementation.

Yes, totally. I think the all non-drawing code should be unified and rewritten in C++. We plan to do this for ART soon.

I've made an overview talk of how React Native bridge architecture works

I've made a talk that presents the current React Native Bridge architecture, explaining its characteristics, how it works and its drawbacks.
I've also talked about how the new future bridge architecture will look like

https://speakerdeck.com/sibelius/react-native-bridges-architectures

I think this could be a good intro for the bridge topic

aljs commented

Are some parts of it already in use without a flag? (on master branch)
Get a crash related to custom view manager on [self.subviews objectAtIndex:]. Only on iOS 9-10, which is weird.

@shergin I’m currently trying to implement the FLIP animation technique in React Native.

If you haven’t seen this in browsers, the short version: When the layout of a component changes, we can invert its positional delta via a transform, and then animate it into its new position by animating x and y back to 0

To do this seamlessly, without seeing the component in its new position for a frame, we need to guarantee onLayout is fired before the new position is drawn to the screen.

The docs say β€œthe new layout may not yet be reflected on the screen at the time the event is received”, and indeed now and then there is a perceivable β€œsnap”. Will Fabric allow us to guarantee execution of onLayout before the layout is reflected on the screen or am I barking up the wrong tree?

Thanks in advance for your input

Will Fabric allow us to guarantee execution of onLayout before the layout is reflected on the screen or am I barking up the wrong tree?

A few things:

  • onLayout() is an async event from native to JS, so unless native guarantees that the event is dispatched synchronously after native layout, there’s no guarantee that the content is final.
  • One of use cases that Fabric can enable is β€œsynchronous initial rendering”, where UI layout happens synchronously until content is ready to be displayed - we’ll tackle this a bit later after the core of Fabric and its parity with existing impl are stable.
  • Now, it is in theory possible to update the behavior of onLayout() to be more synchronous in nature, or to avoid the need of initial onLayout() if native can provide layout info synchronously on mount. We are thinking about this, but it won’t be immediately changed via Fabric project. It’s more of improvements we can do on top of Fabric.

Hope that helps.

will this re architecture of react native yield performance as good as flutter or flutter's performance is just hyped about?I have learned react recently and I love it ,will it prove to be a good decision to learn react-native for native mobile apps or in core of your heart you feel flutter is better?

@contactyash

  1. Fabric is designed to be (incredibly) responsive and interopable.
  2. Real performance Flutter vs. Fabric is incomparable unless we have big production apps written in both of them.
  3. All apps that I have seen in Flutter don't demonstrate impressive performance unfortunately (totally bias opinion).

The two main reasons that I stopped using on React Native were Navigation and ListView.
For navigation, I think I've tried 5 different libraries including React Navigation and all felt sluggish. I think wix/react-native-navigation v2 can finally address the problem. I have my hopes up.
For ListView, I've tried every library and every optimization solution out there and it all failed miserably for large lists with pictures and few dynamic components. In the end, I had to bridge native tableview and native cells in order to make it useable.
App startup kept getting slower as app grew large as well. I really hope this re-architecture finally fixes these issues.
ListView and Navigation are the most commonly used components in any apps, and they are still the main problems after 5 years for React Native.
With sync communication between native and js, will it be possible to use native native tableview with cells being rendered in js?

@joonhocho Yes, Fabric is a foundation that meant to help improve things including navigation (sync external interop) and lists (better/sync measuring API, build-in view recycling and flattening). Fabric itself will not solve that, but it will enable actual solutions.

@shergin I am wondering, in new react native architecture, whether even the rendering can be synchronized. I believe IOS UITableView requires synchronized rendering of cells. That means React should render and return native cell view to the tableview in synchronized way. Will this kind of behavior supported by the new architecture or rendering will be always asynchronous?

Yes, Fabric will support synchronous rendering (state change). However, relying on UITableView it's not the only way to implement smooth and fluid lists, the actual approach and API might be different.

@shergin when Fabric reaches beta level will we be able to use both JSI and Bridge at the same time ? I am trying to learn if we will need to wait until every component is ported to new architecture or they will be able to live together until Fabric takes over ? Thanks.

Also i think/hope Fabric will help resolving many core problems, thanks for starting this re-architecture team. My best wishes for React Native.

I have some questions:

  • Will fabric comes with big list optimization by default. If not, is this on some schedule.
  • Will fabric bring new api like SyncStorage

when Fabric reaches beta level will we be able to use both JSI and Bridge at the same time ? I am trying to learn if we will need to wait until every component is ported to new architecture or they will be able to live together until Fabric takes over ?

See @shergin's comment regarding timeline: #4 (comment)

At the moment, the system allows both Fabric compatible components and the existing view manager-based components. At some point in the future though, all components need to be Fabric-compatible. We'll share more details around the plan in later time until the core of Fabric is more complete and stable.

Will fabric comes with big list optimization by default. If not, is this on some schedule.

@shergin touched this in his previous comments:

Will fabric bring new api like SyncStorage

Fabric is just about the UI layer of ReactNative. SyncStorage seems like something that could benefit from synchronous calls to native (whether or not JSI will be used). If you want to call native synchronously, it is already possible today: #11 (comment). We're working on an effort to improve calls to native from JS as a whole though, separate from Fabric: #40

(updated the first comment with a link to Ram's talk at ReactConf)

Is the JSI project going to be open-sourced? If so, where can we view it?

JSI already landed on master. See the series of commits ending with facebook/react-native@8427f64

The biggest concerns I have seen in RN today are:

  • large list
  • Navigation
  • Android overflow in hybrid apps
  • lazy bundle loading to improve boot time
  • Debugging code in app runtime

I see other speakers including @axe-fb Ram talking about the Fabric to help enable navigation and large lists. How will the other three work in Fabric?

(updated first comment with Shergin's tweet about View Flattening)

large list & Navigation

Please see @shergin's comment here #4 (comment) - Fabric enables solutions for these problems, but the Fabric project doesn't include the solutions.

Android overflow in hybrid apps, lazy bundle loading to improve boot time, Debugging code in app runtime

These are not related to Fabric project.

Android overflow: see facebook/react-native@b81c8b5
I had seen this commit but will this enable me to render something outside the bounds of the reactroot view?

I'm really excited about Fabric. Thanks for the core team making that happened.

But still, does the Fabric fixes the most annoying part of React Native – layout animation, i.e. width/height animations which cannot be started using useNativeDriver option. I didn't find any information about that.

can't wait for Fabric πŸš€

@terrysahaidak The role and concrete implementation of the native driver in Fabric is still not clear. We hope that Fabric’s sync nature can enable new approaches to solve those problems more efficiently.

Does this mean C++ native modules will become a first class, documented citizen of the RN universe? That would be awesome, I’m doing a lot of work in this area and most of it had to be figured out by reverse engineering/trial and error :) Sounds exciting anyway, thanks for the information!

msand commented

I'm thinking that ideally, with the new fabric rewrite of react-native, we would generate a native svg rendering library interface (c++, js, ts, flow) from the WebIDL spec of svg 2.0 to cover the entire api (using something like https://github.com/Microsoft/TSJS-lib-generator and https://github.com/motiz88/webidl-to-flow), use rust implementations for processing (https://github.com/RazrFalcon/resvg) and rasterizing it (https://github.com/pcwalton/pathfinder or https://github.com/nical/lyon).

Then make a small wrapper with java + objective-c glue to attach to the view hierarchy and hit testing / gesture responder / event system, such that it can be used from react-native, (and perhaps c#, kotlin, dart, python, ruby, julia, r etc. to get more platforms) as well as any other native environment, with a single cross-platform, efficient, memory and thread safe implementation. Having the WebIDL specified api would allow much of the existing js which runs against svg implementations in e.g. browsers to work almost straight away. And, give a nice escape hatch around the async bridge and vdom diffing.

I think it would make sense to name this something else than react-native-svg, that could still live on with its java and obj-c implementations at least as a baseline for perf benchmarks, as this is more cross-platform. This would be more of an embeddable svg engine, mirroring the full svg related subset of js apis available in browsers, which can be embedded when you need svg rendering and want to interact with it from e.g. a javascript environment, but a full webview/browser would be overkill.

Also, I think for the next gen native animation driver, it would be ideal to get rid of heap allocations and autoboxing from the property updates. As this can be kind of the inner loop of certain animations, it should avoid causing any garbage collection as far as possible, as that can make jitter free 60fps hard to achieve.

Does this mean C++ native modules will become a first class, documented citizen of the RN universe?

This has nothing to do with Fabric. It will be covered in #40

@msand Sounds amazing!

First of all, I m really excited about fabric.

But I have some questions on my mind about this.
Would the existing React-Native Apps (RN 0.56) be able to upgrade to this new RN Fabric?
if yes then,
Would there be any breaking changes to our apps?
What could be Pros and Cons of migrating our existing apps to new React-Native Fabric?

I have a question. How will we know that fabric is ready? I'm following this thread, but I keep on asking myself, where are we right now?
Can I start writing code using the new re-architecture?

This tweet from Krzysztof should give you a glimpse of fabric: https://twitter.com/kzzzf/status/1064891715457294337

@SudoPlz

How will we know that fabric is ready?

It will be properly communicated.

where are we right now?

The FB team is working on the various aspects of JSI/TurboModules/Fabric, and while doing so they are doing small tests internally.

Can I start writing code using the new re-architecture?

There are some parts of the new implementation already in master of OSS, but I highly recommend that you don't dip your toe into it for now.

If I would have to give you a rough estimate, I would say that you should not expect Fabric to be "out in the wild" in a React Native OSS release for at least a couple more months. And, again, proper communication about it will happen as the situation keeps evolving 😊

Will RN core consider officially supporting more platforms (eg: desktop) once Fabric is released?

@aleclarson, It depends what you mean by officially supporting more platforms. Facebook has no plans to maintain a React Native Windows library for example. In fact, I don't think you would want this, Microsoft is much better suited at maintaining such a thing.

However, with Fabric, more of React Native will be implemented in cross platform C++, enabling other platforms to reuse more of the behavior from core. I believe the group at Microsoft is already thinking about how much they can reuse from Fabric's C++ core.

Background

My story with react-native today goes something like this:

I started working on a side project as a web developer, at first everything seemed very straight forward and there were no major differences from normal react workflow.

I then stumbled upon few hurdles when I needed to use third party native libraries / upgrade react-native. This led me to remove as many of third party libs as I can and deep dive into writing my own custom modules so I can update them faster. To write these efficiently I had to spend few weeks learning quirks of iOS / Android and react native bridging, as well as lvl up my ObjC and Java skills.
After a while I was able to write few bridges for native sdk integrations / camera / gyroscope. It took a long while.

Question

While reading this thread I got excited about fabric, but still don't think like I fully understand it. General concept is grasped and difference with bridge architecture is clear.

But what are differences in dev experience for those of us who decide to write custom native modules / contribute back to react native?

@iljadaderko If you custom native module is not UI-related (not a custom view component), Fabric will not affect developer experience here (but TurboModules might).
If are talking about some custom view component, you will probably need to refactor your native component to adopt new APIs (understanding of C++ is NOT required). Those changes should be pretty trivial for most components.

  1. Is Fabric going to require any changes in how the JavaScript/JSX code is written?
  2. Is it going to be a breaking change in any way?

@rapPayne the answer to both your question is that ideally it's going to be a smooth transition. But when we are closer to release it will probably become more clear.

I have read changelog abount 0.58.0, but there's no mention about new jsi or fabric. However in this issue thread, someone said new JSI was already on master. Does 0.58.0 have new JSI(Fabric)?

@dulmandakh
I understand that original RN bridge is asynchronous so that it causes some problems like flickering long flatlist rendering, but new JSI will use sync bridge and will solve many problems, improve performance, and reduce memory usage.

JSI is in, but not JSC and Fabric.

Does it means new JSI is in 0.58 but still does problems still exists?

IIRC, JSI is small part of the new architecture. Now RN developers working on Fabric to make UI non-async.

@dulmandakh
Ok. Thank you for your quick response.

Will JSI make it more straightforward to write native modules in Swift, or will we still have to write an Objective-C bridge?

Is there any progress for Frabic?
When can we try it? @kelset @shergin
Thanks.

@rhysforyou I think you should take a look at the TurboModules

@jimzhao2012 as we said times and times again, there will be proper communication once it's usable. Progress is constant and you can check the commit history on master to keep an eye on what's happening.

@kelset Thanks for the great work. It would be nice if there is seperate traction on just the fabric.

Will it be Possible to Load RCTRootView Content Synchronously in Fabric?

There’s a technical issue with React Native that affects navigation libraries using the underlying native API on iOS. I’m hoping that Fabric will solve the problem.

The problem arises when you try to write React components that change the appearance of the navigation bar. For example, I’m writing a component that adds a search bar to the navigation bar. In the native view I create a UISearchController and assign it to the navigationItem of the new UIViewController. But when I add the component to a scene, the search bar doesn’t show up.

//SearchBarView.m

- (void)didMoveToWindow
{
    [super didMoveToWindow];
    ...
    [self.reactViewController.navigationItem setSearchController:...];
}

iOS expects all changes to the navigation bar to be made during the view-loading phase. Changes made after this (while animating to the new UIViewController) don’t appear. Because of React Native’s asynchronous nature, the view content isn’t created in the view-loading phase and so the didMoveToWindow of the SearchBarView fires too late to make changes to the navigation bar.

Will it be possible in React Native Fabric to load the initial rendered content synchronously, i.e., will the init of the RCTRootView include the rendered content?

- (void)loadView
{
    …
    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:...];
    self.view = rootView;
}

Will it be Possible to Load RCTRootView Content Synchronously in Fabric?

Use RCTSurface for iOS, it works today with/without Fabric. Android version is still on the work.

@fkgozali is there ANY example anywhere on the web as to how to use the RCTSurfaceView?
I can't for the life of me figure how to use that.

Thank you

Try something like:

RCTSurface *const surface = [[RCTSurface alloc] initWithBridge:bridge
                                                    moduleName:@"MyModule"
                                             initialProperties:properties];
[surface start];

CGSize minimumSize = (CGSize){0, 0};
CGSize maximumSize = (CGSize){screenSize.width, CGFLOAT_MAX};
[surface setMinimumSize:minimumSize maximumSize:maximumSize];

// synchronously mount
BOOL wasRenderedWithoutTimeout = [surface synchronouslyWaitForStage:RCTSurfaceStageSurfaceDidInitialMounting timeout:timeout];

UIView *theView = surface.view;

@fkgozali Thank you so much for sharing that code.
Is the hard work taking place as soon as [surface synchronouslyWaitForStage:RCTSurfaceStageSurfaceDidInitialMounting... runs (if timeout is 0) ?

@fkgozali Thanks for the RCTSurface suggestion. I wrestled with it and, although I couldn't get it working, it helped me think about my problem in a different way

@jimzhao2012 as we said times and times again, there will be proper communication once it's usable. Progress is constant and you can check the commit history on master to keep an eye on what's happening.

I sense some irritation in this reply. As an outsider that read about Fabric more than a year ago, at this point I have no clue about the timelines. Is there any way to guide expectations about when it will be released given the current pace of development and priority at Facebook? Can we expect Fabric to drop in a few months, a year or more than a year from now?

This rough estimation would help a lot of people I think because a lot of us run into limitations and/or performance issues with react-native, that might be much better addressable with Fabric. If it's not too far out we can defer, but if it still takes a long time before Fabric ships, it might be better to migrate parts of the interface to native.

@jfrolich You don't ask Apple what will be in iOS 15, do you? This is open source hence you can see what they are working on it, if you check the commit history. Once they are ready, they will document it and you will have enough time to upgrade your app/library to use Fabric.

@markhomoki Missing the point. Also, as a matter of fact I have in the past asked apple what's next because of requirements on new features (partner preparations). They were extremely punctual.

This is about knowing what the timeline "more or less" is. Which is okay to ask.

I would agree with your message if it were a demand. But this is a reasonable request for a very rough estimation to help make decisions.

@jfrolich i am following Fabric related discussions in commit etc a lot and i feel that it will be fully completed at the end of 2019 and it will be GA in the first quarter of 2020.

DomiR commented

@jfrolich According to the comments from blog.nparashuram "most of the code is already in OSS"

First post here also states that there is a working example using early stage Fabric already.

They are repeatedly saying that they are not going to tell us any dates and I would guess here is the first place they will tell us 🀞(whenever it is usable). On the other hand I've heard several times that they would like to release later this year, but I guess nobody can plan with that. I would love a is-fabric-ready-yet page Γ  la (isfiberreadyyet.com) though, as there is no clear communication on what/how much exaclty is missing πŸ˜‹

Hey everyone! I encourage everyone to step away from this conversation for a bit, relax and calm down. We know that people are incredibly excited about the future of React Native. We are too! It's easy to get into heated conversations because of all of our passion but it doesn't help us move forward productively.

While I have no news right at this moment, Fabric is being developed and tested heavily internally at Facebook and we will share more news as soon as we have them. I would recommend you not to make any decisions based on Fabric for your applications just now and instead suggest exhausting all the other options you can consider to improve your app. If you are having specific performance problems, chances are that Fabric won't magically solve them and instead there may be other things you can do.

the latest version 0.60.0-rc3, is missing this file : https://raw.githubusercontent.com/facebook/react-native/master/scripts/generate-rncore.sh
so unless i am wrong, you have no chance to set it up from the latest RC release.
For those interested, building the fabric requires these lines to be added to the Podfile :

pod 'React-RCTFabric', :path => '../node_modules/react-native/React'
pod 'React-Fabric', :path => '../node_modules/react-native/ReactCommon'
pod 'React-graphics', :path => '../node_modules/react-native/ReactCommon/fabric/graphics'

any idea how I can use the trunk. what should I add in package.json instead of
"dependencies": {
"react": "16.8.6",
"react-native": "0.60.0-rc.3"
}

?
thanks

the latest version 0.60.0-rc3

The latest version is 0.60 released yesterday! 😎

oh didn't notice that! thanks
do we still need the 3 lines I pasted above to set up the fabric?

I configured it the same and i still have same error with 0.60 released yesterday
[!] Failed to load 'React-Fabric' podspec:
[!] Invalid React-Fabric.podspec file: No such file or directory @ rb_sysopen - ../scripts/generate-rncore.sh.

the file is in the git trunk though, how can it be missing in 0.60?

@windev92 it looks like the file hasn't been added to package.json: https://github.com/facebook/react-native/blob/0.60-stable/package.json

I guess for now you could just copy it manually into node_modules/scripts

already tried. the script itself contains yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js command that fails
it needed a yarn add flow-node before and it then gives this error :
node_modules/.bin/flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js
internal/modules/cjs/loader.js:583
throw err;
^

Error: Cannot find module '/works/myproj0_60/packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js'

not really nice. Is there anyone who can explain how it works? I am kinda really close to build the whole stuff.
If I comment the line in podspec that runs the script, pod install command completes successfully but Fabric project doesn't build.

I advanced a bit more on it,
this flow-node I think is supposed to install these rncore headers from "somewhere".
#include <react/components/rncore/EventEmitters.h>
#include <react/components/rncore/Props.h>

I couldn't find a trace of these files in the git react-native trunk repo, and nowhere in google.
they respectively define the classes SliderEventEmitter and SliderProp.
Any idea where to find these files? @fkgozali .

I would like to try the code you pasted above :

RCTSurface *const surface = [[RCTSurface alloc] initWithBridge:bridge
                                                    moduleName:@"MyModule"
                                             initialProperties:properties];
[surface start];

CGSize minimumSize = (CGSize){0, 0};
CGSize maximumSize = (CGSize){screenSize.width, CGFLOAT_MAX};
[surface setMinimumSize:minimumSize maximumSize:maximumSize];

// synchronously mount
BOOL wasRenderedWithoutTimeout = [surface synchronouslyWaitForStage:RCTSurfaceStageSurfaceDidInitialMounting timeout:timeout];

UIView *theView = surface.view;

@windev92 Those files should be generated while you install pods with fabric enabled.

thanks for your reply. they are not generated. I have now tried RNTester from git with configuration :
use_react_native!(path: "..", turbo_modules_enabled: true, fabric_enabled: true) and it doesn't generate the headers as expected. cf readme.md
it fails to build at this level.
#import <react/components/modal/ModalHostViewComponentDescriptor.h>

Could you please give a try with the official instructions in readme.md pasted below? It takes 2 minutes to try.
I don't have a script error anymore, during pod install, but fails to build

RNTester

The RNTester showcases React Native views and modules.

Running this app

Before running the app, make sure you ran:

git clone https://github.com/facebook/react-native.git
cd react-native
npm install

Running on iOS

Both macOS and Xcode are required.

  • Install CocoaPods. We installing CocoaPods using Homebrew: brew install cocoapods
  • Run cd RNTester; pod install
  • Open the generated RNTesterPods.xcworkspace. This is not checked in, as it is generated by CocoaPods. Do not open RNTesterPods.xcodeproj directly.

@windev92 Can you try those steps: clone react-native repo -> npm/yarn install -> uncomment fabric pods in RNTester podfile -> pod install. I remember when I tried it last time, the files were generated only when I run pod install for the first time, maybe that's the issue.

I just spotted the files are generated with my setup but not added to the search paths. gonna try to understand why it doesn't build. Have you had a chance to build with fabric, using instructions from readme.md? the podfile has no fabric by default, you need to add it yourself.
with fabric commented out, all builds flawless, but i don't think the rncore files are used. (gonna double check now)

update : the 2 first don't build, but the 2 last(rncore) are properly included. it has to do with modal headers not in search paths somehow.

#import <react/components/modal/ModalHostViewComponentDescriptor.h>
#import <react/components/modal/ModalHostViewState.h>

#import <react/components/rncore/EventEmitters.h>
#import <react/components/rncore/Props.h>

the 2 modal files are present in the filesystem but are not symlinked in RNTester/ios/Pods/Headers/Public(or Private)/React-Fabric/react/components/modal
where they are expected to sit.
added the symlink manually and got linking error => added the modal cpps to the React-Fabric target and minor headers not found build errors (but files exist). Got it to build but app crashes in
YGFloatOptional YGNode::getLeadingPadding() following the Scheduler::startSurface(), more exactly the uiManagerBinding_->startSurface() executed in the uiManagerBinding_->startSurface queued but the runtimeExecutor

@windev92 Fabric is somewhere nearby. I followed your instructions, with some build script tinkering I was able to build RNTester.

I noticed, that not all turbomodules was codegened, so i changed scripts/generate-rncore.sh a little bit to build all available Turbomodules.
And after some xcode project modifications - wolia it compiles.

{ find "$PWD/../Libraries" -name "*NativeComponent.js" -print; find "$PWD/../Libraries" -name "Native*.js" -print;}| xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore.json
yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore.json rncore ReactCommon/fabric/components/rncore FBReactNativeTestSpec

Video

We can see that not all components yet implemented. For example SafeView, that blocks back button.

@michbil would it be too much to ask for a short medium how to article whenever you get some free time?

I analyzed all hacks I made, and fixed Podfiles, so everyone can build fabric by himself. Here is diff attached.
Diff to build Fabric yourself
Currently RCTImageLoader not supported, I assume because of CoreModules not yet included. If you get yellowbox error, just dissmiss it.

@windev92 Fabric is somewhere nearby. I followed your instructions, with some build script tinkering I was able to build RNTester.

I noticed, that not all turbomodules was codegened, so i changed scripts/generate-rncore.sh a little bit to build all available Turbomodules.
And after some xcode project modifications - wolia it compiles.

{ find "$PWD/../Libraries" -name "*NativeComponent.js" -print; find "$PWD/../Libraries" -name "Native*.js" -print;}| xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore.json
yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore.json rncore ReactCommon/fabric/components/rncore FBReactNativeTestSpec

Video

We can see that not all components yet implemented. For example SafeView, that blocks back button.

Nice!

Previous version of scripts/generate-rncore.sh was not entirely correct, it placed codegen artifacts in wrong folders. More correct is this one:

find "$PWD/../Libraries" -name "*NativeComponent.js" -print | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore.json
yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore.json rncore ReactCommon/fabric/components/rncore FBReactNativeSpec

find "$PWD/../Libraries" -name "Native*.js" -print | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore-modules.json
yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore-modules.json rncore ReactCommon/fabric/modules/rncore FBReactNativeSpec

It places codegened code where developer intended it to be :)

@SudoPlz I will try to find some time for it, but can not promise.

msand commented

@michbil Great, seems to be working quite well. Might be possible to start prototyping a rewrite of react-native-svg now.

@michbil thanks for the Diff. After applying it, I get the following when building the RNTester app (on xcode 11.1). Am I missing a step?

'cstddef' file not found

@michbil thanks for the diff for how to build Fabric ourselves.
I followed your changes and had to create generate-rncore.sh script, but when running pod install.

But when it executes the generate-rncore.sh script I'm getting the following error:

[!] /bin/bash -c 
set -e
#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
#
# This script collects the "core" component schemas used by fabric
# then uses react-native-codegen to generate the component headers
# to a location that the podspecs expect.

# shellcheck disable=SC2038

find "$PWD/../Libraries" -name "*NativeComponent.js" -print | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore.json
yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore.json rncore ReactCommon/fabric/components/rncore FBReactNativeSpec

find "$PWD/../Libraries" -name "Native*.js" -print | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore-modules.json
yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore-modules.json rncore ReactCommon/fabric/modules/rncore FBReactNativeSpec

yarn run v1.19.0
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
find: /Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-eaf9e/../Libraries: No such file or directory
error Command "flow-node" not found.

If I remove yarn from the script before flow-node the error that I get is:

find "$PWD/../Libraries" -name "*NativeComponent.js" -print | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore.json
flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore.json rncore ReactCommon/fabric/components/rncore FBReactNativeSpec

find "$PWD/../Libraries" -name "Native*.js" -print | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js schema-rncore-modules.json
flow-node packages/react-native-codegen/buck_tests/generate-tests.js schema-rncore-modules.json rncore ReactCommon/fabric/modules/rncore FBReactNativeSpec

find: /Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/../Libraries: No such file or directory
internal/modules/cjs/loader.js:783
    throw err;
    ^

Error: Cannot find module 'nullthrows'
Require stack:
- /Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js
- /Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/src/generators/RNCodegen.js
- /Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/buck_tests/generate-tests.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:780:15)
    at Function.Module._load (internal/modules/cjs/loader.js:685:27)
    at Module.require (internal/modules/cjs/loader.js:838:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js:13:20)
    at Module._compile (internal/modules/cjs/loader.js:945:30)
    at Module._compile (/usr/local/lib/node_modules/flow-remove-types/node_modules/pirates/lib/index.js:91:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:962:10)
    at Object.newLoader [as .js] (/usr/local/lib/node_modules/flow-remove-types/node_modules/pirates/lib/index.js:96:7)
    at Module.load (internal/modules/cjs/loader.js:798:32) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js',
    '/Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/src/generators/RNCodegen.js',
    '/Users/myuser/Library/Caches/CocoaPods/Pods/External/React-Fabric/00f12b300dc83f8f5aecf88d084b45e1-1dec8/packages/react-native-codegen/buck_tests/generate-tests.js'
  ]
}

What did I do wrong?

@Frakcool @tachtevrenidis My diff is not working with latest master. I will try to find some time, and make it build again.

@michbil this worked for me thanks!

@michbil I will need to create the packages folder and the file inside, am I right? Because I have no GenerateModuleCpp.js in my node_modules for react-native.

Now, for some reason I'm also getting:

[!] Invalid `Podfile` file: undefined method `use_react_native!' for #<Pod::Podfile:0x00007ffcc9130498>.

After a pod install

@michbil I will need to create the packages folder and the file inside, am I right? Because I have no GenerateModuleCpp.js in my node_modules for react-native.

No, packages folder should stay intact. Maybe you corrupted packages by accident. All codegened artifacts are placed under ReactCommon/fabric/components/rncore

Now, for some reason I'm also getting:

[!] Invalid `Podfile` file: undefined method `use_react_native!' for #<Pod::Podfile:0x00007ffcc9130498>.

After a pod install

I would recommend you start with fresh installation of react-native, and then apply patch.