ParamDiff — decode, expand, and diff URL query params
A small web app for inspecting and comparing URLs — paste 1–4 URLs, peel back URL-encoding layer by layer, expand nested query strings, and diff query parameters across URLs side by side.
Download index.html — single self-contained file (~150 KB). Open it in any modern browser; no install, no server, no network needed.
See release notes for the changelog and other assets.
- Open the app. Either visit a hosted instance, or download
index.htmlfrom the latest Release and open it in any modern browser. The file is fully self-contained (~150 KB) — no install, no server, no network needed at runtime. Your URLs never leave the page. - Paste a URL into the first input. ParamDiff splits it at the first
?and lists every query parameter as its own row. - Peel encoded values. Click Decode on any row to apply one
decodeURIComponentpass — click again for double-encoded values (%253A → %3A → :). The button disables once nothing further would change. - Drill into nested query strings. When a value carries its own params (typical of OAuth
returnUrl/redirect_uri), click Expand to split it into indented child rows. Each child has its own Decode/Expand/Reset, so you can recurse arbitrarily deep. - Reset. Click Reset to restore the original raw value and collapse any expansion on that row.
- Compare. Click + Add URL for up to 4 URLs. The Diff section under the inputs lists every parameter key seen across them, with one cell per URL — green when all match, red when they differ, grey when missing in that URL.
Tip: the diff reflects whatever decode/expand state you've applied. To compare two URLs fairly, peel them the same number of times.
- Top-level split at the first
?→base+key=valuepairs (no automatic decoding; values are preserved raw so you can choose when to peel). - Decode applies
decodeURIComponentonce. If the result is identical (already fully decoded, or unchangeable), the button disables. - Expand is offered when a value contains
=plus either a?or a chain of&-joinedkey=valuepairs with conservative-looking keys (/^[A-Za-z0-9_\-.]+$/). It splits at the first?(if any), keeps the prefix asnestedBase, and creates child params from the rest. - Diff flattens each URL's param tree to
{ keyPath, value }[], builds a union of keys preserving first-seen order, and renders one row per key with one cell per URL.
- Param keys are matched literally for diffing — if URL A uses
client_idand URL B usesclientId, they show as separate rows. - Bare query strings (
a=1&b=2with no?) are detected by Expand only when keys look conservative — this avoids false positives on prose values. - Repeated keys (
?tag=a&tag=b) keep both, but the diff key path is the same for both, so the second one wins in the per-URL flat map. Rare in practice. - No persistence — refreshing the page clears all inputs.
Build instructions, project layout, and internals live in DEVELOPMENT.md.
MIT — see LICENSE.
