Skip to content

NetCarve

TypeScript (strict) Preact + WXT Manifest V3 IPv4 + IPv6 Two permissions only No network requests ~44 KB gzipped 100 % branch coverage on the IP core
Live on the Chrome Web Store.
NetCarve is published and free to install. It asks for two permissions, no host access at all, and makes no network requests — every plan you carve stays in your own browser profile.

Plan address space, not just calculate it. NetCarve does the subnet arithmetic every calculator does, and then the part that actually takes the afternoon: laying out a client’s address space, checking it against what is already there, and getting the result into the documentation.

The NetCarve quick calculator with 192.168.1.37/24 typed in: the resolved network shown as 192.168.1.0/24 with an IPv4 badge, a prefix-length slider, a bit ruler whose filled cells mark the network bits, and a grid of network address, prefix length, subnet mask, wildcard mask, broadcast address, address range, first and last usable address and the two counts, above a reserved-ranges note flagging 192.168.0.0/16 as private under RFC 1918.

Everything retunes as the prefix slider moves, and any value can be clicked to copy. The whole result comes out as a Markdown table for a client report.

The Problem It Solves

There is no shortage of subnet calculators. They all answer the same question — what is this subnet? — and they answer it in about a second. That question was never the expensive one.

The expensive question is how should this address space be laid out: a /16 for a head office that has to hold four VLANs today and whatever gets added next year, sized so the printers do not end up wedged between voice and guest Wi-Fi. That work happens in a spreadsheet, gets checked by hand against an inherited list of blocks nobody fully trusts, and then has to be written up for the client.

NetCarve keeps all of it in one place: carve the block visually, name and colour what you carve, let the VLSM solver do the sizing, paste the inherited list in to see what collides — and export the result as Markdown, CSV or JSON when you are done.

Five Jobs, One Extension

  • Quick calculator — IPv4 and IPv6, and it takes whatever you paste: 10.20.0.0/16, 192.168.1.37 255.255.255.0, 2001:db8::/48, even fe80::1%eth0. Reserved ranges are flagged as you type, with deprecated allocations marked as deprecated rather than quietly listed
  • Visual planner — named projects that persist, a block tree you split and join, a VLAN ID and a colour per subnet, and a utilisation bar. Join a branch back and it tells you what you would lose first. Undo and redo throughout, and the tree is fully keyboard-driven: arrows move, S splits, J joins, F2 renames
  • VLSM solver — host counts in, an allocation in address order out, with the waste each block leaves and the free blocks left over. A requirement that does not fit is told exactly how many addresses short it is, and one click sends the whole solution into the planner as a named plan
  • Conflict checker — paste a merger, a site-to-site VPN or an inherited spreadsheet and see the duplicates and containment chains at once. Comments and blank lines are ignored; a line that will not parse is named rather than silently dropped
  • Bases and bit mathematics — one value in decimal, hexadecimal, binary and its address form at a width you choose from 8 to 128 bits, because NOT 0xFF is not the same answer in eight bits as in thirty-two. The bit display is an input: click a bit and every base follows

Where the Address Actually Turns Up

An address rarely arrives while you have a planning tool open. It arrives in a ticket, a config paste, a wiki page someone wrote in 2019. So the calculator also lives in the toolbar popup, at its own size, and a single context-menu item — Analyse … in NetCarve — appears when text is selected, so a block you spotted mid-sentence goes straight into the calculator.

Two Permissions, and Nothing Leaves the Browser

A tool that holds a client’s address plan is a tool that should not be phoning anywhere. NetCarve declares exactly two permissions — storage and contextMenus — and no host permissions and no content scripts at all. It cannot read the pages you visit.

It also makes no network requests of any kind: no backend, no analytics, no crash reporting, no remote fonts. Every calculation happens in your browser and every project stays in your own profile, in chrome.storage.local, under three keys you can read in the privacy policy.

That claim is not left to the readme. tests/e2e/privacy.spec.ts statically scans the shipped bundle and then drives every view with a live request monitor attached, so a stray fetch fails the build rather than the review. The manifest’s permission list is pinned by a test of its own for the same reason: it is the kind of thing that grows by one line during a refactor and is never noticed again.

