What the Developer Data Toolkit cannot do
Every utility here has an edge. This page states where each one stops, why, and what to use instead — so you find out before you depend on it, not after.
Constraints that apply to everything
All processing happens in one browser tab, using your device’s memory. That is what makes the privacy claim true, and it is also the source of every size limit below. Each utility caps its input explicitly and refuses oversized work with a clear message rather than freezing the page.
Two features need a secure context — https:// or localhost — because that is the only place browsers expose the Web Crypto API: SHA hashing and UUID generation. Opened over plain HTTP on a LAN address, both will tell you they are unavailable. Neither will substitute a hand-written implementation, because the browser’s own is the one worth trusting.
There is no service worker, so the first load needs a network connection. After that, nothing the toolkit does requires one.
JSON
Strict RFC 8259 only. Comments, trailing commas, single-quoted strings, unquoted keys and NaN or Infinity are all rejected — these are JSON5 or JavaScript object literal features, not JSON. The validator names which one it found, so the rejection is at least actionable.
Numbers are parsed as IEEE-754 doubles, which is what JSON.parse does. Integers beyond 2^53 lose precision on the round trip. If you are handling large identifiers, they need to be strings in the JSON itself — there is no way for any JavaScript tool to recover a value the format cannot represent.
Key order is preserved as written, and the optional sort applies to object keys only. Array order is never changed, because reordering an array changes the data rather than its presentation.
Documents over about 8 million characters are refused.
Syntax converters
Nine directed conversions — JSON to YAML, YAML to JSON, JSON to XML, XML to JSON, JSON to TOML, TOML to JSON, YAML to TOML, TOML to YAML, JSON to CSV. Anything not on that list is refused with a sentence naming the route that does exist. The full set of conventions is on the converters page; this section states where the conversions stop.
CSV is written and never read. Reading it means guessing a delimiter, a quoting dialect, a header row and a type for every cell — four guesses a converter gets wrong quietly.
Comments are lost in every direction, in every format that has them.
YAML is loaded with a restricted schema that can only produce JSON-shaped data. Custom and language-specific tags — !!js/function, !!python/object/apply, !!binary, !!timestamp, !!set, !!omap — are refused. That is deliberate: a loader that constructs those is an arbitrary-object constructor.
Under the default JSON schema, "~" and an empty value are strings rather than null, and "yes" is the string "yes". The Core schema option resolves those the way most people expect. Both are safe; they differ in scalar interpretation, and the tool explains which is which at the point of choice. Neither reads NO as false — that is a YAML 1.1 behaviour and this is YAML 1.2.
A multi-document YAML stream becomes an array of documents, because no other format here has a stream. Anchors and aliases are resolved rather than preserved, a recursive alias is refused, and a document that expands past a million values once its aliases are followed is refused — the YAML "billion laughs" pattern. A repeated mapping key keeps the last value, and the tool says so.
YAML infinity and NaN have no representation in any target format. Rather than let JSON.stringify silently write null, the tool converts and warns you that it happened.
An XML document containing a DOCTYPE is refused outright, harmless ones included, so no external entity can ever be resolved and no entity chain can ever be expanded. There is no option to allow it. XML mixed content loses the position of text relative to child elements, a single repeated element cannot be distinguished from a non-repeated one, and every value is a string unless type inference is switched on.
TOML has four temporal types that JSON, YAML and XML do not have. Each becomes the RFC 3339 string it was written as, so a TOML round trip changes those values into strings; there is no lossless path. TOML has no null, so null keys are dropped from TOML output. A TOML document’s root must be a table, so a JSON array or scalar cannot become TOML at all. Integers past 2^53 become strings rather than being silently rounded.
CSV cannot distinguish an empty string from a null. Nested values are flattened into dotted column names, so a key that already contains a dot produces an ambiguous name that is warned about rather than escaped. Text cells beginning with =, +, -, @, a tab or a carriage return are prefixed with an apostrophe, because spreadsheets execute them as formulas.
Input is capped per format: 8 million characters for JSON, 4 million for XML, 2 million for YAML and TOML. CSV output is capped at 100,000 rows and 2,000 columns.
Base64
Text only. There is no file upload here: to encode a file you would need to read it, and this toolkit is built around a text box. Use a file-oriented tool for that.
Decoding produces text when the bytes are valid UTF-8, and reports a clean error when they are not — at which point the byte view will show you the hex instead. An arbitrary binary payload is not text, and pretending otherwise would corrupt it.
Inputs over about 4 million characters are refused.
URL encoding
The three rules offered — component, whole-URL and form — are the three the platform defines. Application-specific variants (AWS SigV4 canonicalisation, OAuth 1.0a percent-encoding) differ in small ways and are not provided.
The URL inspector needs an absolute URL with a scheme. A relative path cannot be decomposed into host, path and query, because it does not have them.
Internationalised domain names are shown as the browser normalises them, which may be punycode rather than the original script.
HTML entities
The named entity table covers the practical subset — markup-critical characters, typography, currency, arrows, maths, Greek and Latin-1 — not all 2,231 HTML5 named references. Names outside it are listed for you and left exactly as written, because inventing a character would be worse than leaving the text alone.
A terminating semicolon is required. HTML5 tolerates a few legacy references without one, but resolving those correctly depends on the surrounding markup, which a standalone text tool does not have.
Decoding is a single pass, so "&lt;" decodes to the text "<" rather than to "<". That is correct: the double encoding was presumably intentional.
This escapes text for HTML. It is not an HTML sanitiser — it will not take a document full of markup and strip the dangerous parts. That is a different and much harder job.
Timestamps
Unit detection is a heuristic: 10^11 and above is read as milliseconds. It is always shown and always overridable, but it is a guess on ambiguous input.
Microsecond and nanosecond timestamps, which some databases emit, are not detected. Divide by 1,000 or 1,000,000 first.
Conversions use POSIX time, which has no leap seconds — 23:59:60 does not exist here, as it does not in any Unix timestamp.
Local-time rendering uses your browser’s configured zone. You cannot pick an arbitrary IANA zone to render in.
Values beyond roughly ±273,790 years from the epoch exceed what JavaScript dates can represent and are refused.
UUIDs
Only version 4 (random) is generated. Versions 1 and 6 need a MAC address and a stable clock sequence; version 7 needs a monotonic counter to be worth anything; versions 3 and 5 are name-based and need a namespace and a hash the browser does not expose for this purpose.
The validator recognises the canonical text form and reports version and variant. It cannot tell you whether a UUID was generated well — a version-4 UUID produced from a weak generator looks identical to a good one.
A batch is capped at 500 values.
Without Web Crypto, nothing is generated. Falling back to Math.random() would produce predictable identifiers, so the tool refuses instead.
SHA hashes
Only SHA-1, SHA-256, SHA-384 and SHA-512, because those are what SubtleCrypto implements. MD5 is absent by necessity and by choice.
SHA-1 is present for legacy interoperability and is labelled as cryptographically broken everywhere it appears. Do not use it for anything whose security matters.
Text only — no file hashing, for the same reason base64 has no file input.
No HMAC, no key derivation, no password hashing. Passwords need a slow, salted, memory-hard function such as Argon2id, scrypt or bcrypt; a fast general-purpose hash is the wrong tool and using one is a serious mistake rather than a small one.
Text diff
Line-level comparison only. There is no word-level or character-level highlighting within a changed line.
A modified line appears as a removal plus an addition, which is how a line-based edit script represents it.
Identical leading and trailing lines are trimmed before the comparison, so large files differing in one place are fast. What remains is capped at 2,000 differing lines per side, beyond which the tool refuses rather than attempting an allocation that would kill the tab.
There is no three-way merge, no patch application and no syntax awareness.
JWT decoding
Decoding only. Signatures are never verified, and this will not change — the reasoning is set out in the token guide.
Encrypted tokens (JWE, five segments) cannot be decoded without the key. The tool identifies them and stops.
Nested tokens are not unwrapped automatically; decode the inner token separately.
Claims outside RFC 7519’s registered set are shown without interpretation, because their meaning is application-specific.
Tokens over 200,000 characters are refused.
HTML WYSIWYG editor
The sanitiser is an allowlist for this editor’s own output, built on a string tokeniser rather than a full HTML5 parser. It is not a general-purpose XSS filter, and using it as one would be a mistake: a browser can parse a deliberately malformed payload into a different tree than this tokeniser does. Untrusted HTML belongs in a server-side sanitiser running against a real parser.
Only the listed elements survive: paragraphs, headings, emphasis, lists, links, quotes, code, and a handful of inline tags. Everything else is unwrapped, so its text remains and its tag does not. Images, tables, colours, fonts and inline styles are all absent, and there is no way to add them.
script, style, iframe, object, embed, form, svg, math and the other raw-text or foreign-content elements are removed together with everything inside them.
Links may use http, https, mailto, tel, ftp or a relative address. Anything else — including javascript:, data: and blob: — is refused, as is an address containing a character reference outside this tool’s entity table.
The editing surface uses document.execCommand. It is deprecated, its replacement is not implemented in any browser, and behaviour differs between engines, particularly for nested lists. Source mode is the escape hatch when a command does the wrong thing.
Documents over 500,000 characters are refused.
Chmod calculator
The twelve permission bits only: read, write and execute for owner, group and other, plus setuid, setgid and sticky. Access control lists, extended attributes, SELinux contexts, capabilities and Windows ACLs are all outside what a mode can express.
The command it builds is text for you to copy. Nothing is executed, and no file on your machine is read or changed — the path field exists only to fill in the command.
It does not calculate umask arithmetic, and it does not know what mode a given file currently has, because a web page cannot see your filesystem.
Docker run to compose
One docker run command becomes one service. Multi-container setups have to be assembled by converting each command and merging the results yourself.
--mount, --gpus, --device, --link, --volumes-from, --network-alias and a dozen other flags have no equivalent this converter will write. Each produces a warning naming the flag rather than disappearing.
A flag the converter does not recognise is treated as taking no value, and says so in a warning. If it did take one, that value is misread — remove the flag and add its effect by hand.
Nothing is executed, evaluated or passed to a shell: the command is split by a tokeniser that understands quoting and nothing else. The converter therefore cannot expand $VARIABLES, resolve $(subshells) or read an --env-file, because all three would mean running something or opening a file.
The output is checked for correct YAML quoting but is not validated against the Compose Specification, and no image is contacted to confirm it exists.
Commands over 100,000 characters are refused.
Crontab generator
Five-field crontab syntax only. Six-field Quartz and systemd expressions are rejected with an explanation, as are the non-standard operators L, W, # and ?, and @reboot, which has no schedule to preview.
The day-of-month and day-of-week fields are combined with OR when both are restricted, matching Vixie cron. The tool warns whenever that applies, because it is the most common misreading of a cron line.
Next-run times come from the browser’s Intl time-zone data. They are a preview, not a promise: the machine running cron may use a different zone, a different tzdata version, or may simply not be running at the time.
The preview searches five years ahead. A schedule rarer than that — 29 February, for instance — will show fewer than five runs.
What happens to what you paste
- Every conversion, hash, decode and diff runs in your browser tab. No input is uploaded, logged or stored on a server, because there is no server involved once the page has loaded.
- Hashes come from the browser’s own Web Crypto implementation, and UUIDs from its cryptographically secure random generator. Neither involves a network call.
- Nothing you type is written to local storage or a cookie. Reloading the page discards it; closing the tab discards it.
- There is no analytics script, no advertising script and no third-party request of any kind. You can confirm all of this in your browser’s network panel — the page makes no requests after it loads.
- That said: a JWT or an API key is a live credential. The safe habit is never to paste one into a web page you did not write, however trustworthy its claims — including this one.
Questions
Will you add file upload for hashing or base64?
Possibly, but it is a different kind of tool — file reading, progress reporting, memory guards for large files — rather than a small addition to a text box. Today the answer is no.
Will you add signature verification to the JWT decoder?
No. Verification requires the issuer’s key and an algorithm pinned outside the token, and a web page asking for either is asking for the ability to forge tokens. The limitation is the feature.
Why refuse large inputs instead of just being slow?
Because "slow" in a browser tab means an unresponsive page, and on a phone it often means the tab is killed and your input is gone. A clear refusal with a stated limit is more useful than a spinner that never ends.
Can I use this offline?
After the page has loaded, yes — nothing the toolkit does needs the network. There is no service worker, so the first load does require a connection.
Limitations
- This page is itself the limitations list; each section above states what one utility cannot do.
- Limits are enforced in code and reported in the interface, not merely documented here.
Last reviewed 2026-09-13.