
Why Discord Is Sticking with React Native - jhgg
https://blog.discordapp.com/why-discord-is-sticking-with-react-native-ccc34be0d427
======
saagarjha
> In the React Native repo, we sometimes see hot issues with limited activity
> in response from Facebook. Lack of visibility into such a large company can
> bring about frustrations when so many people depend on their open source
> contributions. On the other hand, it forces us to dive into the core
> codebase in order to figure out the problem, which admittedly one of the
> best ways to learn an open source platform. By understanding the React
> Native platform deeply, we were able to maintain a fork that fixes issues
> for our own use cases and reuse their core modules.

I guess that's one way to sugarcoat the fact that you're at the mercy of
Facebook being timely in fixing bugs here…

~~~
nikanj
They are not at the mercy of Facebook at all. They have access to all of the
source, and all the build tools too.

People don't remember what it's like, praying to dear gods that Microsoft
patches that IIS bug before you lose your last customers.

~~~
giancarlostoro
This right here. I hope companies stop fearing contributing to React / React
Native (and ANY open source project they rely enough on). I think companies
that make plenty of revenue off of certain open source projects should invest
resources into said projects. If you patched some part of the project,
contribute it back! It will only benefit you in the long run instead of
running frankenforks of the code, and ultimately if it gets abandoned, offer
to continue to maintain it!

I wish more companies would give developers about 10% of their time to develop
things they think would benefit the company, whether it's internal tools or
open source projects they rely on (or building new things). Just give devs
every Friday or every other Friday with free reign to code or learn new
things.

Ah well... If the projects they rely on stop being maintained they just suck
it up and let it foster eternally till forced to migrate.

Dear Discord:

Your bread and butter seems to rely upon React / React Native. It's an open
source project, pay your employees to contribute to it!

~~~
victoriasun
Hi! I'm from Discord and we _do_ contribute to React/React Native! I have to
say it's quite an adventure to dig through React Native's issue tracker only
to find that your CTO's PR has been merged :P

~~~
giancarlostoro
That's good to know, thanks for the context, didn't mean to assume just wasn't
sure, been so busy at work today so hadn't read the whole article yet. That
does sound pretty awesome! I hope more companies do contributions like you
guys do. Facebook kickstarted the project, doesn't mean they will run it
forever, eventually the torch must be carried by the community.

~~~
victoriasun
No worries! We actually didn't highlight it in the post :P I just find it such
a cool fun fact that I wish we talked about it more.

------
ryanjodonnell
I predict there will be another blog post in about 18 months from discord
about "Why we moved away from React Native"

~~~
mrkcsc
Well it’s been three years so far - we shall see :P

I know this comment is a joke but in all seriousness even if we did move away
I think it would still mean we got several years of great utility out of the
framework.

No tech lasts forever and it’s important to be open to change as well as being
mindful to not chase the latest trend - as in all things, balance is key.

------
mrkcsc
Hi all, Discord engineer here! If anyone has any questions about the post or
our experience using React/React Native the team would be happy to answer
them!

~~~
jamesgeck0
The post says, "it’s roughly 1.5s startup delay to load a 15mb bundle on an
iPhone X."

I've seen startup latency much slower than that on my iPhone SE. In the best
case, the application takes about six seconds to cold boot when I tap on a
notification. Sometimes it's closer to fifteen or twenty seconds if the app
sits on the "connecting" screen for a while. It's difficult to understate how
much slower the app feels than everything else on my phone.

~~~
nikanj
The X is the most expensive iPhone you can buy right now, and the SE is the
cheapest. Too bad engineers practically always have the top-end models, so
they don't really have to dogfood the everyday pain of using the slower
devices.

~~~
victoriasun
Actually I don't own an iPhone X :P Our core user base tends to use 6 and
above (approx 2 generations behind) and we dogfood regularly with a huge group
of beta testers (thousands) with a huge range of hardware. We try our best to
make sure the average use case is considered.

~~~
Dylan16807
Considering the average is good but it still pushes the performance treadmill
forward.

If we had some magical way to make the dev treadmill run slower than the user
treadmill, we'd see better architectures in many cases. In that alternate
world it would be easy to precompile the javascript and load 20 times faster.

------
nacho2sweet
I quit Facebook lately and moved to Discord for my group chats, cause we
already had the channels from gaming.

It is good, but we all have trouble with the notifications. (this has nothing
to do with react native but you are here and this is a gripe). Like if you
have it running on a computer it doesn't come to your phone. So we have tons
of miss-communication for stuff like "yo I am drinking near your house meet-
up". Discord just sits running all the time on your PC, which for most is
running all the time. So I stopped using it for time sensitive messages which
sucks. I would never dare use it for a "Hey I am buzzing outside your house
answer". You literally have no idea where the notification for the person is
going to go. FB-Messenger never had this issue.

