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
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
- 💡 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
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.
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.
| 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# | 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.
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:
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/
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.
All converters share the same schema and test suite to ensure compatibility.
# 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.scjsonpypi: [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.
- 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
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).
cd py
pip install -r requirements.txt
pytest -qcd js
npm ci
npm test --silentcd ruby
gem install bundler
bundle install
bundle exec rspeccd go
go test ./...
go buildcd rust
cargo testcd swift
swift testcd csharp
dotnet test -v minimalcd lua
luarocks install luaexpat --deps-mode=one
luarocks install dkjson --deps-mode=one
luarocks install busted --deps-mode=one
busted testsAll 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.