“Green on My Machine” Is a Different Claim from “Green”

Two releases, v1.2.2 and v1.2.3, went out with a red CI run. Not flaky-red: really red, and for a real reason.

A row in the planner had a flexible name column set to flex: 1 1 8rem, which leaves min-width: auto in place — so the column refused to shrink below its own content. On the machine that built it, every window width measured a slack of exactly zero. On CI, rendering the same monospace a few pixels wider, the row overflowed by eight. The layout invariants caught it in the one environment that had different font metrics, and were ignored because the release had already been tagged and published.

Three things changed after that:

  • The release script now commits, pushes, waits for CI on that exact commit, and only tags and publishes if it is green. A red run leaves the commit on main untagged — fix it and run the same command again with the same version number
  • The layout spec stopped stepping over the band where the planner row is tightest and now samples inside it — 1280, 1100, 1024, 960 and 768 pixels — driving a deliberately awkward plan: sixty-character names, four-digit VLAN IDs, five levels of nesting. It measures slack rather than fit, because a layout that fits exactly is a layout that breaks on someone else’s fonts
  • npm run preview renders every view in both themes to a folder, and the rule is to open them before calling any interface change done. Overflow is mechanical and a test can measure it; ugly is not, and the only thing that catches ugly is an eye

That last one exists because three layout defects had already reached a release before anyone looked at a render: a bit ruler overflowing the 400-pixel popup, a link wrapping across three lines beside it, and a value row stretched across a grid meant for four. None of them showed up in the DOM tests, which assert what the markup says rather than what it measures — and a screenshot baseline would not have helped either, since all three were wrong from their first commit and the baseline would simply have enshrined them.

Built With

  • Chrome extension, Manifest V3, built with WXT and Preact; TypeScript under strict
  • The IP core in src/lib/ip is framework-free and holds 100 % branch coverage, enforced as a CI threshold rather than a habit — it is the part where an off-by-one is a wrong answer rather than a wrong pixel
  • Parsers return errors, they never throw: every parse yields a discriminated union, so malformed input cannot take the interface down. Warnings ride along with successful parses, so a zone ID or an assumed prefix never has to masquerade as an error
  • No WCAG 2.1 A/AA violations, checked by axe-core on every route, in both themes, and in the popup
  • Layout invariants in Playwright: nothing may overflow its container on any route, either theme or three window widths — and in the popup, pinned at 400 pixels, even a deliberately scrollable container has to fit. A failure names the offending element
  • Bundle held under 150 KB gzipped — currently about 44 KB — and the end-to-end suite runs headless against the real build, because Chromium’s headless mode loads unpacked extensions
  • Everything exports: Markdown for the client report, plain text for a ticket, CSV for a spreadsheet, and JSON that is a complete backup you can import again

What’s Next — Vote on the Roadmap

These are the improvements on the table. Vote for the ones you want first — one vote per idea per day, no sign-up. Missing something? Suggest it below and it can end up on this list.

NetBox-compatible export: a bridge into an IPAM

  • A plan carved here still has to be re-typed into whatever IPAM the client runs
  • NetBox reads a prefix import format — emitting it is a converter, not a new feature
  • Tell me which IPAM you actually use; NetBox is the guess, not the answer

Supernetting: the minimal CIDR set covering a range

  • The inverse of the planner — give it a start–end range or a list of blocks and get the smallest covering set
  • The job every firewall rule and route summary needs, done by hand today
  • The arithmetic is already in the IP core; what is missing is the aggregation pass and a view

A Firefox build

  • WXT can target Firefox from the same source, so this is packaging and review, not a rewrite
  • The two permissions and the absence of host access translate cleanly
  • Worth doing only if people are asking — hence the vote

A Polish interface and listing

  • Every string already lives in one file, so the translation is the work, not the refactor
  • The store listing would need a second locale alongside the English one
  • Same question as always: which language do the people using this actually work in?

Suggest a Feature or Report a Problem

Both go straight to me. No account, no ticket system — an email address is optional, and only needed if you want an answer.