You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
atob and btoa should not be marked as legacy #57145
the alternative listed is not an equivalent. atob and btoa are optimized at the C++ level, and do not create an in-memory Buffer in javascript context that then has to be garbage collected (needless, for instance, when JSON.parse(atob(b64)))
having these marked as legacy also seems to go against the very good direction node has taken recently of compatibility with web apis like the webstreams api
i think it would be great if these were marked Stability 2! what do you think?
Even if their legacy status has been somewhat weakened by the fact that they were optimized it stands to say that they were not optimized as much as other methods and their proper replacement being https://github.com/tc39/proposal-arraybuffer-base64 is going to be generally available soon(ish)12.
I don't think we need to be doing any changes here. If anything I'd say we update the new recommendation to be the new Uint8Array methods as soon as they become available in V83 (and soon thereafter in node).
I love the new Uint8Array methods! i've been using them in Firefox, and they're great. Though I still don't think they're a great replacement for every usecase:
and that can really matter in memory-sensitive applications!
atob and btoa are stable and fantastic at their job. they're also stable in the web platform and deno. i don't know if that matters so much, but i think many of us really appreciate the cross-runtime compatibility.
But that's not the same! atob and btoa don't work with UTF-8 encoding. This kind of confusion is one of the main reasons that we discourage their use.
Correct, and this fact, that they are not the same was mentioned in the original comment:
the alternative listed is not an equivalent.
Because they are not the same, we can't suggest that someone use the suggested alternative for all use-cases, since those differences might be important for them.
It seems like what we likely want to do here is not mark this as legacy, and also direct to newer APIs for specific scenarios, which is what MDN has chosen to do. This would also align with Deno and with Bun, both of whom do not mark atob btoa as legacy.
A method marked as legacy has no functional or future deprecation related consequences tho. And it is exactly that, legacy. It's part of the HTML standard, not ECMAScript. It doesn't work with utf-8 inputs and it has considerable drawbacks when you actually want to use it with large inputs and eventually move those in/out of Uint8Array.
Because they are not the same, we can't suggest that someone use the suggested alternative for all use-cases, since those differences might be important for them.
They are the same in that they're compatible in terms of what they accept, and they actually accept more, which is not to the user's detriment.
These were marked as Legacy for the simple reason that we want to subtly discourage users from reaching for them while we have better options readily available. When they were proposed to be added there was some disagreement about whether they should be and adding them with the legacy flag was the compromise that was reached. Being marked as legacy means it won't be deprecated or removed but that it's not the thing we recommend that you use. In every other way they are perfectly fine to make use of.
having these marked as legacy also seems to go against the very good direction node has taken recently of compatibility with web apis like the webstreams api
The status of being legacy doesn't really have much to do with compatibility - the fact that they were implemented as legacy features from the beginning is already a choice made with consideration of compatibility. If we are indeed going against this trend then this API would be added in the first place. As @jasnell mentioned the legacy status in the docs is just a way of discouraging usage when there are better alternatives (in this case, the typed array methods or TextDecoder etc. that are capable of handling non-ASCII characters properly).
It seems like a better way forward is to document why it's considered legacy and what's the better alternative instead. We can add a "good first issue" label to see if someone is interested in sending a documentation PR if there's agreed.
Also, I think the fact that the OP states needless, for instance, when JSON.parse(atob(b64)) is somewhat concerning already, because it seems to already been giving people an idea that you don't need to worry about what happens when e.g. b64 = Buffer.from('{"a": "测试"}').toString('base64')
I'm just not sure why these needed to be marked 'legacy' within NodeJS when it seems that no other runtime has marked them as legacy, including sites such as MDN. The messaging to the end-user is mixed. I understand wanting to encourage other alternative APIs, can that be achieved whilst also not tagging these functions as 'legacy'?
Also, I think the fact that the OP states needless, for instance, when JSON.parse(atob(b64)) is somewhat concerning already, because it seems to already been giving people an idea that you don't need to worry about what happens when e.g. b64 = Buffer.from('{"a": "测试"}').toString('base64')
I would assume the OP shortened the example and was likely using input which is always latin-1 such as HTTP Field Values:
A method marked as legacy has no functional or future deprecation related consequences tho
Being marked as legacy means it won't be deprecated or removed
This is great news! the documentation for "Stability 3" is slightly less firm on that point, stating "unlikely to be removed" and "unmaintained". If it were to say "will continue to be maintained, will not be deprecated or removed, but is discouraged" in the docs I probably wouldn't have come here.
I'll see if I can get manager sign-off on the use of legacy atob to decode serialized latin-1 base 64 strings off the back of the commitments in this thread.
The documentation was written to give us long term wiggle room Just In Case but I cannot foresee any circumstance where Node.js would remove atob/btoa or not fix any bugs that may be found, so I'd say you're safe.
Activity
panva commentedon Feb 20, 2025
Even if their legacy status has been somewhat weakened by the fact that they were optimized it stands to say that they were not optimized as much as other methods and their proper replacement being https://github.com/tc39/proposal-arraybuffer-base64 is going to be generally available soon(ish)12.
I don't think we need to be doing any changes here. If anything I'd say we update the new recommendation to be the new Uint8Array methods as soon as they become available in V83 (and soon thereafter in node).
Footnotes
https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64 ↩
https://caniuse.com/mdn-javascript_builtins_uint8array_tobase64 ↩
https://issues.chromium.org/issues/42204568 ↩
chee commentedon Feb 20, 2025
I love the new
Uint8Arraymethods! i've been using them in Firefox, and they're great. Though I still don't think they're a great replacement for every usecase:this is making a lot more Stuff:
than this:
and that can really matter in memory-sensitive applications!
atobandbtoaare stable and fantastic at their job. they're also stable in the web platform and deno. i don't know if that matters so much, but i think many of us really appreciate the cross-runtime compatibility.targos commentedon Feb 20, 2025
But that's not the same!
atobandbtoadon't work with UTF-8 encoding. This kind of confusion is one of the main reasons that we discourage their use.targos commentedon Feb 20, 2025
Example to illustrate:
JakeChampion commentedon Feb 20, 2025
Correct, and this fact, that they are not the same was mentioned in the original comment:
Because they are not the same, we can't suggest that someone use the suggested alternative for all use-cases, since those differences might be important for them.
It seems like what we likely want to do here is not mark this as legacy, and also direct to newer APIs for specific scenarios, which is what MDN has chosen to do. This would also align with Deno and with Bun, both of whom do not mark atob btoa as legacy.
panva commentedon Feb 20, 2025
A method marked as legacy has no functional or future deprecation related consequences tho. And it is exactly that, legacy. It's part of the HTML standard, not ECMAScript. It doesn't work with utf-8 inputs and it has considerable drawbacks when you actually want to use it with large inputs and eventually move those in/out of Uint8Array.
They are the same in that they're compatible in terms of what they accept, and they actually accept more, which is not to the user's detriment.
jasnell commentedon Feb 20, 2025
These were marked as Legacy for the simple reason that we want to subtly discourage users from reaching for them while we have better options readily available. When they were proposed to be added there was some disagreement about whether they should be and adding them with the legacy flag was the compromise that was reached. Being marked as legacy means it won't be deprecated or removed but that it's not the thing we recommend that you use. In every other way they are perfectly fine to make use of.
joyeecheung commentedon Feb 20, 2025
The status of being legacy doesn't really have much to do with compatibility - the fact that they were implemented as legacy features from the beginning is already a choice made with consideration of compatibility. If we are indeed going against this trend then this API would be added in the first place. As @jasnell mentioned the legacy status in the docs is just a way of discouraging usage when there are better alternatives (in this case, the typed array methods or TextDecoder etc. that are capable of handling non-ASCII characters properly).
It seems like a better way forward is to document why it's considered legacy and what's the better alternative instead. We can add a "good first issue" label to see if someone is interested in sending a documentation PR if there's agreed.
joyeecheung commentedon Feb 20, 2025
Also, I think the fact that the OP states
needless, for instance, when JSON.parse(atob(b64))is somewhat concerning already, because it seems to already been giving people an idea that you don't need to worry about what happens when e.g.b64 = Buffer.from('{"a": "测试"}').toString('base64')JakeChampion commentedon Feb 20, 2025
I'm just not sure why these needed to be marked 'legacy' within NodeJS when it seems that no other runtime has marked them as legacy, including sites such as MDN. The messaging to the end-user is mixed. I understand wanting to encourage other alternative APIs, can that be achieved whilst also not tagging these functions as 'legacy'?
I would assume the OP shortened the example and was likely using input which is always latin-1 such as HTTP Field Values:
chee commentedon Feb 20, 2025
This is great news! the documentation for "Stability 3" is slightly less firm on that point, stating "unlikely to be removed" and "unmaintained". If it were to say "will continue to be maintained, will not be deprecated or removed, but is discouraged" in the docs I probably wouldn't have come here.
I'll see if I can get manager sign-off on the use of legacy
atobto decode serialized latin-1 base 64 strings off the back of the commitments in this thread.jasnell commentedon Feb 21, 2025
The documentation was written to give us long term wiggle room Just In Case but I cannot foresee any circumstance where Node.js would remove
atob/btoaor not fix any bugs that may be found, so I'd say you're safe.chee commentedon Feb 21, 2025
@jasnell thank you <3