scjson
A JSON-based serialization of SCXML (State Chart XML) for modern tooling, interoperability, and education.
Execution Engines
- Python engine: Deterministic trace emitter, vector generation, and compare tools. See
docs/ENGINE-PY.mdandpy/ENGINE-PY-DETAILS.md. - Ruby engine: Trace interface under active development with growing feature parity. See
docs/ENGINE-RB.md.
JS/TS Harness (via SCION)
- The JS package ships a harness CLI
scjson-scion-tracethat directly requiresscion-coreto execute SCXML and emit JSONL traces. Installscion-corein your project to enable it. - Supports both
.scxmland.scjsoninput (the latter is converted to SCXML internally). - Normalization flags:
--leaf-only,--omit-delta,--omit-transitions,--strip-step0-noise,--strip-step0-states. - Usage (package):
npx scjson-scion-trace -I chart.(scxml|scjson) -e events.jsonl [--xml] [--leaf-only] [--omit-delta] [...] - Dev alternative (in this repo):
node tools/scion-runner/scion-trace.cjs -I chart.scxml -e events.jsonl --xml
Overview
scjson is a structured, schema-based representation of SCXML, the W3C standard for state machine modeling. This format preserves the semantics and hierarchy of SCXML while making it more accessible to modern tools, languages, and interfaces.
Why JSON?
- Easier to parse in JavaScript, Python, Rust, etc.
- Fits naturally with REST APIs, editors, and static validation
- Can be round-tripped to and from standard SCXML
- Works with compact formats like MessagePack or Protobuf when needed
Goals
- 💡 Interoperability: Serve as a bridge between SCXML and modern application ecosystems
- 📦 Portability: Enable translation to binary formats (MessagePack, Protobuf, etc.)
- 📚 Pedagogy: Make it easier to teach and learn state machines with cleaner syntax and visual tools
- 🔁 Round-trip Fidelity: Support conversion back to valid SCXML without semantic loss
Schema
The canonical scjson.schema.json file is located in /scjson.schema.json.
It is generated from Pydantic models and used to validate all *.scjson documents.
Detailed inference rules used by the converters are described in INFERENCE.md.
Directory Structure
Each language implementation lives in its own directory, as a standalone module or library root:
/schema/ → JSON Schema definition of scjson /examples/ → SCXML and scjson sample pairs /tutorial/ → Git submodule: Zhornyak SCXML tutorial /python/ → Python reference implementation (CLI + library) /js/ → JavaScript CLI and library /ruby/ → Ruby CLI and gem /go/ → Go command line utility /rust/ → Rust command line utility /swift/ → Swift command line tool /java/ → Java command line tool /lua/ → Lua scripts /csharp/ → C# command line tool
Each directory is designed to be independently usable as a library or CLI tool.
Converters & Engines
| Language | Status | Path | Notes |
|---|---|---|---|
| Python | ✅ Canonical | py | Reference implementation and compatibility baseline |
| JavaScript | ✅ Parity | js | Matches Python output on the tutorial corpus; harness available via SCION |
| Ruby | ✅ Parity | ruby | Converter parity; engine trace interface under active development |
| Rust | ✅ Parity | rust | Matches Python output on the tutorial corpus |
| Java | ✅ Parity | java | Uses SCION-backed runner; matches Python output |
| Go | ✅ Parity | go | Matches Python output on the tutorial corpus |
| Swift | ✅ Parity | swift | Matches Python output on the tutorial corpus |
| C# | ⚠️ Beta | csharp | Functional CLI; parity work in progress |
| Lua | ✅ Parity | lua | Matches Python output on the tutorial corpus |
See docs/COMPATIBILITY.md for the latest cross-language parity details and test notes.
Examples & Test Suite
This repo includes a curated set of canonical SCXML examples and their equivalent scjson forms in /examples. These are used for:
- Functional validation (SCXML ↔ scjson ↔ SCXML)
- Teaching state machine concepts via visual tools
- Demonstrating usage in editors, UI libraries, and low-code platforms
These examples are derived from and/or adapted from:
📚 Included Tutorial (as Git Submodule)
We include Alex Zhornyak’s SCXML Editor Tutorial as a Git submodule under /tutorial.
This provides a rich set of canonical SCXML test cases and diagrams.
Attribution is provided for educational purposes. No endorsement is implied.
Source: https://alexzhornyak.github.io/ScxmlEditor-Tutorial/
🛠️ Submodule Setup
If you cloned this repo and /tutorial is empty, run:
git submodule init
git submodule update
Or clone with submodules in one step:
git clone --recurse-submodules https://github.com/your-org/scjson.gitThis ensures you get the complete tutorial content alongside the examples and converters.
Converters
All converters share the same schema and test suite to ensure compatibility.
Getting Started
# Convert from SCXML to scjson
scjson convert --from scxml path/to/file.scxml --to scjson path/to/file.scjson
# Validate a scjson file
scjson validate path/to/file.scjsonPackage Repostory Availability
pypi: [https://pypi.org/project/scjson/]
pip install scjsonnpm: [https://www.npmjs.com/package/scjson]
npm install scjson
# harness requires scion-core
npm install scion-coreHarness (Node):
npx scjson-scion-trace -I path/to/chart.scxml -e events.jsonl --xmlrubygems: [https://rubygems.org/gems/scjson]
gem install scjsonRubyGems notes:
- Ruby CLI includes converters and a trace interface. See
docs/ENGINE-RB.mdfor engine usage and maturity. The gem is published at the link above.
cargo: [https://crates.io/crates/scjson]
cargo install scjsondockerhub: [https://hub.docker.com/r/iraa/scjson] (Full development environment for all supported languages)
docker pull iraa/scjson:latestFor a full example of installing toolchains and dependencies across languages see codex/startup.sh.
Documentation
- User guide (Python engine):
docs/ENGINE-PY.md - Architecture & in-depth reference (Python):
py/ENGINE-PY-DETAILS.md - Compatibility matrix:
docs/COMPATIBILITY.md - Testing guide:
TESTING.md - Agents overview:
AGENTS.md
Known Divergences and Issues
Cross‑engine comparisons sometimes surface intentional, documented differences (e.g., ordering nuances, ECMA in semantics, history re‑entry). Use these resources to understand, normalize, and triage behavior across SCION (Node), Python, and Ruby:
- Comprehensive overview: docs/COMPATIBILITY.md
- Normalization profile:
--norm scionin exec_compare sets leaf‑only, omit‑delta, omit‑transitions, strip‑step0‑states, and ordering=scion.- Example:
python py/exec_compare.py tests/exec/toggle.scxml --events tests/exec/toggle.events.jsonl --reference "node tools/scion-runner/scion-trace.cjs" --norm scion
- Example:
- CI known‑diffs list: scripts/ci_ruby_known_diffs.txt (used by
scripts/ci_ruby_harness.sh --knownto keep CI green while still reporting expected mismatches). - Ruby converter in CI: when Nokogiri isn’t available, the Ruby CLI falls back to the Python converter for SCXML↔scjson only; execution remains Ruby. See docs/ENGINE-RB.md (CI Notes).
Quick Installs.
Python Module
cd py
pip install -r requirements.txt
pytest -qJavaScript Module
cd js
npm ci
npm test --silentRuby Module
cd ruby
gem install bundler
bundle install
bundle exec rspecGo Module
cd go
go test ./...
go buildRust Module
cd rust
cargo testSwift Module
cd swift
swift testC# Module
cd csharp
dotnet test -v minimalLua Module
cd lua
luarocks install luaexpat --deps-mode=one
luarocks install dkjson --deps-mode=one
luarocks install busted --deps-mode=one
busted testsLegal and Documentation
All source code in this directory is released under the BSD 1-Clause license. See LICENSE and LEGAL.md for details. Additional documentation is available in AGENTS.md and TESTING.md.
