{"id":34245319,"url":"https://github.com/nberlette/atob","last_synced_at":"2026-03-10T16:18:47.137Z","repository":{"id":286253901,"uuid":"908125644","full_name":"nberlette/atob","owner":"nberlette","description":"Performant platform-agnostic ponyfills for `atob` and `btoa`.","archived":false,"fork":false,"pushed_at":"2025-12-12T05:15:38.000Z","size":23,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-19T14:15:42.160Z","etag":null,"topics":["atob","base64","base64-decoding","base64-encoding","btoa","polyfill","polyfills","ponyfill","typescript"],"latest_commit_sha":null,"homepage":"https://jsr.io/@nick/atob","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nberlette.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"nberlette"}},"created_at":"2024-12-25T07:46:59.000Z","updated_at":"2025-12-12T04:20:56.000Z","dependencies_parsed_at":"2025-04-05T09:36:40.001Z","dependency_job_id":null,"html_url":"https://github.com/nberlette/atob","commit_stats":null,"previous_names":["nberlette/atob"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/nberlette/atob","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nberlette%2Fatob","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nberlette%2Fatob/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nberlette%2Fatob/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nberlette%2Fatob/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nberlette","download_url":"https://codeload.github.com/nberlette/atob/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nberlette%2Fatob/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30342165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T15:55:29.454Z","status":"ssl_error","status_checked_at":"2026-03-10T15:54:58.440Z","response_time":106,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atob","base64","base64-decoding","base64-encoding","btoa","polyfill","polyfills","ponyfill","typescript"],"created_at":"2025-12-16T06:30:45.190Z","updated_at":"2026-03-10T16:18:47.114Z","avatar_url":"https://github.com/nberlette.png","language":"TypeScript","funding_links":["https://ko-fi.com/nberlette"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# @nick/atob\n\n\u003cb\u003eLightweight, dependency-free, portable ponyfills for `atob` and `btoa`.\u003c/b\u003e\n\n[![][badge-jsr-score]][JSR] [![][badge-jsr-pkg]][JSR]\n\n\u003c/div\u003e\n\n---\n\n## Install\n\n```sh\ndeno add jsr:@nick/atob\n```\n\n```sh\npnpm add jsr:@nick/atob\n```\n\n```sh\nyarn add jsr:@nick/atob\n```\n\n```sh\nbunx jsr add @nick/atob\n```\n\n```sh\nnpx -y jsr add @nick/atob\n```\n\n---\n\n## Usage\n\nThis package provides [ponyfill] exports for `atob` and `btoa`, as well as a\n`./shim` entrypoint that will automatically polyfill the global scope with\n`atob` and/or `btoa` if they are not already supported.\n\n### [Ponyfill]\n\n```ts\nimport { atob, btoa } from \"@nick/atob\";\nimport assert from \"node:assert\";\n\nconst datauri = `data:image/svg+xml;base64,${btoa(\"\u003csvg\u003e...\u003c/svg\u003e\")}`;\nconst base64 = datauri.split(\",\")[1]!;\n\nconst decoded = atob(base64); // \"\u003csvg\u003e...\u003c/svg\u003e\"\nassert.strictEqual(decoded, \"\u003csvg\u003e...\u003c/svg\u003e\"); // OK\n```\n\n### [Polyfill]\n\nWhile the primary focus of this package is providing a [ponyfill] for `atob` and\n`btoa`, some users might need a \u003cem\u003epoly\u003c/em\u003efill instead.\n\nTherefore, I've also provided an automatic shim module that gracefully installs\nthese functions on an as-needed basis, as well as a manual install module that\nallows you to choose when and if you want it to mutate the global scope.\n\n#### Shim (automatic)\n\n```ts ignore\nimport \"@nick/atob/shim\"; // side-effect import\n\nconst bytes = \"data:application/wasm;base64,AGFzbQEAAAABOwpgAn9/AX...\";\n\nconst buf = Uint8Array.from(atob(bytes.split(\",\")[1]!), (b) =\u003e b.charCodeAt(0));\n\nconst module = new WebAssembly.Module(buf);\nconst instance = new WebAssembly.Instance(module);\n```\n\n#### Install (manual)\n\nIf you need explicit control over the polyfilling, [`install()`](#install-1) can\nbe used to gracefully install the functions on-demand.\n\n```ts\nimport { install } from \"@nick/atob/install\";\nimport assert from \"node:assert\";\n\nif (typeof atob !== \"function\" || typeof btoa !== \"function\") {\n  install(); // ta da!\n}\n\nassert.strictEqual(btoa(\"hello world\"), \"aGVsbG8gd29ybGQ=\"); // OK\nassert.strictEqual(atob(\"aGVsbG8gd29ybGQ=\"), \"hello world\"); // OK\n```\n\n\u003e [!NOTE]\n\u003e\n\u003e This is used internally by the `./shim` entrypoint.\n\n---\n\n## API\n\n### `atob`\n\nDecodes a Base64-encoded string into a decoded string.\n\n#### Signature\n\n```ts ignore\nfunction atob(data: string): string;\n```\n\n##### Params\n\n**`data`** The Base64-encoded string to decode.\n\n##### Return\n\nA decoded string.\n\n#### Example\n\n```ts\nimport { atob } from \"@nick/atob\";\nimport assert from \"node:assert\";\n\nconst encoded = \"aGVsbG8gd29ybGQ=\";\nconst decoded = atob(encoded);\n\nassert.strictEqual(decoded, \"hello world\"); // OK\n```\n\n#### References\n\n- [`atob` - HTML Standard](https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob)\n- [MDN Reference: `atob`](https://developer.mozilla.org/en-US/docs/Web/API/atob)\n\n---\n\n### `btoa`\n\nEncodes a string into Base64.\n\n#### Signature\n\n```ts ignore\nfunction btoa(data: string): string;\n```\n\n##### Params\n\n**`data`** The string to encode.\n\n##### Return\n\nA Base64-encoded string.\n\n#### Example\n\n```ts\nimport { btoa } from \"@nick/atob\";\nimport assert from \"node:assert\";\n\nconst data = \"hello world\";\nconst encoded = btoa(data);\n\nassert.strictEqual(encoded, \"aGVsbG8gd29ybGQ=\");\n```\n\n#### References\n\n- [`btoa` - HTML Standard](https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa)\n- [MDN Reference: `btoa`](https://developer.mozilla.org/en-US/docs/Web/API/btoa)\n\n---\n\n### `install`\n\nGracefully polyfills the global `atob` and `btoa` functions if they are not\nalready present in the environment.\n\n#### Signature\n\n```ts ignore\nfunction install(): Result;\n```\n\n##### Return\n\n- On success, returns a `Success` object containing the installed functions.\n- If the functions are already defined, returns a `Skipped` result.\n- If the installation fails, returns a `Failure` result with the error.\n\n#### Associated Types\n\n##### `Success\u003cT\u003e`\n\nRepresents a successful polyfill installation\n\n```ts ignore\ninterface Success\u003cT\u003e {\n  readonly type: \"success\";\n  readonly data: T;\n}\n```\n\n##### `Skipped`\n\nIndicates that the installation was skipped because `atob` and `btoa` are\nalready present. If available, the `info` property will contain extra context\nabout which functions were already defined and thus skipped.\n\n```ts ignore\ninterface Skipped {\n  readonly type: \"skipped\";\n  readonly info?: string;\n}\n```\n\n##### `Failure`\n\nRepresents a failed installation with an error.\n\n```ts ignore\ninterface Failure {\n  readonly type: \"failure\";\n  readonly error: unknown;\n}\n```\n\n##### `Data`\n\nContains references to the installed polyfill functions. This is the type of the\n`data` property within a `Success` result returned by calling `install()`. If\nonly one function was installed, it will be the only one present in the data\npayload. Otherwise, both of the polyfilled functions will be referenced.\n\n```ts ignore\ntype Data =\n  | { readonly atob: typeof atob }\n  | { readonly btoa: typeof btoa }\n  | { readonly atob: typeof atob; readonly btoa: typeof btoa };\n```\n\n##### `Result`\n\nRepresents the union of all possible results of the installation process, which\nare each documented in the sections above. This is a discriminated union type;\ncheck against the `type` property to determine which variant you have and allow\nTypeScript to narrow the type accordingly.\n\n```ts ignore\ntype Result = Success\u003cData\u003e | Skipped | Failure;\n```\n\n#### Example\n\n```ts\nimport { install } from \"@nick/atob/install\";\nimport assert from \"node:assert\";\n\nif (typeof atob !== \"function\" || typeof btoa !== \"function\") {\n  const result = install();\n  if (result.type === \"success\") {\n    console.log(\"atob and btoa installed successfully.\");\n  } else if (result.type === \"skipped\") {\n    console.log(\"atob and btoa already installed.\");\n  } else {\n    console.error(\"Failed to install atob and btoa:\", result.error);\n  }\n}\n\nassert.ok(typeof btoa === \"function\"); // OK\nassert.strictEqual(btoa(\"hello world\"), \"aGVsbG8gd29ybGQ=\");\n\nassert.ok(typeof atob === \"function\"); // OK\nassert.strictEqual(atob(\"aGVsbG8gd29ybGQ=\"), \"hello world\");\n```\n\n---\n\n### [Contributing]\n\nContributions are always welcome! Before [submitting a pull request], I kindly\nask that you first [open an issue] and start a discussion regarding the feature\nor bug you would like to address. This helps contributions align with the goals\nand scope of the project, ensuring a smoother integration process.\n\nFor additional details, please refer to the [contributing guidelines]. Thanks!\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**[MIT] © [Nicholas Berlette]. All rights reserved.**\n\n\u003csmall\u003e\n\n[github] · [issues] · [docs] · [contributing]\n\n\u003c/small\u003e\n\n[![][badge-jsr]][JSR]\n\n\u003c/div\u003e\n\n[Docs]: https://jsr.io/@nick/atob/doc \"View the API documentation for @nick/atob on jsr.io!\"\n[open an issue]: https://github.com/nberlette/atob/issues/new \"Found a bug? Please open an issue on the nberlette/atob repository!\"\n[contributing guidelines]: https://github.com/nberlette/atob/blob/main/.github/CONTRIBUTING.md \"Please read the Contributing Guidelines prior to making your first contribution.\"\n[submitting a pull request]: https://github.com/nberlette/atob/compare \"Submit a Pull Request on GitHub\"\n[badge-jsr]: https://jsr.io/badges/@nick \"View all of @nick's packages on jsr.io\"\n[badge-jsr-pkg]: https://jsr.io/badges/@nick/atob \"View @nick/atob on jsr.io\"\n[badge-jsr-score]: https://jsr.io/badges/@nick/atob/score \"View the score for @nick/atob on jsr.io\"\n[MIT]: https://nick.mit-license.org \"MIT © Nicholas Berlette. All rights reserved.\"\n[Nicholas Berlette]: https://github.com/nberlette \"Follow @nberlette on GitHub for more useful projects!\"\n[GitHub]: https://github.com/nberlette/atob \"Give this project a star on GitHub! 🌟\"\n[Issues]: https://github.com/nberlette/atob/issues \"Found a bug? Let's squash it!\"\n[JSR]: https://jsr.io/@nick/atob/doc \"View the @nick/atob package on JSR\"\n[Contributing]: https://github.com/nberlette/atob/blob/main/.github/CONTRIBUTING.md \"Read the Contributing Guidelines for nberlette/atob on GitHub\"\n[ponyfill]: https://ponyfill.com \"Learn more about Ponyfills from Sindre Sorhus\"\n[polyfill]: https://developer.mozilla.org/en-US/docs/Glossary/Polyfill \"Polyfills on MDN\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnberlette%2Fatob","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnberlette%2Fatob","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnberlette%2Fatob/lists"}