5 releases
Uses new Rust 2024
| new 0.1.4 | Feb 10, 2026 |
|---|---|
| 0.1.3 | Feb 8, 2026 |
| 0.1.2 | Feb 8, 2026 |
| 0.1.1 | Feb 8, 2026 |
| 0.1.0 | Feb 8, 2026 |
#207 in Encoding
145KB
3.5K
SLoC
Variable
Variable is a type-safe feature configuration system.
You define features in .var files, then generate typed access code so application code never relies on ad-hoc string keys.
Why Variable
- Type-safe flag access in application code
- Defaults are required and baked into generated code
- Stable wire IDs (
u32) for feature/variable compatibility - Binary snapshot tooling for transport and diagnostics
Quick Example
Define features once:
1: Feature Checkout = {
1: enabled Boolean = true
2: max_items Number = 50
3: header_text String = "Complete your purchase"
}
Generate TypeScript:
variable generate --out ./src/generated features.var
Use strongly typed values:
import { VariableClient } from "@variable/runtime";
import { getCheckoutVariables } from "./generated/features.generated";
const client = new VariableClient();
const checkout = getCheckoutVariables(client);
checkout.enabled; // boolean
checkout.max_items; // number
checkout.header_text; // string
Quick Start
1. Prerequisites
2. Build the CLI
git clone <repo-url> && cd variable
cargo build --release
Binary path:
./target/release/variable
3. Write a .var file
1: Feature Search = {
1: enabled Boolean = false
2: max_results Number = 25
3: placeholder String = "Search..."
}
4. Generate code
variable generate --out ./src/generated search.var
5. Optional: create and inspect binary snapshots
variable encode --schema-revision 1 --manifest-revision 42 search.var > search.snapshot.bin
variable decode --pretty search.snapshot.bin
decode is diagnostics-focused JSON output. It is not intended to reconstruct source .var files.
CLI Commands
variable generate --out <dir> <file.var>variable encode [--schema-revision N] [--manifest-revision N] [--generated-at-unix-ms N] [--source TEXT] <file.var>variable decode [--pretty] [--fail-on-error] <file.bin>
DSL Reference
A .var file is a flat list of feature blocks. IDs are explicit and required.
1: Feature Checkout = {
1: enabled Boolean = true
2: max_items Number = 50
}
2: Feature Search = {
1: enabled Boolean = false
2: query String = ""
}
Rules:
- Feature IDs are
u32and unique per file/invocation - Variable IDs are
u32and unique within each feature - Feature names are unique per file/invocation
- Variable names are unique within each feature
- Every variable must have a default value
- String escapes supported:
\n,\t,\\,\"
Supported types:
| DSL Type | TypeScript |
|---|---|
Boolean |
boolean |
Number |
number |
String |
string |
Runtime Model
Generated code imports VariableClient from @variable/runtime.
- Defaults come from generated code
- Provider data can override defaults
- Missing values fall back to defaults
Current TS provider shape:
interface Provider {
getManifest(): Record<string, Record<string, unknown>>;
}
Binary Protocol
Wire format v1 details are documented in:
docs/binary-protocol-v1.md
variable-wire provides Rust encode/decode tooling used by the CLI.
Examples
examples/ts/basic
Run:
cd examples/ts/basic
npm install
npm start
Repository Layout
variable-core/ parser, lexer, AST, validation
variable-codegen/ TypeScript generation
variable-wire/ binary protocol encode/decode tooling
variable-cli/ CLI (`generate`, `encode`, `decode`)
runtime/ts/ TypeScript runtime package (@variable/runtime)
examples/ runnable examples
fixtures/ sample .var inputs
Development
cargo test
cargo build --release
cargo insta review
License
MIT
Dependencies
~9.5MB
~177K SLoC