A developer toolbox that never phones home.
Thirteen everyday utilities — JSON, JWT, Base64, URL, regex, UUID, hashing, timestamps, HTTP, Markdown, QR codes — in one consistent interface that runs entirely in your browser.
No account. No upload. No build step. No dependencies.
Every developer keeps a folder of bookmarks to random single-purpose websites: one to pretty-print JSON, one to decode a JWT, one to generate a UUID. They all work. They all also mean pasting your data into somebody else's server, and half of them are wrapped in ads.
DevBox is the same set of tools with three differences:
- It runs locally. There is no DevBox server. Open the page and everything — parsing, hashing, decoding, QR generation — happens in the tab. Turn off your network and it still works.
- It is one app, not thirteen. Same layout, same shortcuts, same copy button, same empty states.
- It has no supply chain. Zero dependencies, zero build step. What you read in
src/is exactly what runs in the browser.
Format, minify and validate with a hand-written parser that reports the exact line, column and offset of a syntax error, plus a caret under the offending character and a "jump to error" button. Syntax-highlighted output, a lazy tree viewer that handles multi-megabyte documents, deep key sorting, duplicate-key detection, and a stats tab (node counts, depth, minified size saving).
Decode the header and payload of a token, with every registered claim explained in plain English.
Shows issued-at, not-before and expiry as real dates and as relative time, computes the token's
lifetime, and warns about alg: none, missing exp, expired tokens and suspiciously long lifetimes.
Decoding is not verification. Nothing here checks a signature, and the UI says so prominently. The token never leaves your machine — not even to the page's own origin.
Encode and decode text, with the URL-safe alphabet, optional padding and MIME line wrapping.
Drop in a file to get Base64 or a data: URL. Decoding detects payloads that are not valid UTF-8,
shows a hex dump, sniffs the file type from magic bytes, and offers the raw bytes as a download.
Four encoding modes (component, strict RFC 3986, whole-URL, form) with precise decode errors that point at the broken escape. Parses any URL into scheme, credentials, host, port, path segments, query parameters and fragment — and flags punycode hosts, credentials in the URL, and private/loopback hosts.
Live matching with highlighted results, numbered and named capture groups with their offsets, a
replacement previewer ($1, $<name>, $&), flag toggles with explanations, a preset library, and
error messages that translate engine-speak into what to actually fix. Warns on patterns whose shape
invites catastrophic backtracking.
v4 (random) and v7 (time-ordered) generation from crypto.getRandomValues, in bulk, with formatting
options (case, hyphens, braces, URN). Paste any UUID to see its version, variant and — for v1/v7 — the
timestamp it encodes.
SHA-256, SHA-512, SHA-384, SHA-1 and MD5 over text or files, in hex, uppercase hex or Base64. File hashing streams in 4 MiB chunks with a progress bar. A verify box compares a published checksum against every digest at once. Broken and legacy algorithms are labelled as such.
Unix ↔ human conversion in seconds, milliseconds, microseconds or nanoseconds, with automatic unit detection. Real timezone support via the platform's IANA database, ISO 8601 with offsets, HTTP dates, day-of-year, ISO week, relative time, and a world clock.
A small request builder: method, URL, query parameters, headers, body presets. Formatted response with
status, timing, size and headers; export as curl. It tells you where the request is going before it
goes, and never proxies through a third party. An optional local proxy is bundled for CORS-blocked
APIs (see Security).
Editor, preview and split view with live word count and reading time, a heading jump bar, and
Ctrl/Cmd+B/I/E formatting. The renderer escapes HTML rather than executing it, so previewing
somebody else's README cannot run their script.
A complete ISO/IEC 18004 encoder written from scratch: numeric, alphanumeric and byte modes, versions 1–40, all four error-correction levels, Reed–Solomon ECC and automatic mask selection. Export as SVG or PNG, with presets for Wi-Fi, vCard, email, phone and geo payloads.
Command palette (Ctrl/Cmd+K), per-tool keyboard shortcuts, copy/clear/reset on every tool, honest
empty and error states, dark and light themes, five accents, two densities, and locally-stored recent
inputs you can switch off or erase.
| JSON — formatter, tree viewer, precise errors | JWT — claims explained, timing, warnings |
|---|---|
![]() |
![]() |
| Regex — named groups and live highlighting | HTTP — request builder and formatted response |
|---|---|
![]() |
![]() |
| QR — encoder written from scratch | Markdown — split view with safe preview |
|---|---|
![]() |
![]() |
| Hash — text and files | Light theme |
|---|---|
![]() |
![]() |
DevBox is static files. There is nothing to compile and nothing to install.
git clone https://github.com/hope8hope/devbox.git
cd devbox
python serve.py # http://localhost:4321Any static server works just as well:
npx serve . # Node
php -S localhost:4321 # PHP
ruby -run -e httpd . -p 4321Why a server at all?
Browsers refuse to load ES modules over file://, and crypto.subtle (used for SHA hashing) is only
available in a secure context. http://localhost counts as secure, so a plain local server is all it
takes. serve.py is 90 lines of standard library, sets the right MIME types on Windows, and sends a
restrictive Content-Security-Policy.
Installing it as an app
In Chrome or Edge, open DevBox and choose Install page as app from the address bar. You get a windowed, offline-capable copy in your dock or taskbar. Firefox and Safari users can bookmark it.
DevBox has no backend. That is not a marketing line, it is a structural property you can verify:
- Open your browser's Network tab and use every tool. The only requests are for DevBox's own files — and after the first load, none at all.
- The one deliberate exception is the HTTP tool, whose entire job is to send a request you wrote to an address you typed. It shows the destination before sending and warns about plaintext, credentials and private hosts.
- Settings and recent inputs live in
localStorageunder thedevbox:prefix. Settings → Erase all local data removes them; it touches nothing else in your browser. - Credentials are never persisted. The HTTP tool redacts
Authorization,Cookie,X-API-Keyand friends before writing history, and the JWT tool stores a 24-character fingerprint rather than your token. - No analytics, no telemetry, no fonts or scripts from a CDN. CI fails the build if any import points outside the repository.
devbox/
├── index.html # the only page; loads src/app.js as a module
├── serve.py # zero-dependency static server for local use
├── src/
│ ├── app.js # shell, routing, global shortcuts
│ ├── core/ # runtime: dom, store, router, settings, storage,
│ │ # hotkeys, clipboard, toast, icons, format, recent
│ ├── lib/ # pure logic, no DOM: json, jwt, base64, url, regex,
│ │ # uuid, md5, hash, timestamp, http, markdown, qr,
│ │ # highlight
│ ├── ui/ # primitives: button, field, panel, tabs, modal, code,
│ │ # tree, pairs, dropzone, feedback, kbd
│ ├── shell/ # sidebar, command palette, shortcut help
│ ├── styles/ # tokens, base, layout, components, tools
│ └── tools/ # one module per tool + registry.js
├── server/ # optional CORS proxy (Node) + its SSRF guards
├── tests/ # harness, specs, browser runner, Node runner
└── docs/ # architecture notes and screenshots
Three rules keep it navigable:
src/lib/never touches the DOM. Every algorithm — the JSON parser, the QR encoder, the JWT decoder — is a pure module that could run in Node, a worker, or a test. That is why the test suite can be thorough without a browser automation framework.- Every tool is independent. A tool is one file exporting
create(context), loaded on demand via dynamicimport(). Tools do not import each other. Deletingsrc/tools/qr.jsand its registry entry removes the QR tool completely. - Shared UI lives in
src/ui/. If two tools need the same widget, it becomes a primitive. Nothing inui/knows what a JWT is.
// src/tools/lorem.js
export const meta = { id: 'lorem', name: 'Lorem', tagline: 'Placeholder text' };
export function create(context) {
const el = document.createElement('div');
// ...build your UI, using src/ui primitives...
return {
el,
actions: [/* buttons for the tool header */],
shortcuts: [{ combo: 'mod+enter', label: 'Generate', run: generate }],
onMount() {},
destroy() {},
};
}Then add an entry to src/tools/registry.js. That is the whole integration: the sidebar, command
palette, routing, keyboard help and dashboard card all read from the registry.
See docs/architecture.md for the module contract in detail.
node tests/run.js # Node 18+, also `npm test`
node tests/run.js qr # only specs whose name matches "qr"Or open /tests/ in the browser for the same specs with a UI — useful because half of DevBox talks
to WebCrypto, Intl and the File API, and you want to know it works in the engine you actually use.
The suite (224 tests) covers JSON formatting and error positions, JWT decoding and timing, Base64 round-trips, URL encoding, regex behaviour, timestamp and timezone conversion, hashing against the published NIST/RFC vectors, Markdown rendering and XSS resistance, the QR encoder, and the proxy's SSRF guards.
How the QR encoder was verified
Structural tests are not enough for 600 lines of bit manipulation, so the encoder was checked against independent implementations during development:
- Decoded with jsQR: 160 codes covering every version (1–40) at every error-correction level were rendered to a canvas and read back. 159 round-tripped exactly; the one failure (version 23-L) reproduces identically with a reference encoder, so it is a decoder limitation, not an encoding bug.
- Compared with qrcode-generator: matrices are bit-identical for the same input, version, level and mask.
That process caught a genuine bug — one wrong row in the error-correction table produced codes no
scanner could read — which is why tests/specs/qr.test.js now asserts the full ISO/IEC 18004 capacity
table for all 160 version/level combinations.
| Area | What DevBox does |
|---|---|
| JWT | Decodes locally, never verifies, never transmits. States this in the UI, and warns about alg: none, expiry and long lifetimes. |
| Markdown | Escapes all HTML instead of rendering it; URLs are restricted to http, https, mailto, tel and relative paths; control characters are stripped so java\0script: cannot sneak through. |
| Highlighting | Syntax highlighting builds elements with textContent, never HTML strings. |
| HTTP tool | Names the destination before sending; warns about plaintext, credentials and private hosts; redacts secrets from history. |
| Storage | Namespaced to devbox:, size-capped, and erasable from Settings. |
| CSP | serve.py and index.html set a restrictive policy: no external scripts, styles, fonts or frames. |
| Supply chain | Zero dependencies; CI fails if a non-relative import appears. |
Browsers block cross-origin responses that lack CORS headers. For APIs you control, the fix is CORS on
the server. When that is not possible, server/proxy.mjs will relay a request from your own machine:
node server/proxy.mjs # http://127.0.0.1:8787A URL-fetching server is an SSRF engine by construction, so this one:
- binds to
127.0.0.1, never0.0.0.0; - accepts only
http/https; - resolves the hostname and rejects every loopback, private, CGNAT, link-local, multicast or reserved address — including the IPv6 and 6to4/NAT64 forms that wrap an IPv4 address;
- connects to the address it validated, so DNS cannot be re-pointed between check and connect;
- follows redirects manually, re-validating every hop;
- strips hop-by-hop headers, rejects header injection, caps body size and times out;
- accepts requests only from known local origins.
DEVBOX_ALLOWED_HOSTS, DEVBOX_ALLOWED_PORTS and DEVBOX_ALLOW_PRIVATE narrow or (deliberately)
widen this. The guards are unit-tested in tests/specs/ssrf.test.js.
Found a vulnerability? See SECURITY.md.
| Shortcut | Action |
|---|---|
Ctrl/Cmd + K |
Command palette |
Ctrl/Cmd + / |
Focus tool search |
? |
Show every active shortcut |
Alt + 1…9 |
Jump to a tool |
Ctrl/Cmd + Enter |
Run the current tool's main action |
Ctrl/Cmd + Shift + C |
Copy the result |
Ctrl/Cmd + Shift + Backspace |
Clear |
Ctrl/Cmd + Shift + L |
Toggle theme |
Ctrl/Cmd + , |
Settings |
Tools add their own — Ctrl/Cmd+Shift+M minifies JSON, Ctrl/Cmd+Shift+D downloads a QR PNG, and so
on. Press ? to see what is live right now.
Chrome, Edge, Firefox and Safari, current and previous major versions. DevBox uses crypto.subtle,
Intl.DateTimeFormat, ES modules, color-mix() and CSS nesting-free custom properties — all baseline
in 2023+ browsers. It degrades honestly: if WebCrypto is missing, the Hash tool says so instead of
silently producing nothing.
Bug reports, tools and refinements are all welcome — see CONTRIBUTING.md.
The short version: no dependencies, no build step, src/lib/ stays pure, and new logic comes with
tests.
MIT.









