What NetDash Toolkit is
NetDash Toolkit is a network engineering dashboard: 48 tools covering subnet math, VLSM planning, VLAN and ACL config generation, DNS and TLS inspection, and a set of developer utilities. It ships twice from one codebase, as a static website and as a desktop app.
The shape of the project
Section titled “The shape of the project”There is no backend. next.config.mjs sets output: "export", so next build emits a directory of static files and nothing runs on a server. That single decision drives most of what follows: there is no API to send your subnet to, no request log to leak, and no server-side rendering to reason about.
| Property | Value | Why it matters |
|---|---|---|
| Framework | Next.js 15 App Router, output: "export" |
no server, so no server-side data handling |
| Routing | trailingSlash: true |
every URL is a directory with an index.html, which is what a dumb static server needs |
| Tools | 48, enumerated in lib/tool-registry.ts |
one list drives the sidebar, search, routes, and these docs |
| Offline tools | 36 of 48 | the majority of the app works with no network at all |
| Desktop shell | Electron 43, serving out/ over loopback HTTP |
the same static export, plus capabilities a browser lacks |
| Licence | MIT | fork it, self-host it, ship it |
The tool count and the offline count in that table are not hand-maintained. They are read out of the registry when these docs are built, and a unit test in tests/unit/tool-registry.test.ts asserts that each tool’s declared runtime.offline matches whether the component actually performs network I/O.
The registry is the source of truth
Section titled “The registry is the source of truth”Every tool is one entry in lib/tool-registry.ts carrying its slug, label, description, category, feature list, search keywords, and a lazy component loader. The route app/(shell)/tools/[slug]/page.tsx enumerates those slugs in generateStaticParams, with dynamicParams = false, so an unknown slug fails the build instead of rendering an empty page.
Entries that leave the device also carry a runtime block:
runtime: { offline: false, thirdParty: ["cloudflare-dns.com", "dns.google"], desktopOnly: ["direct DNS queries"],}thirdParty names the hosts that receive your input. desktopOnly names capabilities that exist only in the Electron build. The comment above the interface is blunt about why it exists: the dashboard used to claim “100% offline ready” while a dozen tools did network I/O, and nothing in the registry could contradict it.
What it is not
Section titled “What it is not”- Not a monitoring system. Nothing polls, nothing alerts, nothing runs while the tab is closed.
- Not a substitute for
nmap,dig, ormtr. The desktop build shells out to your system’sping,tracerouteandarpand parses their text output; it does not reimplement them. - Not authenticated by default. Sign-in exists only to sync saved projects, and every tool works without it.
- Not notarized on macOS. Builds are ad-hoc signed because notarization needs a paid Apple Developer ID. Releases and verification covers what to run instead of trusting Gatekeeper.
Not in scope (yet)
Section titled “Not in scope (yet)”- A CSP without
'unsafe-inline'. Both builds now send a Content-Security-Policy, butscript-srcandstyle-srcboth carry'unsafe-inline', because a static export has no per-response anything to bind a nonce to and its inline hydration payload differs page by page, so closing it means a per-path hash policy rather than one extra token. Building the desktop app works the arithmetic, including the inline-script counts measured fromout/. Safe to defer because there is no backend and the tree’s onedangerouslySetInnerHTMLwrites build-time constants.script-srcalso carries'wasm-unsafe-eval', which the documentation search genuinely needs and which permits WebAssembly compilation only, noteval. - A
connect-srcallowlist.connect-srcis'self' https: http:on purpose, and the comment inelectron/csp.tssays why: the network tester, port probe, ping fallback and TLS trust probe all fetch a host you type, so an allowlist would have to contain the whole internet or break the tools. The mitigation is that the hosts the app itself contacts are enumerated and tested rather than restricted at the CSP layer. - Auto-update in the desktop app.
electron-builder.jsonsets"publish": nulland there is noelectron-updateranywhere in the tree, so updates are a manual download or abrew upgrade. Deferring it is defensible for a free project with signed release artifacts, since the verification path in the docs does not depend on an update channel being trustworthy. - A sandboxed renderer.
webPreferencessetscontextIsolation: trueandnodeIntegration: falsebut leavessandbox: false. The navigation allowlist and the single-entry permission allowlist are what currently keep the preload bridge away from remote origins.