Install and use in other tools
| Setup | Interface | What it provides |
|---|---|---|
| Terminal or build pipeline | Native scorescript CLI | Check, format, import, and export files |
| Personal website | SVG/PDF, or browser WASM | Static notation, or local interactive rendering |
| Node or Electron | Generated Node WASM package | A reusable compiled document |
| Code editor | scorescript lsp | Language-server integration |
| Agent client | scorescript-mcp | Native tools and reference resources |
The source-build instructions below require authorized access to the ScoreScript repository. They do not require a public npm or crates.io package. This documentation does not provide a verified public package-install route; do not assume an identically named registry package is this engine.
Install the command-line tool
Prerequisites: an authorized checkout, Rust/Cargo compatible with that checkout, and the platform's Rust build tools. If you keep several checkouts, give each its own CARGO_TARGET_DIR. From the repository root:
cargo install --locked --path crates/scorescript_cli --no-default-features
scorescript --help
scorescript docs --list
Cargo installs the binary into its configured bin directory; that directory must be on PATH. Omit --no-default-features if the terminal-score picture feature is wanted. The smaller build still checks, formats, renders SVG, and exports PDF and MIDI. Installing the CLI does not install the ScoreScript desktop app.
scorescript check piece.scorescript
scorescript render piece.scorescript -o piece.svg
scorescript pdf piece.scorescript -o piece.pdf
scorescript midi piece.scorescript -o piece.mid
For an automated build, stop when check exits nonzero. Preserve diagnostics; a renderer can draw partial output even when source has errors. Pin the engine revision used by a build so upgrading it is a deliberate change.
Node and Electron
Prerequisites: the checkout, Rust/Cargo, wasm-pack, and Node. From the repository root, build the Node-target package:
bash crates/scorescript_wasm/build.sh node
This creates crates/scorescript_wasm/pkg-node/ and runs its packaged-runtime smoke check. Copy the whole generated package into your application's vendor/scorescript/ directory. Keep its JavaScript and WASM from the same build. Save this example as render.cjs in your application root:
const { readFileSync, writeFileSync } = require("node:fs");
const { CompiledDocument } = require("./vendor/scorescript/scorescript.js");
const score = new CompiledDocument(readFileSync("piece.scorescript", "utf8"));
try {
const diagnostics = JSON.parse(score.diagnostics_json());
if (diagnostics.length) console.error(diagnostics);
if (diagnostics.some(d => d.severity === "error")) {
throw new Error("ScoreScript source contains errors");
}
writeFileSync("piece.svg", score.render_svg(JSON.stringify({ width_px: 800 })));
} finally {
score.free();
}
Run node render.cjs. The Node build uses CommonJS and needs no asynchronous initialization. The browser build uses ES modules and does require initialization; the two generated packages are not interchangeable.
For an editor, retain one CompiledDocument per open file and call update(source) when its text changes. Then read diagnostics, notation, and performance from that same document. Call free() when closing it. In Electron, keep filesystem access behind the application's existing trusted host boundary; do not enable Node access in an untrusted page to run this example.
Document API
The generated type declarations (scorescript.d.ts) describe the exact API of your build. JSON-returning methods return strings; decode them with JSON.parse. Option arguments are JSON strings, not JavaScript objects.
| Method | Result |
|---|---|
update(source) | Compile changed text; unchanged text keeps the same revision |
revision() | Current revision as a decimal string |
diagnostics_json() | Codes, severity, messages, and source ranges |
render_svg(optionsJson) | Flowing SVG; options include width_px and foreground |
render_pages_json(optionsJson) | Paginated SVG sheets and a layout report; every sheet carries its number and a digest of its own bytes, and {"since": "<revision>"} answers only the sheets that changed since that revision |
event_geometry_json(optionsJson) | Event boxes and system positions for hit testing |
performance_json() | Notes and timing data, not audio output |
performance_json_for(movement) | Performance for an authored movement ID |
performance_json_with_options(movement, playOptional) | The same movement with optional alternatives included when true; default playback omits them |
position_clock_open_json(requestJson) | Retain one performance with exact timing and optional practice tempo/pulse settings |
position_clock_query_json(requestJson) | Exact arrival/release times at written positions in that reading, including rests and ties |
position_clock_release_json(requestJson) | Release that reading's handle |
format() | Canonical source text; it does not save the file |
free() | Release the document when it is no longer used |
Use the option shape belonging to the output method; flowing and paginated layout options are not interchangeable. parse_json() exposes the parsed structure, not a substitute for checking semantic diagnostics.
Practice playback and source edits
Open a position-clock reading with traversal: "straight-through". Use its returned performance and occurrence table together; do not interpolate silent beats from nearby notes. Handles stay bound to their source revision and must be released when no longer used. Optional tempo scaling, beat-head emphasis and subdivision strikes change that reading, not the saved score. Derived strikes are separate from authored notes. The position-clock methods are available in the lean WASM build too.
Authored pan -100 through pan 100 stays in the part's source. Performance parts include its native projections; tempo rows include the written range's upper endpoint (or null) and the effective quarter_bpm. The first number of a range is the initial playback rate.
Native application bridges can use scorescript_entry::step_grid, part_pan and bar_ops for revision-checked musical edits. These Rust APIs can set notes/rests, meter, tempo, bar structure and pickup length while preserving unselected music. They are not extra methods on the WASM document class; unsupported shapes refuse without changing the source. A host should show these refusals instead of repairing music with its own text substitutions.
Code editors and Markdown pipelines
Configure an editor's language-server client to launch scorescript lsp over stdio for .scorescript files. Syntax highlighting and preview UI are separate editor integrations; launching the server does not add those automatically.
A Markdown fence tagged scorescript is source text, not a universal embed standard. A Markdown site needs a build plugin or browser component that sends that fence to the native CLI or WASM engine. The simplest pipeline renders an SVG during the site build and replaces the fence with an image and source link. See website embedding for both approaches.
Agent clients
Build the native stdio server from the repository root:
cargo install --locked --path hosts/chatgpt-mcp
Set the client's MCP server command to the installed scorescript-mcp binary, with no arguments, using that client's configuration format. Client setup and support for previews or attachments vary; a stdio process is not a public HTTP endpoint.
The server exposes compile_score, update_score, format_score, read_score, render_score, export_score_file, and import_musicxml. Read scorescript://docs/index first, then the specific chapter resource, such as scorescript://docs/structure. These are the same authored chapters available through scorescript docs and this website.
For an existing document, use update_score with an increasing revision. The server returns artifacts for the client to save; it does not accept an arbitrary path and write into the client's filesystem. Ordinary terminal file work can use the CLI directly without an MCP round trip.
Verifying from a terminal
An agent working on files rather than through the server writes, then checks, then proves, then looks:
scorescript check piece.scorescript # does it compile, and what came out
scorescript proof piece.scorescript # every engraved bar, note by note
scorescript png piece.scorescript --all # the printed sheets, as pictures
Everything is in this CLI; never script around it with Python or other tools. check ends with one understood line carrying the bar, note and syllable totals and source lines that produced no music, so a loss the diagnostics cannot see is still visible in one line. proof prints the engraved model itself, one line per bar per voice, with --format json for a machine reader — that is the door for verification that never opens a picture, and it costs about what a check costs. render_score and png are for a reader that wants to look at the page.