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.
Current SCJSON representation and converter authority are documented in
docs/concepts/SCJSON-00-CONCEPTS.md
and
docs/concepts/SCJSON-CONV-00-CONCEPTS.md.
Authoring Metadata and Inclusion
scjson 0.4.0 adds first-class authoring metadata and stronger inclusion coverage for chart documents:
-
help_textis an optionallist[str]field on SCJSON element models. It is for human-readable chart documentation and stays separate fromother_attributes, which remains the extension metadata surface. - SCXML comments are promoted into
help_textduring SCXML -> SCJSON conversion, and non-emptyhelp_textentries are emitted back as leading SCXML comments during SCJSON -> SCXML conversion. This metadata does not affect validation, execution, transition selection, datamodel evaluation, or trace output. - Inclusion and resource surfaces are preserved through conversion, including
<data src="...">,<script src="...">,<invoke src="...">, inline nested<scxml>content,<send>payloads, and<donedata>payloads. - XInclude is supported in two modes. The default
preservemode keeps unresolved<xi:include>directives as extension elements. Theresolvemode expands includes before conversion when a loader or base path is available.
Canonical behavior is specified in
docs/concepts/SCJSON-CONV-00-CONCEPTS.md;
the optional extension metadata registry is documented in
docs/concepts/SCJSON-OTHER-ATTRIBUTES-00-CONCEPTS.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 compatibility status is owned by
docs/COMPATIBILITY.md. The table below is a package
map only; consult the compatibility matrix for current status tiers, parity
details, and test notes.
| Language | Path | Notes |
|---|---|---|
| Python | py | Canonical converter output and Python engine docs |
| JavaScript | js | Converter package and SCION trace harness |
| Ruby | ruby | Converter package and Ruby engine docs |
| Rust | rust | Converter package |
| Java | java | Converter package and SCION-backed runner |
| Go | go | Converter package |
| Swift | swift | Converter package |
| C# | csharp | Converter package |
| Lua | lua | Converter package |
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
# Resolve XInclude directives before converting instead of preserving them
scjson json path/to/root.scxml --xinclude resolve --output path/to/root.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.
