[HN Gopher] Hermes, a JavaScript engine optimized for React Native
       ___________________________________________________________________
        
       Hermes, a JavaScript engine optimized for React Native
        
       Author : dgellow
       Score  : 177 points
       Date   : 2021-03-23 11:21 UTC (1 days ago)
        
 (HTM) web link (hermesengine.dev)
 (TXT) w3m dump (hermesengine.dev)
        
       | matchbok wrote:
       | Don't use FB made tools, please. The company is cancer.
        
         | [deleted]
        
         | notsrg wrote:
         | Using tools made by FB doesn't imply support for the company.
         | Ultimately having FB open source React/RN has been great for
         | open source - by the time it hits public release it's already
         | been battle tested internally.
        
         | ARandomerDude wrote:
         | But my small company isn't. And using ReactNative gets us there
         | easier/faster/cheaper than we ever could without it.
        
           | broberts01 wrote:
           | Agreed. With a two person team and we can do things we
           | couldn't otherwise. Having one shared code base for web,
           | android, and iOS is better for two people IMO.
        
         | [deleted]
        
         | kgin wrote:
         | What's the reasoning here? Facebook will change the way they
         | operate when people boycott paying the $0 to use their open
         | source projects?
        
       | lil_dude wrote:
       | idk really guys feels like shit
        
       | bdahz wrote:
       | How does it compare to QuickJS?
        
         | esprehn wrote:
         | According to this benchmark much larger binary size, but
         | similar performance: https://bellard.org/quickjs/bench.html
         | 
         | that was a while ago though.
        
           | gigel82 wrote:
           | Also, standard support is abysmal in Hermes, whereas full ES6
           | support is already there for QuickJS.
        
             | ridiculous_fish wrote:
             | Hermes is ES6 compliant to my knowledge.
        
               | nicoburns wrote:
               | Not exactly by the looks of things. Kangax says 71%
               | compliant. We tried Hermes at work and had to turn it off
               | again because our app was crashing. That was before they
               | implemented Proxy support, but I'm a little loathe to try
               | it again.
               | 
               | https://kangax.github.io/compat-table/es6/#hermes0_7_0
        
               | ridiculous_fish wrote:
               | My mistake, looks like some of the ES6 work is yet to be
               | finished.
        
       | realPubkey wrote:
       | Is there any performance comparison with the "default" js engine
       | of react native?
        
         | mateioprea wrote:
         | Yes, here:
         | https://engineering.fb.com/2019/07/12/android/hermes/
         | 
         | Scroll down to: How Hermes improves React Native performance
        
           | amelius wrote:
           | I find this interesting:
           | 
           | > Hermes today has no JIT compiler. This means that Hermes
           | underperforms some benchmarks, especially those that depend
           | on CPU performance. This was an intentional choice: These
           | benchmarks are generally not representative of mobile
           | application workloads.
           | 
           | What workloads are different from mobile application
           | workloads, other than server-side code?
        
             | lifthrasiir wrote:
             | Non-mobile web application workloads?
        
             | dgellow wrote:
             | If you continue, just after the bloc you quoted:
             | 
             | > Because JITs must warm up when an application starts,
             | they have trouble improving TTI and may even hurt TTI.
             | Also, a JIT adds to native code size and memory
             | consumption, which negatively affects our primary metrics.
             | A JIT is likely to hurt the metrics we care about most, so
             | we chose not to implement a JIT.
             | 
             | So it seems to be specific to their TTI (Time To Interact)
             | metric. A server application generally has the time to
             | warm-up to reach best-performances (pretty common in the
             | java world for example) while a mobile application has to
             | react to user inputs as soon as possible.
        
               | amelius wrote:
               | Does this mean that V8 (which uses a JIT compiler) is a
               | bad fit for web browsers?
               | 
               | I think they exaggerate:
               | 
               | > A JIT is likely to hurt the metrics we care about most
               | 
               | And they ruled out the possibility of having both a JIT
               | _and_ ahead of time compilation.
        
               | ridiculous_fish wrote:
               | Hermes does have a tier 1 JIT, though it is not a primary
               | focus yet.
        
               | albntomat0 wrote:
               | Do you have more information on this? I remember looking
               | into it a couple months ago, and being told the jit
               | wasn't going to be developed further. Thanks!
        
               | sime2009 wrote:
               | V8 also has an interpreter which runs first while code is
               | being compiled or has yet to be identified as a JIT
               | candidate.
        
               | fpoling wrote:
               | If JS code is few event listeners to verify/massage the
               | data to submit to the server, then the answer is yes. But
               | for more complex web pages the answer is now. For
               | example, React on web and similar framework may not be
               | feasible without JIT.
        
               | jiofih wrote:
               | Probably to limit scope / complexity. Remember that the
               | JS engine here (in React Native) is basically pulling
               | strings to orchestrate a bunch of native modules, not
               | doing any of the heavy lifting. It's quite different from
               | the current web environment.
        
               | Zababa wrote:
               | V8 has an interpreter (Ignition) and a JIT (TurboFan) [1]
               | but can be used without the JIT:
               | https://v8.dev/blog/jitless
        
       | selimnairb wrote:
       | All of these JavaScript frameworks are recreating native runtimes
       | on top of "standard" JavaScript engines. It seems wrong to me to
       | tailor a JavaScript engine to a particular framework. Ideally the
       | goal would be to move native framework-less JavaScript forward so
       | that we don't need all these over-complex competing frameworks.
        
         | runawaybottle wrote:
         | Shouldn't this be a hidden layer under React native? The thing
         | you suggest is impossible without having Google or Apple take
         | up the initiative.
         | 
         | All JS improvements for the last 10 years required a lot of
         | bypassing of browser and device maker's implementation.
        
         | cellularmitosis wrote:
         | The primary React Native performance issue on iOS is that Apple
         | disables the JIT when using JavaScriptCore. If you run some JS
         | in a WKWebView you should see it speed up by 5 to 10x.
         | (WKWebView runs in a different process, so they allow the JIT)
        
           | afavour wrote:
           | Arguably the primary React Native performance issue is that
           | JS is single-threaded. Does React Native provide any useful
           | tools for that?
        
             | spullara wrote:
             | You can run things in workers:
             | 
             | https://github.com/devfd/react-native-workers
        
             | nicoburns wrote:
             | That's not the primary issue. The main issue that there
             | isn't (or wasn't until recently) a fast, low overhead way
             | to communicate between JavaScript and native code. That's
             | changing with JSI, and I think we might find React Native
             | gets a lot faster in practice if they ever complete the
             | work.
        
           | Cthulhu_ wrote:
           | To be anal, the root cause of that is using javascript
           | instead of building a native app.
           | 
           | I get that Facebook has the biggest apps on any platform and
           | they run into platform limitations (like number of classes on
           | Android) and build cycles so for them it makes sense to make
           | a dynamic partial-hot-reloading-in-place app development
           | framework, but they're still beholden to the runtime that
           | Apple offers them.
           | 
           | (In theory they could compile JS to a compiled binary that
           | Apple's reviewers are okay with, but I don't know enough
           | about any of that)
        
             | JUNGLEISMASSIVE wrote:
             | The security implications of running JS in an interpreter
             | and running native bytecode are very different, though.
             | Native apps also routinely request much more permissions
             | and gather extra user data such as contacts, just because
             | it is possible to do so.
        
             | notsureaboutpg wrote:
             | Right, and since using Javascript has such poor performance
             | over using a native app on iOS, and since developers prefer
             | to use Javascript instead of build multiple native apps,
             | Hermes exists to bring Javascript performance closer to
             | native app performance.
             | 
             | Way better to have a tool that helps Javascript performance
             | than to burden developers with having to write native
             | iOS/Android apps separately
        
         | jbverschoor wrote:
         | That's what programmers tend to do. Inception :-). Abstraction
         | over virtualization over abstraction over virtualization etc.
         | 
         | And still there are root exploits that are about to go all the
         | way back up
         | 
         | I like react-native, as in the architecture (nativescript has a
         | better bridge). Unfortunately it's JavaScript. I guess we'll
         | have to deal with it another 40 years min.
        
       | dizzy3gg wrote:
       | From the docs: "Hermes is an open-source JavaScript engine
       | optimized for running React Native apps on Android."
       | 
       | Looks like it's available for iOS now too :)
       | 
       | Announcing React Native 0.64 with Hermes on iOS
       | https://reactnative.dev/blog/2021/03/12/version-0.64
        
         | dgellow wrote:
         | And with "React Native for Windows" and "React Native for
         | macOS" (both are still experimental):
         | https://microsoft.github.io/react-native-windows/docs/hermes
        
           | mirekrusin wrote:
           | Microsoft just gain a ton of respect by putting it out,
           | upfront description etc, I'm impressed by collaboration and
           | plain statements.
        
             | kabes wrote:
             | Yeah. Never thought I'd read how to use a facebook
             | javascript engine for macOS on a microsoft site.
        
               | jbverschoor wrote:
               | Why not?
               | 
               | Microsoft and Facebook have been lovers since the
               | beginning.. Even in terms of UI design of the earliest of
               | facebook.
        
               | WorldMaker wrote:
               | Also, Microsoft has a long history of being one of the
               | largest software developers for macOS. Even when deep in
               | the worst Windows versus Mac OS competitive years,
               | Microsoft still shipped a lot of software to Mac OS.
               | (Most of it Office products.)
        
             | pjmlp wrote:
             | And on Windows it uses WinUI/UWP actually.
             | 
             | The recent XBox dashboard has been remade with it.
        
               | dgellow wrote:
               | On Windows native components can be in C++/WinRT or C#,
               | which is quite nice. Typescript for the glue, managed C++
               | for the heavy lifting. That's a great compromise IMHO, at
               | least in theory. I'm still a bit skeptical because I
               | haven't seen yet WinUI or UWP applications with a
               | passable user experience.
        
               | Cullinet wrote:
               | Woz dug the windows phone in the earlier lumia stages
               | prior to the wp8 NT kernel with everything else gutting.
               | 
               | this is the one book I most want for Christmas - the true
               | account of what happened to the windows phone interface.
               | I was constantly in awe to behold the developments as
               | they happened ; literally "too good to be true"
               | electrocuted me in my chair every time I read the latest.
        
               | pjmlp wrote:
               | Agreed, you can see how I have been an heavy advocate of
               | it, and see it not only as a much better COM, but also
               | what .NET v1.0 should have been (it was the original idea
               | anyway, Ext-VOS).
               | 
               | However nowadays I have become quite sceptical on what it
               | will ever be, and looking forward to what news BUILD 2021
               | might bring.
               | 
               | C++/WinRT tooling still doesn't match C++/CX, doing UI in
               | .NET or ReactNative (QML style) seems to be the
               | workaround for it, endless list of Github issues on
               | WinUI, Reunion and all WinRT bindings, community talks
               | with lots of previews, and state of current tooling.
               | 
               | Then the various UI teams seem to be competing to which
               | of them will get more developer mindshare.
               | 
               | So it is a mess, that I hope BUILD will get a more clear
               | picture.
        
               | Cullinet wrote:
               | totally understand that kind of pain : actively thinking
               | about writing driver primitives to shim into the ui
               | library layers to get the eventual sensibility we need.
               | 
               | I've spent a inordinate amount of time on figuring out
               | how to hire a truly dedicated windows native interface
               | team and the only solid conclusion that I've come to is
               | it's necessary to also recruit to write tooling for the
               | designers to work with. we have a application that
               | happily doesn't need a gui but to be used widely needs a
               | excellent gui. it looks like we'll need at least as many
               | people on interface as for our core application. the
               | tooling, oh the tooling..
        
         | madeofpalk wrote:
         | Interesting - I would have thought custom JS engines/runtimes
         | would be a no go for both iOS and the iOS App Store.
        
           | lucideer wrote:
           | Definitely fine for Android (there's plenty of them), but I
           | would've thought the same for iOS.
           | 
           | Now that I think of it though, I think the Apple ToS that
           | prohibit browsers are about function (app used to browse the
           | web) rather than internals (language support in the engine).
        
             | pritambarhate wrote:
             | Apple's ToS prevent any kind of interpreted language in iOS
             | apps.
             | 
             | > 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. Educational apps designed to teach,
             | develop, or allow students to test executable code may, in
             | limited circumstances, download code provided that such
             | code is not used for other purposes. Such apps must make
             | the source code provided by the Application completely
             | viewable and editable by the user.
             | 
             | Basically embedding any interpreted language inside the app
             | is frowned upon by apple. But historically they have
             | allowed JavaScript and Lua scripts to be embedded in apps.
        
               | fpoling wrote:
               | That does not ban the interpreters. It prevents
               | interpretation of downloaded code. But as long the
               | sources to be interpreted are bundled with app, it is OK
               | at least from that section.
        
               | Cullinet wrote:
               | "Such apps must make the source code provided by the
               | Application completely viewable and editable by the
               | user."
               | 
               | arguably the ability to view source was what created the
               | possibilities of the Web, and as such I don't read this
               | term to be restrictive but instead merely trying to get
               | the best outcome for everyone.
               | 
               | disclaimer being that I have spent a large part of the
               | past year evaluating a ios app for commercial release
               | that both relies on decades of proprietary design and
               | which probably doesn't have a significant future unless
               | it is opened extensively or completely.
        
               | yellowapple wrote:
               | I mean, it depends on what they mean by "execute", right?
               | As far as iOS knows your app is just looping through some
               | binary data.
        
             | iudqnolq wrote:
             | I think the issue is if you interpret dynamically fetched
             | code. So you couldn't use this for out-of-band updates to
             | internals (unless you're important enough).
        
               | dgellow wrote:
               | I'm not sure that's true. When you use react native you
               | can update your javascript bundle and push it to an
               | application already deployed to the App Store and that
               | doesn't seem to be an issue. The application can check at
               | startup if a new bundle is available, otherwise defaults
               | to the local bundle.
               | 
               | See the expo documentation for details:
               | https://docs.expo.io/bare/updating-your-app/.
        
               | gorbypark wrote:
               | Apparently Apple is ok with out-of-band updates as long
               | as they don't add or change features. If it's used to fix
               | a bug then it's ok (at least they haven't cracked down on
               | React-native apps using codepush/expo's auto update
               | feature, yet.). There have been reports of Apple's
               | reviewers asking for clarification on why apps have the
               | ability to update, and as long as the answer is "bug
               | fixes" then they approve the app.
        
               | [deleted]
        
           | SigmundA wrote:
           | Beyond any TOS issues there has always been a technical issue
           | where an app store app cannot write to memory that is marked
           | executable for security purposes.
           | 
           | This prevents JIT's but does not prevent an interpreter from
           | functioning since an interpreter does not directly generate
           | machine code and execute it, it simply reads the code to
           | interpret as data and executes through its own engine.
           | 
           | Most modern JS engines JIT which is why you don't see say
           | electron / node / chromium based stuff on iOS, a lot of it
           | has to do with V8 requiring the ability to JIT.
           | 
           | Hermes does not JIT so it sidesteps the technical limitations
           | on iOS then its just a matter of passing review.
           | 
           | There where some ways around this that have been patched and
           | Apple has recent introduced an official entitlement but does
           | not allow it in the app store yet:
           | 
           | https://saagarjha.com/blog/2020/02/23/jailed-just-in-time-
           | co...
           | 
           | https://9to5mac.com/2020/11/06/ios-14-2-brings-jit-
           | compilati...
        
             | mmebane wrote:
             | Sadly, Apple removed the JIT support in 14.4, so not even
             | sideloaded apps can use it any more.
             | 
             | https://twitter.com/altstoreio/status/1354096048650809349
        
               | SigmundA wrote:
               | Unfortunate but I was surprised Apple looked like they
               | where changing it at all since it would lessen security
               | allowing some common attack vectors.
               | 
               | I haven't followed it for some time however, it does look
               | like V8 supports a JITless mode now which allows it to
               | possibly be used on iOS and other platforms with NX set,
               | albeit with significant performance loss:
               | 
               | https://v8.dev/blog/jitless
               | 
               | Looks like JavaScriptCore still disables JIT when run in
               | a non entitled app. Always thought they might figure out
               | a way to at least let their own JS engine JIT since its
               | trusted in Safari on the open web, but I believe its an
               | all or nothing thing for the process/app and not per
               | module thing.
        
               | layoutIfNeeded wrote:
               | JavaScriptCore could use a daemon process with elevated
               | privileges that does the JIT-ting and then shares back
               | the executable memory pages with the sandboxed process.
               | It's simply a matter of Apple wanting to curb React
               | Native because it threatens their control over app
               | development.
        
               | SigmundA wrote:
               | Out of process mean a loss in performance itself due to
               | marshaling cross process calls and data. When your
               | dealing with UI orchestration its probably better /
               | faster to run an interpreter with no cross process
               | overhead than a JIT with the overhead. Think Web Workers
               | which have similar issues, you have to keep your
               | communication with worker chunky for good performance.
        
               | my123 wrote:
               | You can run JavaScript out of process with the JIT
               | through WKWebView.
        
               | SigmundA wrote:
               | Which is fine if you're doing an HTML UI (PhoneGap) since
               | the DOM and JS engine share the same process. If you're
               | doing a native UI with JS then it must marshal cross
               | process to affect the UI then you have to decide which is
               | worse, no JIT or cross process overhead.
        
           | afavour wrote:
           | They used to be. I can't remember the exact part now but the
           | TOS used to ban anything that wasn't iOS's own JavaScriptCore
           | runtime. They changed it a few years ago.
        
             | fiddlerwoaroof wrote:
             | I don't think interpreters were ever banned, if you weren't
             | executing code downloaded from the internet: at least,
             | there's always been a variety of lisp/Python/Ruby
             | environments available to play with.
        
       | random_savv wrote:
       | I'm looking forward to using Hermes in our RN project when it's
       | fully featured. For us, it's sadly still missing Intl.Collator,
       | which we need to correctly sort international characters,
       | although it's in the works!
        
         | inbx0 wrote:
         | Unlike support for something like Proxies (which was recently
         | added), isn't Intl.Collator fairly easily polyfilled?
        
       | pfraze wrote:
       | Does Hermes use a custom bytecode or is it using wasm?
        
         | dgellow wrote:
         | Custom bytecode from what I get from their documentation
         | (https://hermesengine.dev/docs/design#hermes-bytecode-
         | generat...). You can check the playground to see it in action:
         | https://hermesengine.dev/playground/.
        
       | serguzest wrote:
       | Formatting C++
       | 
       | code with
       | 
       | 80 column hard
       | 
       | limit
       | 
       | looks bad.
        
       | phreack wrote:
       | I'm not an expert on JS engine internals, but every time I used
       | Hermes on a reasonably large React Native app, on Android
       | performance absolutely tanked. It's been like that for over a
       | year, and I just ended up disabling it, or enabling the debugger
       | so the engine turns to Chrome's. There's always been some
       | activity around it on the issue tracker[0] but not many
       | solutions.
       | 
       | [0] https://github.com/facebook/react-native/issues/25986 and
       | related issues
        
       | eatonphil wrote:
       | This site doesn't seem to describe much about the history or
       | internals. This FB blog post seems to have more details on how
       | and why:
       | 
       | https://engineering.fb.com/2019/07/12/android/hermes/
        
       ___________________________________________________________________
       (page generated 2021-03-24 23:01 UTC)