Semantic JSON minification system with bidirectional encoding/decoding
npm install typeshrinkA semantic JSON minification library that transforms verbose property keys into deterministic short codes for reduced payload sizes.
- Bidirectional encoding/decoding - Lossless compression and restoration
- Blueprint pattern - Single source of truth for schema and types
- DJB2 hashing - Fast, deterministic key generation
- Collision detection - Fail-fast mechanism prevents data corruption
- Type safety - Full TypeScript support with inferred types
- ~30% size reduction - Typical compression on JSON payloads
``bash`
npm install typeshrink
`typescript
import { createMinifier } from 'typeshrink';
// Define your schema blueprint (this is the source of truth)
const SCHEMA_BLUEPRINT = {
note: '',
data: {
address1: '',
address2: '',
city: '',
additional_fields: { cpf: '' }
},
cost: {
total_cost: 0,
shipping_cost: 0
}
};
// Create a minifier instance
const minifier = createMinifier(SCHEMA_BLUEPRINT);
// Your data
const payload = {
note: 'Express delivery',
data: {
address1: '123 Main Street',
address2: 'Apt 4B',
city: 'New York',
additional_fields: { cpf: '123.456.789-00' }
},
cost: {
total_cost: 150.00,
shipping_cost: 15.00
}
};
// Encode for transmission/storage
const minified = minifier.encode(payload);
// { "n7k": "Express delivery", "dJ2": { "aX9": "123 Main Street", ... } }
// Decode back to original
const restored = minifier.decode(minified);
// Full original payload with types preserved
`
Creates a minifier instance from a schema blueprint.
Parameters:
- blueprint: T - Object defining the schema structureoptions?: MinifierOptions
- - Optional configuration
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| seed | number | 5381 | Hash seed (change to resolve collisions) |strict
| | boolean | false | Throw on unknown keys during encoding |
Returns: Minifier with methods:encode(data: T): JsonValue
- - Minify datadecode(data: JsonValue): T
- - Restore datagetKeyMaps(): KeyMaps
- - Get encode/decode lookup tablesgetBlueprint(): T
- - Get original blueprintgetKeys(): string[]
- - Get all extracted keys
If two keys hash to the same short code, a CollisionError is thrown at initialization:
`typescript
import { createMinifier, CollisionError } from 'typeshrink';
try {
const minifier = createMinifier(blueprint);
} catch (error) {
if (error instanceof CollisionError) {
console.log(Collision: "${error.key1}" and "${error.key2}" -> "${error.shortKey}");
// Solution: Change the seed or rename one of the keys
}
}
// Resolve by changing the seed
const minifier = createMinifier(blueprint, { seed: 12345 });
`
1. Blueprint Analysis - Recursively extracts all unique keys from your schema
2. Hash Generation - Uses DJB2 algorithm to create 3-char codes: [FirstChar][Hash1][Hash2]encode()
3. Collision Check - Validates no two keys map to the same code (fail-fast)
4. Encoding - Replaces keys with short codes during decode()
5. Decoding - Restores original keys during
For maximum compression, combine typeshrink with CBOR (Concise Binary Object Representation). This gives you both key minification and binary encoding.
`bash`
npm install cbor-x
`typescript
import { createMinifier } from 'typeshrink';
import { encode as cborEncode, decode as cborDecode } from 'cbor-x';
const SCHEMA = {
user: { name: '', email: '' },
items: [{ id: 0, price: 0 }],
total: 0
};
const minifier = createMinifier(SCHEMA);
// === ENCODING (before transmission/storage) ===
function compress(data: typeof SCHEMA): Buffer {
const minified = minifier.encode(data); // Shorten keys
return cborEncode(minified); // Binary encode
}
// === DECODING (after receiving/reading) ===
function decompress(buffer: Buffer): typeof SCHEMA {
const minified = cborDecode(buffer); // Binary decode
return minifier.decode(minified); // Restore keys
}
// Example usage
const payload = {
user: { name: 'John Doe', email: 'john@example.com' },
items: [
{ id: 1, price: 29.99 },
{ id: 2, price: 49.99 }
],
total: 79.98
};
const compressed = compress(payload);
const restored = decompress(compressed);
// Size comparison
const jsonSize = Buffer.byteLength(JSON.stringify(payload));
const compressedSize = compressed.length;
console.log(JSON: ${jsonSize} bytes → CBOR+typeshrink: ${compressedSize} bytes);`
// Typical: 50-60% total reduction
| Format | Typical Size | Reduction |
|--------|-------------|-----------|
| Raw JSON | 100% | baseline |
| typeshrink + JSON | ~70% | ~30% |
| Raw CBOR | ~75% | ~25% |
| typeshrink + CBOR | ~50% | ~50% |
> [!TIP]
> CBOR is particularly effective for payloads with numbers, booleans, and binary data since it uses a more compact binary representation than JSON's text format.
Typical results on JSON payloads:
| Metric | Value |
|--------|-------|
| Compression ratio | 20-40% reduction |
| Encoding speed | < 1ms for typical payloads |
| Hash collisions | Extremely rare (resolvable via seed) |
`bashInstall dependencies
npm install
MIT