Building a 100% Client-Side Developer Workstation: ULID, UUID, and JSON Tools
Modern software development requires dealing with unique identifiers, timestamps, encoded tokens, and raw JSON payloads daily. Many developers rely on online formatters, decoders, and generators to speed up their workflow. However, sending sensitive database keys, credentials, or API responses to remote servers raises privacy and security concerns.
To address this, I built a client-side developer workstation at: https://ulidtool.net/
It is a single-page application that runs entirely in the browser, offering a suite of high-performance tools for identifiers, timestamps, and JSON manipulation with zero tracking and absolute data privacy.
Here is a breakdown of the features I built, the design decisions behind them, a technical comparison of modern unique identifiers, and a guide on choosing the right format.
1. Why I Built This (The Client-Side Approach)
Most developer tools on the web perform computations or store configurations on backend servers. This approach has three key drawbacks:
- Security Risks: Pasting proprietary data, auth tokens, or production database keys exposes them to third-party databases or logging tools.
- Network Latency: Round-trips to servers slow down quick operations like minification or validation.
- Offline Inoperability: Standard web tools fail when working in restricted environments or when internet access is down.
To guarantee privacy, this workstation performs all operations locally in the user's browser. When configuration state needs to be shared (like specific generation settings or JSON data), it is serialized into the URL hash fragment (the part following the # sign). Because URL hashes are processed entirely by the browser, they are never sent to the hosting server in HTTP request headers.
This privacy boundary and the risk of server data leaks are illustrated below:
2. Choosing the Right Identifier: ULID vs UUID vs CUID vs NanoID vs Snowflake
Different systems have different requirements for uniqueness, database index friendliness, and public readability. To help developers navigate this, the workstation provides generation and conversion tools for multiple formats.
Here is a comparison of modern unique identifiers:
| ID Type | Bit Size | Chronologically Sortable? | Encoding / Readability | Best Use Case |
|---|---|---|---|---|
| UUID v4 | 128-bit | No | Hexadecimal with hyphens | General random identifiers |
| UUID v7 | 128-bit | Yes | Hexadecimal with hyphens | Database primary keys (modern) |
| ULID | 128-bit | Yes | Crockford's Base32 | Database keys, audit logs, timelines |
| NanoID | Variable (default 126-bit) | No | Customizable URL-safe Base64 | Public URLs, routing slugs |
| CUID2 | Variable (default 128-bit) | No | Lowercase alphanumeric | Client-side seeds, secure references |
| Snowflake | 64-bit | Yes | Decimal integer | High-throughput distributed databases |
Use the decision tree graphic below to select the appropriate identifier format for your system architecture:
UUID v4 (RFC 4122)
The classic random 128-bit identifier. While excellent for general randomness, its lack of ordering makes it highly problematic for database primary keys. When inserted into B-Tree indexes, random UUIDs cause page splits and high fragmentation, severely degrading database write performance.
UUID v7 (RFC 9562)
A modern version of the UUID standard that places a millisecond-precision timestamp at the beginning of the ID, followed by random bits. This keeps the identifier index-friendly (ordered chronologically) while maintaining binary and string compatibility with legacy 36-character UUID systems.
ULID (Universally Unique Lexicographically Sortable Identifier)
A 128-bit identifier that combines a 48-bit timestamp with 80 bits of random entropy. ULIDs are encoded using Crockford's Base32 alphabet, which excludes ambiguous characters (I, L, O, and U) to prevent readability errors. ULIDs are case-insensitive, easier to select with a double-click than hyphenated UUIDs, and sortable out-of-the-box.
NanoID
A tiny, secure, URL-friendly unique string ID generator. Unlike standard formats, it allows configuring a custom alphabet and length. This is useful for short, public-facing identifiers (like YouTube video IDs) where aesthetics and length matter.
CUID2
Designed specifically for modern web applications. CUID2 offers strong collision resistance, prevents predictability (avoiding sequential guessing attacks), and runs efficiently in both browser and server environments. It is lowercase alphanumeric and starts with a letter, making it safe for HTML element IDs and CSS selectors.
Snowflake ID
Originally developed by Twitter, Snowflake IDs are 64-bit integers composed of a timestamp, worker ID, data center ID, and a sequence counter. Because they are smaller than 128-bit keys, they use less memory and storage, making them ideal for high-throughput distributed database architectures.
3. The JSON Development Suite
JSON processing is central to modern APIs. The workstation embeds Monaco Editor (the editor engine behind VS Code) to provide formatting, validation, and advanced diff operations.
JSON Diff Compare
Spotting differences between two JSON structures is a daily necessity. The workstation supports:
- Live Monaco Comparison: Uses monaco.editor.createDiffEditor to render side-by-side or inline comparisons dynamically. It adapts to screen width, rendering side-by-side on desktop and inline on mobile.
- Flattened Path View: For large JSON files, line-by-line diffs can be difficult to read. The Flattened Path View flattens both documents into dot-separated key paths (e.g. database.port) and displays additions, removals, and changes in a clean, searchable table.
JSON Path Tester
Allows developers to query and validate JSON documents using JSONPath expressions (e.g. $.store.book[*].author). It evaluates queries instantly in the browser and formats the resulting matches.
JSON Patch Applier and Generator (RFC 6902)
- Patch Generator: Compares a source and target JSON document to output a spec-compliant list of patch operations (add, remove, replace). Instead of importing a heavy npm library, I wrote a custom, dependency-free recursive comparison algorithm in vanilla JavaScript to traverse deeply nested structures, track array shifts, and escape pointer paths.
- Patch Applier: Applies RFC 6902 patch operations to a document, supporting add, remove, replace, move, copy, and test commands with strict path validation toggles.
4. Other Workstation Capabilities
The workstation groups utilities into logical sections to streamline standard developer tasks:
- ULID & UUID Decoders: Extract metadata (creation timestamps, versions, variants, node IDs) from raw identifier strings.
- JWT Decoder: Decodes JSON Web Tokens into Header, Payload, and Signature. Since it runs 100% client-side, developers can inspect sensitive authentication tokens without risking key exposure.
- Base64 Converter: Handles text and binary encoding/decoding.
- Timestamp Converter: Converts unix timestamps (epoch seconds and milliseconds) to ISO 8601, RFC 2822, and human-readable dates across multiple time zones.
5. Frequently Asked Questions
Can I use the workstation offline?
Yes. The workstation is built as a single-page application. Once loaded, all generation, decoding, conversion, and comparison logic execute locally inside the browser. It does not make external API requests.
Are shared URLs secure?
Yes. If you share a URL config (for example, with encoded data), the data is stored in the URL hash fragment (following #). Browsers do not send this fragment to web servers. The data stays on your machine and on the machines of the people you share the link with.
Why does Crockford's Base32 matter for ULIDs?
Standard Base64 or Hexadecimal encodings can lead to reading mistakes. Crockford's Base32 excludes the characters I, L, O, and U to avoid confusion with numbers 1 and 0, and eliminates accidental profanity in generated strings.
6. Let's Discuss
Which unique identifier is your default choice in modern systems, and why?
- Team UUID (v4 / v7)
- Team ULID
- Team NanoID / CUID2
- Team Snowflake Drop a comment below explaining your stack and database setups. ---
Conclusion
Try it live: https://ulidtool.net/
Feedback and suggestions are welcome.

Top comments (0)