~~~
brightball
Basically just needs idle tracking.

~~~
Klover
It does have that. No idea why it wouldn't work for GP. If I lock my computer,
or don't look at the Discord tab for a few minutes, my phone gets
notifications.

~~~
Kratisto
Just to add my experience, I feel like it's hit or miss. It seems like I get
notifications with zero issues. Then I'll randomly have a week or two in a row
where I don't get notifications or get 50% of them. Not sure why this happens,
but I use Discord as my only means of contact with multiple people.

~~~
Klover
Interesting. For what it's worth I am using Discord on Mac Safari (not TP),
Win Chrome 69 (dev channel), and iOS. In one year I have not had any of the
issues mentioned above. Perhaps using the desktop app can introduce problems.

~~~
nacho2sweet
Yeah it just doesn't work well for me or my friends we are always complaining.
I don't know why and I don't really want to have nerd out with my chat app
(just want it to work!).

As for using Slack, I am too scared of dropping 3am Friday/Saturday messages
in my work chat instead of my group chat so keep separate apps.

------
Ologn
The usual idea I hear is that React Native might be a good idea for a small
company with an uncomplicated app, especially if they use the React stack on
the web.

However when one grows and starts competing head to head in the App Store or
Google Play with the other top social or finance or music or whatever apps,
the ones who have expert teams with familiarity with the specific Android or
iOS platform will pull ahead. Particularly as you can still have a (mostly)
common REST API backend, base things off the same design mockups with some
modifications, and so on.

~~~
victoriasun
Discord is actually an extremely complex app and run almost entirely off React
Native, with 2 engineers, only 1 of which who is an iOS expert :P! We have
millions of users, and we typically rank in the top 10 of Social Networking on
the iOS App Store. We are excited to share our success story of being a "big"
company using such a product.

~~~
jrumbut
I was very surprised to hear discord used RN because I found that I had to
break down and use native code to deal with a lot of multimedia and a few
other things that aren't just displaying text. I still loved RN, I just maybe
naively hoped I could do everything with it.

Is that your experience too, that a good bit of native code is required (with
RN serving as glue and handling simple screens), or have you avoided that
somehow?

