react-native-url-polyfill
A lightweight, spec-compliant URL and URLSearchParams polyfill built specifically for React Native.
Repository Health
Technical Analysis
React Native ships its own homemade URL implementation, but it was built to cover limited use cases and has accumulated well-known bugs — it mishandles the “localhost” domain, adds trailing slashes incorrectly, and throws on inputs that are perfectly valid per spec. react-native-url-polyfill replaces it with a dependency-free implementation of the WHATWG URL Standard, covering the full basic URL parser state machine, IPv4/IPv6 host parsing, percent-encoding sets, and the application/x-www-form-urlencoded format — while intentionally omitting Unicode/IDNA hostname processing to keep the bundle small (about 25KB added to a React Native app).
Correctness is backed by unit tests generated from the official Web Platform Tests URL suite plus Detox end-to-end tests run against a matrix of React Native versions (0.60 through 0.84), and its types are verified to stay interchangeable with Node.js’s built-in URL and the whatwg-url package. It ships three ways to adopt it: an auto-applying side-effect import, an explicit setupURLPolyfill() call, or a ponyfill-style import of URL/URLSearchParams that leaves globals untouched — plus a built-in workaround for a known iOS 10 ArrayBuffer.byteLength bug.
What You Get
- A self-contained implementation of the full WHATWG URL Standard parser, including IPv4/IPv6 host parsing and percent-encoding sets, with Unicode/IDNA hostname handling deliberately left out to keep the bundle small
- A drop-in URLSearchParams implementation with the same behavior as the web and Node.js versions
- Three integration modes: zero-config auto-patch via
react-native-url-polyfill/auto, an explicitsetupURLPolyfill()call, or a ponyfill import that never touches globals - Zero runtime dependencies — the only dependency is a peer dependency on react-native itself
- A built-in workaround for the iOS 10
ArrayBuffer.prototype.byteLengthbug - Conformance verified against generated Web Platform Tests plus Detox e2e coverage across React Native 0.60 through 0.84, with TypeScript types kept interchangeable with Node’s URL and whatwg-url
Common Use Cases
- Parsing, constructing, and serializing URLs (query strings, paths, hosts, ports) reliably inside a React Native app
- Working around React Native’s known URL bugs — localhost handling, trailing-slash mishandling, and constructor exceptions on valid input
- Sharing URL-parsing code between a React Native app and a web codebase without behavioral drift
- Building or consuming APIs that rely on URLSearchParams for query-string manipulation on mobile
- Running libraries that assume a spec-compliant global URL/URLSearchParams (many networking and data-fetching packages do) inside React Native
Under The Hood
Architecture
The package is architecturally simple by design: a single-purpose polyfill split into js/URL.ts (a ~2,400-line, spec-faithful implementation of the WHATWG URL Standard state machine — UTF-8 encode/decode, percent-encoding sets, IPv4/IPv6 host parsing, the basic URL parser), js/URLSearchParams.ts, and a small js/ios10Fix.js that patches a known iOS 10 ArrayBuffer bug behind a Platform.OS/Platform.Version check. The public surface is index.js, which imports the iOS fix, re-exports URL/URLSearchParams, and exposes setupURLPolyfill() to monkey-patch globalThis; auto.js is a two-line entry point that calls setupURLPolyfill() only when Platform.OS !== 'web', making adoption effectively side-effect-import-triggered rather than instance-based. There’s no dependency injection or multi-layer architecture beyond “one spec-faithful core module + one platform-detection shim + one thin activation wrapper” — the entire behavioral surface sits on top of URL.ts, so that file is the single point that would ripple everywhere if the parser changed.
Tech Stack
The core is TypeScript restricted to erasable syntax (type annotations only, no enums or namespaces), by the source’s own documentation, so it can be executed directly by Node.js via type-stripping; the published package ships compiled, minified JavaScript built with tsdown (ESM, dts type declarations, neverBundle: ['react-native']). There are no runtime dependencies in package.json — react-native is declared only as a peer dependency (*) — keeping the polyfill genuinely dependency-free. Testing runs on Jest with the react-native preset; conformance tests are generated from the official Web Platform Tests URL corpus via a dedicated generator script, and end-to-end verification runs through Detox against a matrix of standalone React Native apps for versions 0.60 through 0.84 (each with its own iOS/Android projects). CI runs on CircleCI, with ESLint (react-native-community config) and Prettier enforced pre-commit via Husky and lint-staged.
Code Quality
Test coverage is unusually extensive for a polyfill of this size: unit tests for the public API (__tests__/index-test.js, auto-test.js), deep implementation tests for URL and URLSearchParams (hundreds of lines each), a WebIDL conformance suite, and a WPT-corpus conformance runner, on top of Detox e2e specs replicated per supported React Native version. Types are checked with TypeScript’s native-preview compiler (tsgo) and shipped as .d.ts files alongside the build. The parser follows the spec’s own error-handling convention — returning a FAILURE sentinel rather than throwing or silently swallowing invalid input — and linting/formatting is enforced automatically on every commit.
API Design
The public API is deliberately minimal and offers three adoption paths to match different team preferences: a zero-config side-effect import for teams that just want the globals fixed, an explicit setupURLPolyfill() call for teams that want control over timing, and a ponyfill-style named import for teams that don’t want to touch globals at all. Naming mirrors the platform APIs exactly (URL, URLSearchParams), so there’s no new vocabulary to learn, and the runtime sets a globalThis.REACT_NATIVE_URL_POLYFILL marker so consumers can verify at runtime that the polyfill actually applied. Getting started is a single import line, and shipped TypeScript types give consumers autocomplete and type-checking with no extra setup.
Used by 5 apps in this directory
Jitsi Meet
Team Chat · Collaboration · Video Conferencing
Open-source, end-to-end encrypted video conferencing you can self-host or embed into any web or mobile app.
Joplin
Note Taking
The privacy-first, open-source note-taking app with end-to-end encrypted sync, AI assistance, and a powerful plugin ecosystem across every platform.
Notesnook
Note Taking · File Storage · Security
End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.
Suna
AI Agents
Turn your company into a git repo — one config, one command center, a workforce of AI agents that runs the real work around the clock.
Supabase
Developer Tools · Databases · Search
The open-source Postgres development platform that replaces Firebase with authentication, real-time APIs, edge functions, storage, and vector embeddings — all built on PostgreSQL.