Read the presentation as text
Compact encodes small pieces of state as URL-safe text. Put settings in a link, then recover them at the other end. Both programs share the schema, so messages carry values without repeating field names.
The sender and receiver already know the field order and what each value represents. The application passes the values to Compact, then rebuilds the data from the decoded values using that same schema.
Sender:
{
choices: [7, 2, 3],
flags: [true, false, true, false]
}
Compact token:
BCjH00ug
Receiver:
{
choices: [7, 2, 3],
flags: [true, false, true, false]
}
Compact packs the values into bits and includes the lengths needed to separate them. Field names and application-level types stay in the shared schema.
I needed to move structured state through a short, text-only channel. Both ends already knew what the values meant, so I kept the schema in the application and worked out how to encode the values and recover their boundaries.
Compact · Antonio M.
Python · JavaScript · C · Fortran
Technical details
Compact packs ordered sections into a length-prefixed bitstream, then maps six-bit groups to the URL-safe alphabet A–Z a–z 0–9 - _. Field names, domain types and schema versions remain in the application.
The settings example encodes three choice indices and four flags as BCjH00ug. The complete token takes 8 characters, including structural headers. The same fixture takes 33 characters in values-only JSON and 102 in named JSON, with no optional whitespace.
[[7,2,3],[true,false,true,false]] BCjH00ug
Compact packs bits and omits application metadata. Output size depends on the values and their grouping; Compact is not always smaller than JSON. See all fixtures and reproduce the comparison.
| Language | Included functionality |
|---|---|
| Python 3.10+ | Encoding, section decoding, schema helpers and CLI. |
| JavaScript | Encoding, section decoding and schema helpers. Dependency-free ES module. |
| C99 | Encoding and bitstream/text conversion. |
| Fortran 2008 | Encoding and bitstream/text conversion. |
From a checkout of the repository:
python -m pip install -e "./implementations/python[dev]" python -m compact encode --text "hi" python -m compact decode BEhcQ0NI
The encode command prints BEhcQ0NI. No package-registry release is required.
| Mode | Representation |
|---|---|
| 01 / FIXED | Equal-width binary chunks; the width is stored once. |
| 10 / DYNAMIC | Individually length-prefixed binary chunks. |
| 11 / INTEGER | Positive integers represented with prefix codes. |
The portable profile is an empty stream or an ordered list of nonempty sections. Empty sections are outside the interoperable profile. Common fixed-width integer helpers support widths 1–30; text across all four ports is simplest as ASCII without embedded NUL bytes.
Python and JavaScript decode section structure; the application still validates expected modes, widths, ranges and schema versions. The decoders are permissive. Bound and validate untrusted input before decoding, and add authentication or integrity protection where your application requires it. Compact provides neither encryption nor schema negotiation.
Use the supplied bit-to-text conversion functions; byte-oriented Base64 is not a direct substitute. The implementations use strings of bits for inspection and clarity, so small output does not imply optimized memory use or throughput. The C port assumes successful allocations and terminates for some input errors.
python -m pytest implementations/python/tests npm --prefix implementations/javascript test python tools/check_vectors.py python tools/check_vectors.py --all python tools/size_comparison.py --check
The all-language checker requires Node, Make, a C99 compiler and gfortran. Python and JavaScript verify decoded values; C and Fortran demos verify encoder output against shared vectors.
Wire specification · Design decisions · Full input contract · Reproducible size comparisons
I developed the original format and initial implementation from scratch, without AI assistance or a textbook walkthrough. I had not designed a serialization format before; the rules grew out of the problem I was trying to solve.
Implementations: MIT. The specification retains its CC0 notice.

![From structured data to a short string. The sender and receiver already know the field order and what each value represents. The application passes the values to Compact, then rebuilds the data from the decoded values using that same schema. Sender { choices: [7, 2, 3], flags: [ true, false, true, false ] } BCjH00ug Receiver { choices: [7, 2, 3], flags: [ true, false, true, false ] } Compact packs the values into bits and includes the lengths needed to separate them. Field names and application-level types stay in the shared schema. Try your own values ↗](/adrienverhaert/compact/raw/main/docs/readme/assets/example-desktop.png)