~~~
victoriasun
Personally I have found that RN does require some amount of native platform
knowledge to be successful. However, the bulk of our app is actually in React
Native. The times we've had to bridge into native is mostly around our voice
modules or things that, in RN, were not very performant (like poor list
performance) or required synchronous updates (like the keyboard problem
mentioned in the post). Certain multimedia objects RN doesn't support out of
the box but the community has come to the rescue (ie:
[https://github.com/cornedor/react-native-video-
player](https://github.com/cornedor/react-native-video-player) for video).

~~~
QualityReboot
I agree with all of this, but I'd add that bridging RN to Native is not as
scary as it sounds.

Check out the code examples: [https://facebook.github.io/react-
native/docs/native-modules-...](https://facebook.github.io/react-
native/docs/native-modules-ios)

In practice, most of it is wrapping "RCT_EXPORT_METHOD" around native code and
importing it into JS.

Even if you had to write half the app in native code (which you won't), you're
still far ahead of having to write it all in native code on both platforms.

~~~
laex
Agreed. Creating bridging modules aren't that complicated. For anyone
interested, I've linked a sample of a bridging module from my open-source
project, for both IOS and Android. See [0] & [1]

The bridge creates an interface between an embedded webserver to react native.

Things to note:

1\. Always dispatch bridging methods to their own threads. On IOS you can do
this via. dispatch_async. On Android, you can utilise native threads or some
kind of task management library. I like Bolts [2].

2\. Always create bridging methods that resolve promises. This makes it easy
to utilise async / await paradigm on the JS side.

[0] Android: [https://github.com/hemantasapkota/react-native-web-
server/tr...](https://github.com/hemantasapkota/react-native-web-
server/tree/master/android/app/src/main/java/com/reactnativewebserver/AppWebServer)

[1] IOS: [https://github.com/hemantasapkota/react-native-web-
server/tr...](https://github.com/hemantasapkota/react-native-web-
server/tree/master/ios/ReactNativeWebServer/AppWebServer)

[2] Bolts: [https://github.com/BoltsFramework/Bolts-
Android](https://github.com/BoltsFramework/Bolts-Android)

------
sandGorgon
Love discord..but their email notifications are a problem. There are no fine
grained controls and once unsubscribed, you can never re-subscribe.

Would have loved to use discord at work, but in developing countries...
network connectivity is not always a given.

------
joeblau
This post is interesting because at the bottom, Discord is soliciting for
engineers. Gabriel Peal from AirBnB came and gave a talk at our company a few
weeks ago and he shared at after AirBnB published their 5 part medium
series[1], they got a huge flood of mobile developer resumes.

[1] - [https://medium.com/airbnb-engineering/sunsetting-react-
nativ...](https://medium.com/airbnb-engineering/sunsetting-react-
native-1868ba28e30a)

~~~
hamms
I feel like it's far more unusual to see a blog post from a tech company that
_doesn't_ end with them soliciting for engineers.

~~~
joeblau
Yeah. I guess my point is that they are trying to get web/mobile engineers,
but the data from AirBnB shows that the opposite of this post is what
_actually_ attracts mobile engineers.

~~~
mathw
What AirBnB showed is that there are a load of mobile engineers out there who
don't want to work with React Native.

What Discord might show is that there are also a load of mobile engineers out
there who do.

Personally I find it baffling why anybody would choose to work with anything
based on JavaScript (I'm grumpy enough about having to work with something as
primitive and loosely-typed as C#, so I find JavaScript an endless horror
show), but there are people sitting right near me in my office who work on
frontend web code all day and chose to do that and actually enjoy it.

So really, I guess I'm saying we're all different. And that's a good thing,
because there are lots of different jobs we need to get done to keep all these
systems running.

------
haney
What tool/service/library are you using for OTA updates? Could you share any
best practices around managing the roll out (do you push to everyone, a
subset, etc.)?

~~~
victoriasun
Hi! Not Fanghao but another Discord iOS engineer. We wrote our own library for
OTA updates but React Native Code Push ([https://github.com/Microsoft/react-
native-code-push](https://github.com/Microsoft/react-native-code-push)) is a
pretty reasonable out of the box solution. Because our OTA solution is
designed for hotfixing issues rather than feature releases we push to
everyone, and we also have a flag that forces our users to relaunch the app if
the bug is app breaking.

~~~
saagarjha
How do you comply with Apple's App Store Review Guidelines when using this
(specifically, this clause):

2.5.2 Apps should be self-contained in their bundles, and may not read or
write data outside the designated container area, nor may they download,
install, or execute code which introduces or changes features or functionality
of the app, including other apps.

Also,

> we also have a flag that forces our users to relaunch the app if the bug is
> app breaking

How do you do this?

~~~
victoriasun
Apple allows updates to Javascript outside of the review process as long as it
subscribes to certain guidelines (1), including but not limited to: not
changing core feature functionality, being limited to bug fixes, and also that
the app doesn't provide unlimited access to native SDK or system functions.
React Native provides a limited API to js code so it's fine.

As far as your second question, we simply deploy store logic that loads a
Modal telling our users that they must relaunch the app.

[1] [https://microsoft.github.io/code-
push/faq/index.html#1-does-...](https://microsoft.github.io/code-
push/faq/index.html#1-does-the-apple-app-store-allow-developers-to-perform-
these-types-of-updates)

~~~
saagarjha
How do you convey "relaunch the app" to your users? I'm sure many of them
think that pressing the home button is the same as killing your app.

~~~
victoriasun
Since OTA updates can _only_ impact JS, we can offer a button that essentially
calls something like `window.refresh` and it reloads the JS bundle within the
container. We actually recently leveraged ErrorBoundaries in React 16 to do
something similar in our app as well.

------
babaganoosh89
For comparison how many engineers does it take to make the native Android app?

~~~
mrkcsc
The core Android team is four engineers so about double in size.

This makes some sense since on Android we have to re-write most of the
stores/business logic and not just UI. We have modeled the architecture
similarly to things on the Desktop/iOS side so we still are able to move fast
and stay lean as a team.

~~~
Klathmon
Can you expand/clarify on what you mean by "on Android we have to re-write
most of the stores/business logic and not just UI"?

~~~
mrkcsc
The iOS application can safely pull data and perform actions from just about
every Store (we don't use redux but the idea is the same
[https://redux.js.org/api-reference/store](https://redux.js.org/api-
reference/store)) and Action Handler ([https://reactjs.org/docs/handling-
events.html](https://reactjs.org/docs/handling-events.html)) that exists in
the main Discord React application.

So if one is writing a feature that say allows one to ban a user - they don't
need to write any of the banning logic or worry about fetching the user
data/validating it against server roles permissions - if it exists on the main
Discord app, it can be safely imported.

Other helpful examples are perhaps things like markdown parsing - iOS was able
to just import and use the exact same system desktop uses to handle markdown
and things like user/channel mentions, custom emoji, etc. On Android we had to
write one ourselves: [https://blog.discordapp.com/how-discord-renders-rich-
message...](https://blog.discordapp.com/how-discord-renders-rich-messages-on-
the-android-app-67b0e5d56fbe)

On Android since there is no code re-use everything had to be written from
scratch.

~~~
Klathmon
Oh, I missed that the Android version isn't React Native.

------
mhartl
_The Discord iOS app has millions of daily active users and 4.8 stars with
over 240k ratings. This has all been accomplished with a team of two
engineers!_

This is impressive.

------
oh-kumudo
> small and mighty team

Says it all. It is all about cost.

~~~
mrkcsc
It's not about cost, it's about impact.

The team - myself included - works normal eight hour days and there is no
"crunch time" (other than very rarely when we have external dependencies like
when we launched our Spotify integration).

As an engineer we all want to have agency and be able to make impactful
decision on the products we work on. Over-hiring too quickly is often what can
lead to organizational bloat and can make things get built _slower_.

Instead, I think it's better to grow slowly, hire great people, and only hire
when it's needed. I've found that as a company, staying small has made us
always ask ourselves to make tradeoffs and constantly be thinking about what
are the most important and impactful things we can be working on.

~~~
oh-kumudo
Well, keeping a small team is a choice, and the technology decision follows.
What works for you guys works.

I am not debating whether it is a good one or bad one.

~~~
mrkcsc
Thats true, I appreciate the discussion and the clarification.

------
driverdan
RE Android, are you saying that React Native Android is still bad? If so, why
hasn't it been improved?

~~~
mrkcsc
It's less that it's bad (in my opinion) and more that on Android you have a
_much_ wider range of hardware to support ranging from quite new and recent,
to basically ancient almost flip phone level.

I am hoping that in the future something like React Fiber
([https://www.youtube.com/watch?v=aV1271hd9ew](https://www.youtube.com/watch?v=aV1271hd9ew))
will make its way to React Native and unlock a new level of performance.

------
KirinDave
I wonder if, one day, Discord will get around to fixing the fact that once you
have more than 3 channels and get a notification in more than one, your mobile
notifications do not go to "newest" they go to the "channel highest on the
sidebar".

This is why I really hate tools like react native. They try and create a code
symmetry and that's not unreasonable, but then they go too far and create
behavioral symmetry and that's pretty much unacceptable for as wide a gulf as
browser apps and mobile apps. They have such radically different use cases.

~~~
victoriasun
Actually, behavioral symmetry is not an issue with React Native so much as its
an issue with poor UX design. Nothing about RN mandates that the apps behave
similarly. That the iOS app and the desktop app look and behave similarly is
simply a design choice made by the team to maintain a consistent look/feel/UX
across the apps, not RN itself. We do not share Views. All Views across all
the apps are custom.

However, as Discord's mobile teams grow and expand we're exploring alternative
UX designs that are significantly more mobile friendly. So your feedback is
heard loud and clear at HQ :)

~~~
KirinDave
> Actually, behavioral symmetry is not an issue with React Native so much as
> its an issue with poor UX design. Nothing about RN mandates that the apps
> behave similarly.

I think the economics of RN strongly do though. Why would you use RN if you
aren't planning to reuse code between environments?

~~~
victoriasun
We do reuse code. To be clear, a traditional "React app" typically consists of
these pieces:

\+ view/UI layer

\+ flux/redux stores

\+ data fetching and processing

\+ action creators

\+ utility libraries (date functions, markdown processor, etc)

The economics of RN allows us to share the last 4. However, sharing the first
is actually more or less impossible without tooling like react-native-web as
the components that exist on a native iOS app and the components that exist in
HTML are just different. Certainly you can argue that sharing this much
business logic would necessitate that the UI layer looks all the same, but I
fundamentally disagree. That is like saying that because all your clients use
the same API, they all must look the same.

~~~
KirinDave
I guess there is an implicit value judgement here that React+Redux's approach
is desirable for your team, so that motivates using utility libraries not
optimized for the constrained environment and a FRP framework with those
characteristics.

~~~
victoriasun
Yes, this is 100% correct. That being said you can also create a React app
using FRP framework such as Cycle JS and share exactly the same amount of code
that I've listed above. Our team has chosen to go the React/Redux approach; I
would argue that as an untyped language Javascript is unsuitable for FRP in
the first place, despite FRP's advantages in handling reactive UI.

------
superplussed
After starting to use RN for iOS, did you adapt the web app to use react-
native-web?

~~~
victoriasun
No, we do not share Views with web. All view logic is custom on each platform.

\- a Discord iOS engineer

------
HNNewer
Yeah, keeping a fork of it does the trick, but it means you have to watch your
back from React's unstable APIs, changing too fast

