Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for atob() and btoa() functions #1178

Closed
jonkoops opened this issue Oct 30, 2023 · 20 comments
Closed

Add support for atob() and btoa() functions #1178

jonkoops opened this issue Oct 30, 2023 · 20 comments
Labels
community-support-needed Facebook can't provide direct support for this issue, it is up to the community enhancement New feature or request

Comments

@jonkoops
Copy link

Problem

Much of the existing code in the JavaScript ecosystem, such as packages on NPM contain code that uses the atob() and btoa() global functions. And although not strictly part of the ECMAScript specification, it might be worthwhile to support these for the sake of compatibility with the rest of the ecosystem. Other runtimes that are also not strictly web-based such as Node.js, Bun and Deno all support these functions as well.

Solution

Add support for the atob() and btoa() global functions to Hermes.

Additional Context

I contribute to jwt-decode, a popular library (~5.7 million downloads per week) to decode JSON Web Tokens. One of the users logged an issue specifically referencing this issue in React Native, and by extension Hermes (see auth0/jwt-decode#241).

@jonkoops jonkoops added the enhancement New feature or request label Oct 30, 2023
@tmikov tmikov added the community-support-needed Facebook can't provide direct support for this issue, it is up to the community label Oct 30, 2023
@tmikov
Copy link
Contributor

tmikov commented Oct 30, 2023

It seems that JSC supports these, which is a pretty strong argument in favor of adding them.

@neildhar
Copy link
Contributor

@tmikov My understanding is that these were added to JSC relatively recently, and only to the CLI tool. (in WebKit/WebKit@70ccbd9). So RN users on JSC would likely still need an atob polyfill.

There seem to be three options:

  1. Continue using the polyfill, which may be slow if the inputs are large.
  2. Adding Base64 encoding and decoding to Hermes natively.
  3. Add an implementation over JSI to RN. But this will be clumsy to write because JSI forces strings to be converted to UTF-8, which means we will force some unnecessary conversions for the binary string. If we do this, we should consider adding functions to convert to/from std::u16string.

@tmikov
Copy link
Contributor

tmikov commented Oct 30, 2023

Issues like this will keep popping up. I think we need to figure out a general way to address them without the overhead of JSI. An optional "library" .so perhaps.

@shamilovtim
Copy link

shamilovtim commented Nov 15, 2023

I've been using the JSI based https://github.com/craftzdog/react-native-quick-base64

Issues like this will keep popping up. I think we need to figure out a general way to address them without the overhead of JSI. An optional "library" .so perhaps.

The pure JS polyfills everyone recommends in these threads are even worse than JSI!

Issues like this will keep popping up. I think we need to figure out a general way to address them without the overhead of JSI. An optional "library" .so perhaps.

It's perplexing to me how long the RN runtime has existed without these critical Web APIs. I think it would be uncontroversial to say that the platform is critically incomplete without them. I know it doesn't belong in Hermes and you get these requests here. But why are the runtime team disregarding the lack of these APIs that exist in every web runtime and native platform?

@tmikov Why can't the atob/btoa, crypto, web streams, etc. C++ libraries from Chromium just be inserted into the React Native core and exposed through JSI?

@tmikov
Copy link
Contributor

tmikov commented Nov 15, 2023

Good news, folks! We have decided to add these to Hermes. We should have them soon. We are also working on a way to handle this in general in Static Hermes, by automatically pulling such functions in only when they are needed.

Of course, we realize that after we commit these new functions, it then takes a significant time for them to actually be usable, because the next RN release needs to happen, and then users need to upgrade to it...
We plan to also address this problem very soon by introducing a stable Hermes ABI, which will allow Hermes to be upgraded freely independently of RN.

@jonkoops
Copy link
Author

That is great news, thanks so much for considering this and the quick and efficient handling of this issue!

@tmikov
Copy link
Contributor

tmikov commented Jan 17, 2024

Implemented in 13fafde and d2177c3.

@tmikov tmikov closed this as completed Jan 17, 2024
@Bardiamist
Copy link

Cool, I want to use it. How can I understand in which version it will land and which version used in a react-native project?

@tmikov
Copy link
Contributor

tmikov commented Jan 17, 2024

@Bardiamist React Native automatically uses the latest Hermes version when they cut a release, so it will be in the next RN release, I guess 0.74.

@Bardiamist
Copy link

Bardiamist commented Jan 17, 2024

Is it possible to see versions? 0.12.0 is the latest version of Hermes? It's strage because of more than year ago.
And how to see Hermes used version in react native?

@tmikov
Copy link
Contributor

tmikov commented Jan 17, 2024

@Bardiamist for now Hermes is distributed as part of RN and has no independent distribution or version. You can see versions as branches in the Hermes repo:
Screenshot 2024-01-17 at 7 55 56 AM

@jonkoops
Copy link
Author

@tmikov just to verify, as I am having some trouble reading the changelog for React Native, has this been released in version 0.73?

@Bardiamist
Copy link

@jonkoops No, this commint not in https://github.com/facebook/hermes/tree/rn/0.73-stable

Also I checked that atob doesn't exist in [email protected] just now

@jonkoops
Copy link
Author

Thanks for checking that @Bardiamist. I'll assume this will be landing in version 0.74 then.

@TwistedMinda
Copy link

How do you check if atob is included ?

0.74 has released by now, would be nice to see if this is settled.
Thanks

@tmikov
Copy link
Contributor

tmikov commented May 13, 2024

One simple way to see whether it is available using the CLI:

echo "print(typeof atob)" | hermes

@Bardiamist
Copy link

Now atob has issue reactwg/react-native-releases#287
But should be fix will be cherry picked soon

@mauricedoepke
Copy link

@TwistedMinda I am using react-native 0.74.1 atob and btoa are now working for me.

@wh201906
Copy link

wh201906 commented Jun 27, 2024

Hi there.
I wonder if it's possible to change the implementations of atob() and btoa() to some faster libraries, like simdutf. This is used in Node.js and should be faster than the implementation in 13fafde and d2177c3

@tmikov
Copy link
Contributor

tmikov commented Jun 27, 2024

@wh201906 do you have a specific case where the performance of atob()/btoa() is unsatisfactory? On what platform?

The Hermes team doesn't have bandwidth to experiment with faster implementations of these. But if there is a PR that measurably improves performance on all supported platforms without dramatically increasing the binary size (which is very important for a mobile platform), we will consider it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community-support-needed Facebook can't provide direct support for this issue, it is up to the community enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants