
Creationix Rx Data Store
- 873 installs
- 66 repo stars
- Updated July 9, 2026
- aradotso/trending-skills
creationix-rx-data-store is a developer skill for the RX embedded data format that encodes JSON-shaped documents once and queries them in place with random-access reads and no parsing overhead.
About
creationix-rx-data-store is an expert skill from aradotso/trending-skills for RX, an embedded data store treating JSON-shaped data as a text-safe binary buffer. Developers encode a document once, then run random-access lookups directly on the encoded buffer without rebuilding an object graph or triggering GC pressure from repeated parsing. The skill covers RX encoder/decoder usage in TypeScript, converting JSON to RX, and querying encoded buffers in place—positioned as a no-SQL SQLite alternative for unstructured payloads. Use it when building services that read the same large JSON documents repeatedly and need predictable lookup latency without a full document database.
- O(1) array access and O(log n) object key lookup on encoded buffers
- Automatic deduplication of values and shared schemas
- Text-safe binary encoding that is copy-paste friendly
- Minimal heap allocations (~10 vs millions for JSON)
- Achieves ~18x compression on real deployment manifests (92 MB → 5.1 MB)
Creationix Rx Data Store by the numbers
- 873 all-time installs (skills.sh)
- +6 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #442 of 4,386 Backend & APIs skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aradotso/trending-skills --skill creationix-rx-data-storeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 873 |
|---|---|
| repo stars | ★ 66 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 9, 2026 |
| Repository | aradotso/trending-skills ↗ |
How do you query JSON without parsing overhead?
Encode and query JSON-shaped data with zero-parsing random access lookups using the RX format.
Who is it for?
Backend developers optimizing repeated reads of large JSON documents who want embedded random-access storage without a full database.
Skip if: Relational transactional workloads, ad-hoc SQL analytics, or projects that only need standard JSON.parse once per request.
When should I use this skill?
A developer asks to encode data with RX, convert JSON to RX, query an RX buffer, or implement zero-parse random-access JSON lookups in TypeScript.
What you get
RX-encoded binary buffer with in-place random-access query paths and no repeated JSON parse cycles.
- RX-encoded binary buffer
- Random-access query implementation
Files
RX Data Store
Skill by ara.so — Daily 2026 Skills collection.
RX is an embedded data store for JSON-shaped data. Encode once, then query the encoded document in place — no parsing, no object graph, no GC pressure. Think of it as no-SQL SQLite: unstructured data with database-style random access.
Key benefits:
- O(1) array access, O(log n) object key lookup on encoded data
- Automatic deduplication of values and shared schemas
- Text-safe encoding (copy-paste friendly, no binary tooling needed)
- Minimal heap allocations (~10 vs millions for JSON parsing)
- ~18x compression on real deployment manifests (92 MB → 5.1 MB)
---
Installation
npm install @creationix/rx # library
npm install -g @creationix/rx # CLI (global)
npx @creationix/rx data.rx # CLI (one-off)---
Core API
String API (most common)
import { stringify, parse } from "@creationix/rx";
// Encode
const rx = stringify({ users: ["alice", "bob"], version: 3 });
// Returns a string — store it anywhere you'd store JSON text
// Decode (returns a read-only Proxy)
const data = parse(rx) as any;
data.users[0] // "alice"
data.version // 3
Object.keys(data) // ["users", "version"]
JSON.stringify(data) // works — full JS interopUint8Array API (performance-critical paths)
import { encode, open } from "@creationix/rx";
const buf = encode({ path: "/api/users", status: 200 });
const data = open(buf) as any;
data.path // "/api/users"
data.status // 200Inspect API (lazy AST)
import { encode, inspect } from "@creationix/rx";
const buf = encode({ name: "alice", scores: [10, 20, 30] });
const root = inspect(buf);
root.tag // ":"
root[0].tag // "," (a string key)
root[0].value // "name"
root.length // 4 (key, value, key, value)
// Iterate children
for (const child of root) {
console.log(child.tag, child.b64);
}
// Object helpers
for (const [key, val] of root.entries()) { /* ... */ }
const node = root.index("name"); // key lookup → node
const elem = root.index(2); // array index → node
// Filtered key search (O(log n + m) on indexed objects)
for (const [key, val] of root.filteredKeys("/api/")) { /* ... */ }Escape hatch to underlying buffer
import { handle } from "@creationix/rx";
const h = handle(data.nested);
// h.data: Uint8Array
// h.right: byte offset---
Encoding Options
stringify(data, {
// Add sorted indexes to containers with >= N entries (enables O(log n) lookup)
// Use 0 for all containers, false to disable entirely
indexes: 10,
// External refs — shared dictionary of known values for cross-document dedup
refs: { R: ["/api/users", "/api/teams"] },
// Streaming — receive chunks as they're produced
onChunk: (chunk: string, offset: number) => process.stdout.write(chunk),
});
encode(data, {
indexes: 10,
refs: { R: ["/api/users", "/api/teams"] },
onChunk: (chunk: Uint8Array, offset: number) => { /* ... */ },
});If the encoder used external refs, pass the same dictionary to the decoder:
const data = parse(payload, { refs: { R: ["/api/users", "/api/teams"] } });
const data = open(buf, { refs: { R: ["/api/users", "/api/teams"] } });---
CLI
rx data.rx # pretty-print as tree (default on TTY)
rx data.rx -j # convert to JSON
rx data.json -r # convert to RX
cat data.rx | rx # read from stdin (auto-detect format)
rx data.rx -s key 0 sub # select a sub-value: data["key"][0]["sub"]
rx data.rx -o out.json # write to file
rx data.rx --ast # output encoding structure as JSON
rx data.rx -w # write converted file (.json↔.rx)Full CLI flags:
| Flag | Description |
|---|---|
<file> | Input file (format auto-detected) |
- | Read from stdin explicitly |
-j, --json | Output as JSON |
-r, --rexc | Output as RX |
-t, --tree | Output as tree |
-a, --ast | Output encoding structure |
-s, --select <seg>... | Select a sub-value by path segments |
-w, --write | Write converted file |
-o, --out <path> | Write to file instead of stdout |
-c, --color / --no-color | Force or disable ANSI color |
--index-threshold <n> | Index containers above n values (default: 16) |
--string-chain-threshold <n> | Split strings longer than n (default: 64) |
--string-chain-delimiter <s> | Delimiter for string chains (default: /) |
--key-complexity-threshold <n> | Max object complexity for dedupe keys (default: 100) |
Shell completions:
rx --completions setup zsh # or bashTip — paged, colorized viewing:
p() { rx "$1" -t -c | less -RFX; }---
Proxy Behavior
The value returned by parse/open is read-only:
obj.newKey = 1; // throws TypeError
delete obj.key; // throws TypeError
"key" in obj; // works (zero-alloc key search)
obj.nested === obj.nested // true (container Proxies are memoized)Supported operations on the Proxy:
- Property access:
data.key,data[0] Object.keys(),Object.entries(),Object.values()for...of,for...inArray.isArray().map(),.filter(),.find(),.reduce()- Spread and destructuring
JSON.stringify()
---
Common Patterns
Build-step: convert JSON artifact to RX
import { readFileSync, writeFileSync } from "fs";
import { stringify } from "@creationix/rx";
const json = JSON.parse(readFileSync("manifest.json", "utf-8"));
const rx = stringify(json, { indexes: 10 });
writeFileSync("manifest.rx", rx, "utf-8");Runtime: sparse read from large RX file
import { readFileSync } from "fs";
import { parse } from "@creationix/rx";
const manifest = parse(readFileSync("manifest.rx", "utf-8")) as any;
// Only the accessed values are decoded — everything else is skipped
const route = manifest.routes["/dashboard/projects"];
console.log(route.title, route.component, route.auth);Streaming encode to stdout
import { stringify } from "@creationix/rx";
stringify(largeData, {
onChunk: (chunk, offset) => process.stdout.write(chunk),
});Using external refs for cross-document deduplication
import { stringify, parse } from "@creationix/rx";
const sharedRefs = { R: ["/api/users", "/api/teams", "/api/projects"] };
// Encode multiple documents sharing the same ref dictionary
const doc1 = stringify(data1, { refs: sharedRefs });
const doc2 = stringify(data2, { refs: sharedRefs });
// Decode with the same dictionary
const val1 = parse(doc1, { refs: sharedRefs }) as any;
const val2 = parse(doc2, { refs: sharedRefs }) as any;Low-level inspect traversal (zero allocation)
import { encode, inspect } from "@creationix/rx";
const buf = encode(routes);
const root = inspect(buf);
// Walk object entries without creating JS objects
if (root.tag === ":") {
for (const [key, val] of root.entries()) {
if (key.value === "/dashboard") {
console.log("Found:", val.index("title").value);
break;
}
}
}Type-safe usage pattern
import { parse } from "@creationix/rx";
interface Route {
title: string;
component: string;
auth: boolean;
}
interface Manifest {
routes: Record<string, Route>;
version: number;
}
// Cast after parse — RX Proxy supports all read operations
const manifest = parse(rxString) as unknown as Manifest;
const dashboard = manifest.routes["/dashboard"];---
Format Reference
RX is a text encoding — not human-readable like JSON, but safe to copy-paste.
Every value is read right-to-left. The parser scans left past base64 digits to find a tag character:
[body][tag][b64 varint]
◄── read this way ──| JSON | RX | Description |
|---|---|---|
42 | +1k | tag + (integer), b64 1k = 84, zigzag → 42 |
"hi" | hi,2 | tag , (string), length = 2 |
true | 't | tag ' (ref), built-in literal |
[1,2,3] | +6+4+2;6 | tag ; (array), b64 6 = content size |
{"a":1} | +2a,1:a | tag : (object), interleaved keys/values |
Tags: + integer · * decimal · , string · ' ref/literal · : object · ; array · ^ pointer · . chain · # index
---
When to Use RX vs Alternatives
| Scenario | Use |
|---|---|
| Large artifact, sparse reads | RX |
| Build manifests, route tables | RX |
| Small config files | JSON |
| Human-authored config | JSON/YAML |
| Write-heavy / mutable data | Real database |
| Fixed schema, minimize wire size | Protobuf |
| Relational/tabular data | SQLite |
| Minimizing compressed transfer | gzip/zstd + JSON |
---
Troubleshooting
`TypeError: Cannot set property` on decoded value The Proxy returned by parse/open is read-only by design. To mutate, spread into a plain object first:
const mutable = { ...parse(rx) };
mutable.newKey = "value"; // worksDecoded value looks correct but `instanceof Array` fails Use Array.isArray(val) instead — this is correctly intercepted by the Proxy.
External refs mismatch / wrong values decoded Ensure the exact same refs dictionary (same keys, same arrays, same order) is passed to both stringify/encode and parse/open.
CLI not found after global install
npm install -g @creationix/rx
# If still not found, check your npm global bin path:
npm bin -gInspecting encoded bytes
rx data.rx --ast # shows encoding structure with tags and offsetsOr use the live viewer at [rx.run](https://rx.run/) — paste RX or JSON directly.
Performance: lookups slower than expected Ensure indexes threshold is set appropriately when encoding. For large objects (e.g., 35k keys), use indexes: 0 to index all containers:
stringify(data, { indexes: 0 });---
Resources
- [rx.run](https://rx.run/) — live web viewer, paste RX or JSON to inspect
- [docs/rx-format.md](https://github.com/creationix/rx/blob/main/docs/rx-format.md) — full format spec with grammar and railroad diagrams
- [docs/cursor-api.md](https://github.com/creationix/rx/blob/main/docs/cursor-api.md) — low-level zero-allocation cursor API
- [samples/](https://github.com/creationix/rx/tree/main/samples) — example datasets (route manifest, RPG state, emoji metadata, sensor telemetry)
Related skills
How it compares
Pick creationix-rx-data-store over SQLite or MongoDB when payloads are JSON-shaped, reads dominate, and you need zero-parse in-buffer lookups without a server process.
FAQ
What problem does the RX data store solve?
creationix-rx-data-store addresses repeated JSON parsing cost by encoding documents once into RX binary buffers. Queries run as in-place random-access reads without rebuilding objects or paying parse overhead on every access.
Which languages does creationix-rx-data-store cover?
creationix-rx-data-store focuses on RX encoder and decoder usage in TypeScript, including converting JSON to RX and querying encoded buffers with random-access lookup patterns.
Is Creationix Rx Data Store safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.