This is an experiment and not intended to be used for production wikis.
Giving Every Tiddler a Birth Certificate
The status quo
TiddlyWiki identifies tiddlers by title — and titles must be unique within a wiki. That’s fine and should stay that way. But titles alone can’t answer:
-
When you merge two wikis — are these two differently-titled tiddlers actually the same?
-
When you import — did this tiddler already exist under another name?
-
When you rename — how do external references (URLs, printed notes, conversations) find it again?
There’s no built-in way to say “this is the same tiddler” across wikis or across renames. A c32 field gives every tiddler a permanent identity that is independent of its title.
What this plugin does
The wikilabs/uuid7 plugin assigns every new tiddler a UUID v7 identifier — a 128-bit, globally unique, time-ordered ID defined in RFC 9562 (2024). It stores this ID in two formats:
c32 — Crockford Base32 (29 chars)
01KMP4-ND9W-E8Y8V5YM1DR0-01VG
c7 — Standard UUID hex (36 chars)
019d2c4a-b53c-723c-8d97-d40b70000770
The c32 field uses Crockford’s Base32 encoding in a 6-4-12-4 display format. Same 128 bits as c7, just more compact and a bit more human-friendly:
| c7 (UUID hex) | c32 (Crockford Base32) | TW created
|
|
|---|---|---|---|
| Length | 36 chars | 29 chars | 17 chars |
| Sortable | Yes | Yes | Yes |
| Unique | Globally | Globally | Not guaranteed |
| URL-safe | Yes | Yes | Yes |
| Human-readable | Hard | Better | Readable (but not unique) |
The c32 format adds only 12 characters over the existing created field — in exchange for guaranteed global uniqueness.
Mnemonic phrases
Every UUID is also encoded as 8 adjective-noun-verb triplets:
metal dog soars, clear hawk drifts, proud leaf seeks, ...
You can navigate to a tiddler by typing a few phrase words in the URL:
https://mywiki.com/#metal+dog+soars
Remembering tiddlers
You don’t need to memorize 29 characters. The 6-4-12-4 format is designed so you can remember just the first few and last few characters:
| Remembered | Example | Safe up to |
|---|---|---|
| First 3 + last 4 (6 chars) |
01K + 01VG
|
~5K tiddlers |
| First 5 + last 4 (8 chars) |
01KMP + 01VG
|
~1M tiddlers |
| First group + last group (9 chars) |
01KMP4 + 01VG
|
millions |
Navigation
c32 values work as wiki links and URL hashes — full or partial. Because the 6-4-12-4 format groups bits by meaning, partial matches act as ranged selections:
[[01KMP4]] → all tiddlers from the same ~17 min window
[[01KMP4-ND9W]] → narrows to the exact millisecond
[[E8Y8V5YM1DR0]] → double-click, copy, paste — 56 random bits, clash: 1 in ~72 quadrillion
[[01VG]] → last 4 chars — usually unique in any wiki
https://mywiki.com/#01KMP4 → URL: opens all tiddlers from that time window
https://mywiki.com/#01VG → URL: opens the specific tiddler
The first group is a time-based range — sharing a link like #01KMP4 opens every tiddler created in that ~17-minute session. The last group is a random pinpoint — #01VG almost certainly identifies one specific tiddler.
Input is case-insensitive with Crockford alias support (O→0, I→1, L→1).
Filter operators
Both c32 and uuid7 filters have full feature parity:
[{!!c32}c32[ms]format:timestamp[YYYY-0MM-0DD]] → 2026-03-26
[{!!c32}c32[phrase]] → metal dog soars, clear hawk drifts, ...
[{!!c32}c32[check]] → U (mod 37 check symbol)
[{!!c32}c32[c7]] → 019d2c4a-b53c-... (convert to UUID)
[{!!c7}uuid7[c32]] → 01KMP4-ND9W-... (convert to c32)
Backfill
Existing tiddlers get their c7 and c32 fields on import or via a startup backfill module (dry-run by default). Timestamps are derived from the existing created or modified field.
What it would need to be part of core
The plugin works today with zero core changes — it monkey-patches getCreationFields() at startup. But for first-class support, a small set of core changes would make it cleaner:
-
boot.js— Registerc32as a built-in field type, so it’s available before plugins load (~5 lines) -
wiki.jsgetCreationFields()— Generate UUID v7 natively, store asc32(Crockford Base32), and derivecreatedfrom its timestamp. This eliminates the dual-field redundancy and makes the UUID the source of truth (~10 lines) -
Tiddler constructor — Enforce read-only: once a
c32is assigned, it never changes. This prevents accidental mutation through the UI (~5 lines)
Note: MWS already uses c7 (UUID hex) as a database index. The c32 format encodes the same 128 bits — conversion between c7 and c32 is lossless and trivial, so both can coexist.
That’s roughly 20 lines of core code. Everything else — display, sorting, filtering, serialization — works unchanged because tiddler.fields.created remains a Date object.
Backward compatibility
- Existing tiddlers without UUIDs keep working — the field module falls back to
parseDate - Code reading
tiddler.fields.createdgets aDateobject as before - The UUID is an addition to the timestamp, not a replacement — nothing is lost
Try it
The plugin is available at wikilabs/uuid7 — install it, create a tiddler, and watch the c32 badge appear.
The plugin also provides a c7 field (standard UUID v7 hex format) with full feature parity to c32 — same filter operators, same navigation, same backfill. Both encode the exact same 128-bit value and are 100% compatible with the UUID v7 spec. Having both lets you explore which format you prefer — in the future only one may remain.
Links
- RFC 9562 — UUID v7 (IETF standard, May 2024)
- Crockford Base32 (encoding spec, 2002)
- ULID spec (same concept, predates UUID v7)