npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wifi-sim

v0.1.0

Published

Physically-based indoor Wi-Fi planning suite (3D ray tracing, ITU-R P.2040 materials)

Downloads

299

Readme

WiFi-Sim

A free, offline Wi-Fi planning suite that runs in your browser. Upload a photo or scan of your floorplan, trace the walls, describe what they are made of, place your router, and get a coverage map computed from actual electromagnetics.

Nothing is uploaded anywhere. It all runs locally.

Open the app · Documentation · Start here

Coverage map of a two-bedroom flat

One router in the living room. The signal barely notices the stud partitions between the bedrooms and falls off a cliff at the load-bearing wall, and the one strong path into the kitchen goes through the door opening rather than through the wall. That is what the physics actually does, and it is what a decibels-per-wall model cannot show you.

Try it in five minutes

You need a floorplan with at least one printed dimension on it. If you do not have one to hand, use ours:

Download the example floorplan

The example floorplan

Then follow your first coverage map.

Ways to run it

| | | | --- | --- | | In a browser | professorquantumuniverse.github.io/wifi-sim | | Locally, one command | npx wifi-sim@latest | | In a container | docker run --rm -p 8080:8080 ghcr.io/professorquantumuniverse/wifi-sim:latest | | On your own server | wifi-sim-dist.zip from any release |

All of them run the identical application, and in every case the computation happens on your machine. "Hosted" only means the program is downloaded from GitHub, the way any web page is. Your floorplan is never uploaded, because there is nothing on the other end to upload it to.

There is no double-clickable HTML file, and there cannot be: the tracing and the solve both run in Web Workers, which browsers refuse to start on a page opened from the file system. See ways to run it.

What it actually computes

Every path from the router to every point on the map is enumerated and solved in closed form: the direct path, specular reflections up to second order, transmission through each wall in between, and UTD edge diffraction around corners and through door reveals.

Walls are not "6 dB per wall" lookups. Each build-up is solved with the exact multilayer transfer matrix, per polarisation and incidence angle, from ITU-R P.2040 material data. Rates come from the IEEE 802.11 sensitivity tables and OFDM numerology, not from a rate chart.

Traced walls over the scan

The tracing step. Green centrelines with their measured thicknesses, red markers at the junctions, and the yellow calibration line along the printed 11.00 m dimension. The lettering, the furniture symbols, the hatching and the dimension lines have all been filtered out by one slider.

Why bother

Free Wi-Fi planners are empirical. They add up a fixed dB per wall along the line of sight, which means they cannot represent reflection, diffraction, interference, or the fact that the same wall behaves differently at 2.4 and 5 GHz. Their heatmaps look convincing and are mostly decoration. The tools that do real physics (Ekahau, iBwave, Ranplan) are closed and expensive.

Two examples of what the difference costs you:

  • A 4-16-4 insulating glass unit attenuates 0.2 dB at 2.4 GHz and 9.3 dB at 5.5 GHz. Same window, 9 dB apart, because at 5.5 GHz the cavity is near half a wavelength. No per-wall table can express that.
  • Add the Low-E coating that every window fitted since about 2000 has, and it becomes 29 dB at 2.4 GHz and 34 dB at 5.5 GHz. That single fact explains most "why is my Wi-Fi dead on the balcony" mysteries, and most tools ignore it entirely.

Both of those numbers are asserted by the test suite on every commit.

The other principle: no invented numbers. Every physical constant carries its source, and the app says so. Anything not covered by a standard is a required input with a stated valid range, never a silent default. Where a model is used outside its validity (rebar mesh at Wi-Fi wavelengths, for instance), it says that too instead of returning a confident wrong answer.

Throughput map

The same solve as throughput rather than signal strength, which is usually the map you actually want. Dark means no link at all.

Is it right?

That question deserves a real answer rather than a claim, so the validation suite runs on every commit and every pull request:

npm test

| What | Against | Agreement | | --- | --- | --- | | Direct path | Friis | better than 0.002 dB | | Ground reflection | two-ray with the exact Fresnel coefficient | better than 0.02 dB | | Brewster's angle | TM null at atan(sqrt(eps_r)) | reflectance below 1e-20 | | Shadow boundary | half the incident field, 6.02 dB down | within 1 dB | | Half-wave dipole | Balanis, D = 1.643 | 2.15 dBi | | Low-E coating | t = 2/(2 + eta_0/R) | to nine decimals | | PHY rates | published 802.11n/ac/ax/be tables | exact |

Plus the invariants any correct solver has to satisfy: energy conservation, reciprocity, and that a wall face with windows and doors in it is tiled exactly by its compiled panels.

Writing that suite found three real bugs, including a diffraction sign error that inverted the lit and shadow regions for any wall drawn right to left. See the validation suite.

What it does not model

The honest list. Read it before you trust a number. The short version: one floor at a time, single diffraction, reflections to second order, smooth surfaces, and a single-station link. Most of the gaps are in the pessimistic direction.

Documentation

| | | | --- | --- | | Your first coverage map | Ten minutes, assumes nothing | | Tracing a floorplan | The step people get stuck on | | Reading the map | What the five layers actually mean | | The physics | Materials, walls, ray tracing, rates | | What it does not model | The most useful page | | Architecture | If you want to work on it |

Contributing

The most useful contribution needs no code: material data with a citation.

The material library is limited to ITU-R P.2040 Table 3, because that is the only source this project has and it does not invent numbers. PVC window profiles, screed, tile, carpet, mineral wool, rigid insulation and aerated concrete blocks are all missing. One sourced material improves every result the tool produces for anybody who has it in their building.

Almost as useful: a floorplan the tracer handles badly, and a comparison between a map this produced and a real measurement.

See CONTRIBUTING.md.

Stack

TypeScript, React, Vite, Zustand. No runtime dependencies beyond that, no network calls, and no build step needed to read the physics: it lives in src/physics and src/engine, and neither knows anything about the browser.

Licence

GNU General Public License v3.0 or later. See LICENSE.

You may use, study, modify and redistribute this freely. If you distribute a modified version, you must make your source available under the same terms. That was a deliberate choice: the physics engine is the valuable part of this project, and it should stay free for everybody rather than become the basis of somebody's closed product.

Copyright (C) 2026 Lorenzo Bay-Mueller.