Using SYNX in code
Mirrored from the format repository โ docs/spec/SPECIFICATION_EN.md, SYNX 3.7.4. Changes are made there.
๐ Core Principle: SYNX is read by your code directly. No conversion to JSON is needed. The library parses the
.synxfile itself and returns a native object for your language โdictin Python,Objectin JavaScript. You work with data immediately.
5.1 Installation
# JavaScript / TypeScript
npm install @aperturesyndicate/synx-format
# Python
pip install synx-format5.2 Python โ Reading .synx Directly
from synx import Synx
# Read a .synx file โ and get a dict immediately
data = Synx.load('config.synx')
# Done. Data is ready. Work with it like a regular dictionary:
print(data['app_name']) # "TotalWario"
print(data['server']['port']) # 8080
print(data['gameplay']['base_hp']) # 100
print(data['gameplay']['boss_hp']) # 500 (computed by :calc)
print(data['gameplay']['greeting']) # "Wario time!" (chosen by :random)
# Lists are regular lists:
for map_name in data['map_rotation']:
print(f'Loading map: {map_name}')
# Nesting is regular dicts:
if data['server']['ssl_enabled']:
print('SSL is enabled')Synx.load(path) โ reads the file and parses in one call.
Synx.parse(text) โ parses a string (if you already have the content).
# Alternatively โ from a string:
with open('config.synx', 'r', encoding='utf-8') as f:
data = Synx.parse(f.read())5.3 JavaScript โ Reading .synx Directly
const Synx = require('@aperturesyndicate/synx-format');
// Read a .synx file โ get a regular JS object
const data = Synx.loadSync('config.synx');
// Work with it like a normal object using dot notation:
console.log(data.app_name); // "TotalWario"
console.log(data.server.port); // 8080
console.log(data.gameplay.base_hp); // 100
console.log(data.gameplay.boss_hp); // 500
console.log(data.gameplay.greeting); // random phrase
// Lists are regular Arrays:
data.map_rotation.forEach(map => {
console.log(`Loading map: ${map}`);
});
// Destructuring:
const { base_hp, boss_hp, greeting } = data.gameplay;
console.log(`Boss HP: ${boss_hp}, greeting: ${greeting}`);Synx.loadSync(path) โ reads the file and parses synchronously.
Synx.load(path) โ async version (returns Promise).
Synx.parse(text) โ parses a string.
// Async variant:
const data = await Synx.load('config.synx');
// From a string:
const fs = require('fs');
const text = fs.readFileSync('config.synx', 'utf-8');
const data = Synx.parse(text);5.4 TypeScript โ With Type Safety
import Synx from '@aperturesyndicate/synx-format';
// Define the structure of your config:
interface GameConfig {
app_name: string;
version: string;
server: {
port: number;
host: string;
ssl_enabled: boolean;
};
gameplay: {
base_hp: number;
boss_hp: number;
greeting: string;
loot_tier: string;
};
map_rotation: string[];
}
// The parser returns a typed object:
const data = Synx.loadSync<GameConfig>('config.synx');
console.log(data.gameplay.boss_hp); // number โ autocomplete works
console.log(data.server.port); // number5.5 Using SYNX Data for CSS
SYNX returns a plain object โ Object in JS, dict in Python. You can use this data to generate CSS, CSS custom properties, or pass it into any styling system.
Example: CSS custom properties from SYNX in Node.js
# theme.synx
primary #5a6eff
secondary #ff5a8a
font_size 16
border_radius 8
spacing 12const Synx = require('@aperturesyndicate/synx-format');
const fs = require('fs');
const theme = Synx.loadSync('theme.synx');
// Generate CSS custom properties
const css = `:root {
--color-primary: ${theme.primary};
--color-secondary: ${theme.secondary};
--font-size: ${theme.font_size}px;
--border-radius: ${theme.border_radius}px;
--spacing: ${theme.spacing}px;
}`;
fs.writeFileSync('theme.css', css);Example: Inline styles in React
import Synx from '@aperturesyndicate/synx-format';
const theme = Synx.loadSync('theme.synx');
function Button({ children }) {
return (
<button style={{
backgroundColor: theme.primary,
borderRadius: `${theme.border_radius}px`,
padding: `${theme.spacing}px`,
fontSize: `${theme.font_size}px`,
}}>
{children}
</button>
);
}Example: CSS-in-JS (styled-components, Tailwind config)
// tailwind.config.js
const Synx = require('@aperturesyndicate/synx-format');
const theme = Synx.loadSync('theme.synx');
module.exports = {
theme: {
extend: {
colors: {
primary: theme.primary,
secondary: theme.secondary,
},
spacing: {
base: `${theme.spacing}px`,
},
},
},
};SYNX doesn't replace CSS โ it provides data (colors, sizes, tokens) that your code uses to generate styles. This is especially useful for design systems and theming.
5.6 Rust โ Type-Safe Parsing
The SYNX Rust crate (synx) provides zero-dependency parsing with a rich type system.
Installation (Cargo.toml):
[dependencies]
synx-core = "3.6"Basic Usage:
use synx::Synx;
fn main() {
// Parse a .synx file
let data = Synx::parse_file("config.synx").unwrap();
// Access values with type safety
if let Some(port) = data.get("server").and_then(|s| s.get("port")) {
let port_num: i64 = port.as_int().unwrap_or(8080);
println!("Server running on port {}", port_num);
}
// Work with nested objects
let app_name = data
.as_object()
.and_then(|obj| obj.get("app_name"))
.and_then(|v| v.as_str());
// Convert to JSON if needed
let json = serde_json::to_string(&data).unwrap();
}Value type methods:
.as_str()โOption<&str>.as_int()โOption<i64>.as_float()โOption<f64>.as_bool()โOption<bool>.as_object()โOption<&HashMap<String, Value>>.as_array()โOption<&Vec<Value>>.is_null()โbool
Indexing:
let value = data["server"]["port"];Note: The Rust synx-core crate supports both static and !active modes, including all markers, constraints, .synxb compilation, and !tool parsing. It is the reference implementation.
5.7 C โ FFI to synx-core (JSON strings)
The supported C integration is bindings/c-header: the header include/synx.h plus a shared or static library produced by the Rust crate synx-c (cdylib / staticlib). Functions return UTF-8 JSON strings (or byte buffers for .synxb); there is no SynxValue AST in C โ use your JSON library if you need a native tree.
Build the library (from the repo root):
cargo build -p synx-c --release
# Linux: target/release/libsynx_c.so
# macOS: target/release/libsynx_c.dylib
# Windows: target/release/synx_c.dll (+ MSVC import .lib)Include:
#include "synx.h"Memory: every char* result is heap-allocated; the caller must synx_free() exactly once. Byte buffers from synx_compile must be released with synx_free_bytes(ptr, len).
Functions (v3.6): synx_parse, synx_parse_active, synx_stringify, synx_format, synx_parse_tool, synx_compile, synx_decompile, synx_is_synxb, synx_diff โ see bindings/c-header/include/synx.h.
Minimal example:
#include "synx.h"
#include <stdio.h>
int main(void) {
char *json = synx_parse("name John\nage 25\n");
if (!json) {
fputs("parse failed\n", stderr);
return 1;
}
puts(json);
synx_free(json);
return 0;
}Parity: This path uses the same engine as
synx-core3.6.x (!active,!tool,.synxb, canonical JSON).
5.8 C++ โ thin wrapper (bindings/cpp)
The supported C++ surface is bindings/cpp/include/synx/synx.hpp (namespace synx) โ a thin C++17 wrapper over ยง5.7. It exposes std::optional-based helpers for std::string_view / std::string and std::vector<unsigned char> for .synxb. You must link the same synx-c library and place both include directories on your path (bindings/cpp/include, bindings/c-header/include).
Example:
#include <synx/synx.hpp>
#include <iostream>
int main() {
auto json = synx::parse("name Wario\nage 30\n");
if (!json) return 1;
std::cout << *json << '\n';
return 0;
}Wrappers: parse, parse_active, stringify, format, parse_tool, diff, compile, decompile, is_synxb โ same semantics as synx.h.
Build notes: bindings/cpp/README.md and bindings/cpp/CMakeLists.txt (optional minimal example).
Parity: Behavior is identical to Rust
synx-corefor all FFI-exported operations.
5.9 C# โ .NET 8 library (parsers/dotnet)
The supported C# implementation is parsers/dotnet/src/Synx.Core, targeting .NET 8.0. NuGet package ID APERTURESyndicate.Synx (the ID Synx.Core is taken on nuget.org).
Install via NuGet:
dotnet add package APERTURESyndicate.SynxListing: nuget.org/packages/APERTURESyndicate.Synx. Until the package is on the feed, use a project reference or local .nupkg โ see parsers/dotnet/README.md.
Basic usage:
using Synx;
var map = SynxFormat.Parse("server\n host 0.0.0.0\n port 8080\n");
if (map["server"] is SynxValue.Obj server
&& server.Map["port"] is SynxValue.Int port)
Console.WriteLine(port.Value);
var json = SynxFormat.ToJson(map);
// !active resolution (markers, constraints, includes)
var resolved = SynxFormat.ParseActive("!active\nport:env:default:8080 PORT\n");Entry points (SynxFormat): Parse, ParseActive, ParseFull, ParseFullActive, ParseTool, ToJson.
Values: SynxValue discriminated records โ Null, Bool, Int, Float, Str, Secret, Arr, Obj.
Parity: Static parse and canonical JSON match
synx-corefor covered conformance cases;ParseActiveruns the managed!activeengine..synxbin C# is not implemented yet (usesynx-coreor bindings that wrapsynx-c).
5.10 Go โ cgo binding to synx-c (JSON API)
The supported Go integration is bindings/go: cgo wraps the same synx.h / synx-c library as C and C++. Functions return UTF-8 strings (JSON or SYNX text) or byte slices (.synxb); use encoding/json if you need a tree.
Requirements: Go 1.21+, CGO_ENABLED=1, a C toolchain, and synx_c installed/built (cargo build -p synx-c --release). Linux/macOS link flags default to -L../../target/release -lsynx_c relative to bindings/go. Windows: link synx_c.dll.lib via CGO_LDFLAGS, put synx_c.dll on PATH โ see bindings/go/README.md.
Example:
package main
import (
"fmt"
synx "github.com/APERTURESyndicate/synx-format/bindings/go"
)
func main() {
j, err := synx.Parse("name Wario\nage 30\n")
if err != nil {
panic(err)
}
fmt.Println(j)
}API (v3.6): Parse, ParseActive, Stringify, Format, ParseTool, Compile, Decompile, IsSynxb, Diff โ mirror synx.h.
Parity: Same engine as
synx-core(!active,!tool,.synxb, canonical JSON).
5.11 Mojo โ Python interop (bindings/mojo)
Mojo can call CPython via Python.import_module. The supported way to get SYNX 3.6 parity with synx-core is to import synx_native (the same PyO3 / maturin wheel as pip install synx-format). This is not a standalone Mojo grammar implementation (that would be a separate, large port โ analogous to maintaining synx-js alongside Rust).
Setup: Install Python synx_native (wheel from this repo or PyPI). Optionally Python.add_to_path(...) if you built locally with maturin develop.
String helpers (also on synx_native for thin callers): parse_to_json, parse_active_to_json, parse_tool_to_json, stringify_json, format, compile_hex, decompile_hex, is_synxb_hex, diff_json.
Example (bindings/mojo/examples/demo.mojo pattern):
from std.python import Python
from synx.interop import parse_json
def main() raises:
var j = parse_json("name Wario\nage 30\n")
print(j)Parity: Identical to
synx-corebecause execution runs insidesynx_native(Rust).
5.12 Kotlin / JVM โ bindings/kotlin (JNA + synx-c)
The supported JVM integration in this repository is bindings/kotlin: SynxEngine loads synx_c through JNA. Parse results are canonical JSON String values (or ByteArray for .synxb) unless you decode them yourself.
1. Build the native library (repo root): cargo build -p synx-c --release.
2. Build / test from bindings/kotlin: set SYNX_LIB_DIR to the directory containing libsynx_c / synx_c.dll, then ./gradlew test. See bindings/kotlin/README.md.
Example:
import com.aperturesyndicate.synx.SynxEngine
val json = SynxEngine.parse("name Wario\nage 30\n")
val tool = SynxEngine.parseTool("!tool\nweb_search\n query test\n")
val active = SynxEngine.parseActive("!active\nport:env:default:8080 PORT\n")API (v3.6): SynxEngine.parse, parseActive, stringify, format, parseTool, diff, compile, decompile, isSynxb โ mirrors bindings/c-header/include/synx.h.
Parity: Same engine as
synx-core(including!active,!tool,.synxb,diff). Tooling uses JDK 17+ for Gradle; publishedcom.aperturesyndicate:synx-kotlinmay follow (usepublishToMavenLocaluntil then).
5.13 Swift โ SwiftPM + synx-c (C interop)
The supported Swift integration is bindings/swift: a Swift Package that wraps synx.h / synx-c via CSynx (module.modulemap, link "synx_c"). Types are String / Data; parse results are canonical JSON strings unless you decode yourself.
Build the C library (repo root): cargo build -p synx-c --release, then link libsynx_c when building the package (swift build -Xlinker -Lโฆ -Xlinker -lsynx_c). See bindings/swift/README.md.
Example:
import Synx
let json = try SynxEngine.parse("name Wario\nage 30\n")
print(json)
let tool = try SynxEngine.parseTool("!tool\nweb_search\n query test\n")API (v3.6): SynxEngine.parse, parseActive, stringify(json:), format, parseTool, diff, compile, decompile(_:), isSynxb โ mirrors synx.h.
Parity: Same engine as
synx-core.Sources/CSynx/synx.hmust stay in sync withbindings/c-header/include/synx.h.
5.14 Lua โ Zero-Dependency Parser
Installation:
Copy synx.lua into your project:
local synx = require("synx")Usage:
local synx = require("synx")
-- Parse from string
local data = synx.parse(text)
print(data:get("server"):get("port"):as_int()) -- 8080
-- Parse from file
local data = synx.parse_file("config.synx")
print(data:get("server"):get("host"):as_str()) -- localhost
-- Full parse (mode detection)
local result = synx.parse_full(text)
print(result.mode) -- "static" or "active"API:
synx.parse(text)โSynxValuesynx.parse_full(text)โ{ root, mode }synx.parse_file(path)โSynxValue, errSynxValue:get(key)โ child by key or 1-based indexSynxValue:as_bool(),:as_int(),:as_float(),:as_str()SynxValue:len(),:keys(),:type(),:is_null()
๐ Note: The Lua parser is static-only. No active function evaluation. Works with Lua 5.1+ and LuaJIT.
5.15 Dart / Flutter โ Native Parser
Installation (pubspec.yaml):
dependencies:
synx:
git:
url: https://github.com/APERTURESyndicate/synx-format.git
path: packages/synx-dartUsage:
import 'package:synx/synx.dart';
// Parse from string
final data = Synx.parse(text);
print(data['server']['port'].asInt); // 8080
// Parse from file
final data = Synx.parseFile('config.synx');
// Full parse (mode detection)
final result = Synx.parseFull(text);
print(result.mode); // SynxMode.activeFlutter usage:
import 'package:synx/synx.dart';
import 'package:flutter/services.dart' show rootBundle;
Future<SynxValue> loadConfig() async {
final text = await rootBundle.loadString('assets/config.synx');
return Synx.parse(text);
}API:
Synx.parse(text)โSynxValueSynx.parseFull(text)โSynxParseResult { root, mode }Synx.parseFile(path)โSynxValueSynxValue[key]โ subscript by string key or int index.asBool,.asInt,.asFloat,.asStr.length,.keys,.type,.isNull
๐ Note: The Dart parser is static-only. No active function evaluation. Requires Dart 3.0+.
5.16 PHP โ Native Parser
Installation:
Copy Synx.php into your project:
require_once 'Synx.php';Usage:
require_once 'Synx.php';
// Parse from string
$data = Synx::parse($text);
echo $data->get('server')->get('port')->asInt(); // 8080
// Parse from file
$data = Synx::loadFile('config.synx');
// Full parse (mode detection)
$result = Synx::parseFull($text);
echo $result->mode; // "static" or "active"API:
Synx::parse($text)โSynxValueSynx::parseFull($text)โSynxParseResult { root, mode }Synx::loadFile($path)โSynxValue->get($key)โ child by string key or int index->asBool(),->asInt(),->asFloat(),->asStr()->length(),->keys(),->type(),->isNull()
๐ Note: The PHP parser is static-only. No active function evaluation. Requires PHP 8.0+.
5.17 Bash / PowerShell โ Shell Parsers
Bash (4.0+)
Installation:
source synx.shUsage:
source synx.sh
synx_parse_file "config.synx"
echo "$(synx_get server.host)" # localhost
echo "$(synx_get server.port)" # 8080
echo "$(synx_type server.port)" # int
echo "$(synx_mode)" # static
# Arrays
echo "$(synx_get items.0)" # Sword
echo "$(synx_get items.__length)" # 3API:
synx_parse "$text"โ parse SYNX textsynx_parse_file "$path"โ read and parse filesynx_get "$path"โ value at dot-notation pathsynx_type "$path"โ type namesynx_modeโ document mode
Note: Values are stored in flat associative arrays with dot-notation keys (e.g.
server.host).
PowerShell (5.1+)
Installation:
. .\Synx.ps1Usage:
. .\Synx.ps1
$result = Read-SynxFile "config.synx"
$result.Root.server.host # localhost
$result.Root.server.port # 8080 (int)
$result.Root.items[0] # Sword
$result.Mode # staticAPI:
ConvertFrom-Synx $textโPSCustomObject { Root, Mode }Read-SynxFile $pathโ same
Objects are [ordered]@{}, arrays are native PowerShell arrays, scalars are typed ([long], [double], [bool], [string], $null).
๐ Note: Both shell parsers are static-only. No active function evaluation.
5.18 Comparison: SYNX Directly vs JSON
| JSON | SYNX | |
|---|---|---|
| Reading (JS) | JSON.parse(fs.readFileSync(...)) | Synx.loadSync('file.synx') |
| Reading (Python) | json.load(open(...)) | Synx.load('file.synx') |
| Reading (Rust) | serde_json::from_str(...) | Synx::parse_file(...) |
| Reading (C) | cJSON_Parse(...) | synx_parse(text) |
| Reading (C++) | nlohmann::json::parse(...) | synx::Synx::load(path) |
| Reading (C#) | JsonSerializer.Deserialize(...) | SynxFormat.Parse(File.ReadAllText(path)) |
| Reading (Go) | json.Unmarshal(...) | synx.ParseFile(path) |
| Reading (Java) | new ObjectMapper().readTree(...) | Synx.load(path) |
| Reading (Swift) | JSONDecoder().decode(...) | Synx.load(path) |
| Reading (Lua) | cjson.decode(...) | synx.parse(text) |
| Reading (Dart) | jsonDecode(...) | Synx.parse(text) |
| Reading (PHP) | json_decode(...) | Synx::parse($text) |
| Reading (Bash) | jq '.key' file.json | synx_get "key" |
| Reading (PowerShell) | ConvertFrom-Json | ConvertFrom-Synx |
| Intermediate format | None | None โ same! |
| What you get | Object / dict / Value | Object / dict / Value (same) |
| Built-in logic | No โ write it yourself | :random, :calc, :env, etc. |
| Validation | No โ need a separate lib | [min:3, type:int] in the file |
| File size | ~100% | ~40% smaller |
By language:
| Language | Package | Method | Notes |
|---|---|---|---|
| JavaScript | @aperturesyndicate/synx-format | Synx.loadSync() | Full engine (active + static) |
| Python | synx-format | Synx.load() | Full engine (active + static) |
| Rust | synx-core (crates.io) | Synx::parse() | Full engine (reference implementation) |
| C | synx.h + synx-c lib | synx_parse() โ JSON | FFI to synx-core 3.6.x |
| C++ | synx/synx.hpp + same lib | synx::parse() โ optional<string> | Thin wrapper; same engine |
| C# | APERTURESyndicate.Synx (NuGet) | SynxFormat / parser API | .NET 8 library; Synx.Core ID was taken on nuget.org |
| Go | bindings/go (cgo) + synx-c | synx.Parse() โ JSON | Same engine as Rust |
| Mojo | bindings/mojo + CPython synx_native | parse_json() / parse_active_json() โฆ | Full parity via PyO3; not a pure-Mojo parser |
| Kotlin/JVM | bindings/kotlin + synx-c | SynxEngine.parse() โ JSON String | JNA; JDK 17+ build; same engine as Rust |
| Swift | bindings/swift + synx-c | SynxEngine.parse() โ JSON String | C interop; same engine as Rust |
| Lua | synx.lua (copy) | synx.parse() | Lua 5.1+, zero-dep, static-only |
| Dart/Flutter | synx (pub.dev / git) | Synx.parse() | Dart 3.0+, static-only |
| PHP | Synx.php (copy) | Synx::parse() | PHP 8.0+, zero-dep, static-only |
| Bash | synx.sh (copy) | synx_get() | Bash 4.0+, zero-dep, static-only |
| PowerShell | Synx.ps1 (copy) | ConvertFrom-Synx | PowerShell 5.1+, zero-dep, static-only |