🔌 navigator.connection
polyfill for anywhere
📜 Implements the Network Information API
🗺️ Provides navigator.connection
APIs
🚀 Easy to use with a drop-in import polyfill
🦄 Also has a ponyfill import too
💻 Works in Node.js
🌐 Works in the browser
🦕 Works in Deno
🧅 Works in Bun
👀 Looking for navigator.connection.saveData
? Check out the related Save Data
API polyfill at @webfill/savedata.
You can install this polyfill using your favorite npm package manager like npm, pnpm, or Yarn:
npm install @webfill/netinfo
If you're using Deno you can use an npm:
specifier and it should Just Work™:
import "npm:@webfill/netinfo";
If you want to go buildless in the browser you can use an npm CDN like esm.sh or esm.run:
<script type="module">
import "https://esm.run/@webfill/netinfo";
import "https://esm.sh/@webfill/netinfo";
</script>
Navigator
/navigator
class/object to
mutate and add the Network Information APIs to. If you're using Deno, Bun, the
browser, or Node.js v21+ this is already available. If not, you'll need to add
a Navigator
/navigator
polyfill.
This polyfill is a drop-in import that will add the Network Information APIs to
the global scope's navigator
object. Then you can use navigator.connection
just like you would in a conforming browser environment:
import "@webfill/netinfo";
console.log(navigator.connection);
//=> {
// downlink: 10,
// downlinkMax: Infinity,
// effectiveType: "4g",
// rtt: 100,
// type: "wifi",
// }
if (navigator.connection.rtt > 200) {
alertBox.innerText = "You may experience some delay in game responsiveness.";
}
If you prefer to utilize the implementation directly without mutating the
global scope, you can use the @webfill/netinfo/ponyfill
import instead:
// This still delegates to the browser-native features if available.
import { NavigatorNetworkInformation } from "@webfill/netinfo/ponyfill";
const navigatorConnection = Reflect.get(
NavigatorNetworkInformation.prototype,
"connection",
globalThis.navigator ?? {}
);
console.log(navigatorConnection);
//=> {
// downlink: 10,
// downlinkMax: Infinity,
// effectiveType: "4g",
// rtt: 100,
// type: "wifi",
// }
if (navigatorConnection.rtt > 200) {
alertBox.innerText = "You may experience some delay in game responsiveness.";
}
This polyfill uses periodic fetch()
polling with performance.now()
to guage
the speed (or lack thereof) of your network connection. There's also a fallback
to use a synchronous version if you do navigator.connection.rtt
or something
before the first polling interval has completed.
This project is written in TypeScript. You can run the tests in the browser
using npm run test:browser
or in Node.js using npm test
.
The most interesting bits are getFetchStats()
, guessNetInfo()
, and
src/lib/NetworkInformation.ts
. That's where most of the magic happens.
Why not Vitest?
Vitest doesn't play well with Worker
threads and Atomics.wait()
. If you use
@vitest/web-worker, it's the same thread and so it deadlocks. You can't use
new Worker()
either since you need a raw JavaScript file (not .ts
). Thus,
the easiest thing to do to test things is to just build it and test against the
output JavaScript files instead of the TypeScript source code.
If you can figure out a way around this problem, I'd be very grateful! ❤️