alda-lang/alda
A music programming language for musicians. :notes:
Mixed signals — read the receipts
weakest axisnon-standard license (EPL-2.0); no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 7w ago
- ✓10 active contributors
- ✓Distributed ownership (top contributor 39% of recent commits)
Show all 7 evidence items →Show less
- ✓EPL-2.0 licensed
- ✓Tests present
- ⚠Non-standard license (EPL-2.0) — review terms
- ⚠No CI workflows detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/alda-lang/alda)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/alda-lang/alda on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: alda-lang/alda
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/alda-lang/alda shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit 7w ago
- 10 active contributors
- Distributed ownership (top contributor 39% of recent commits)
- EPL-2.0 licensed
- Tests present
- ⚠ Non-standard license (EPL-2.0) — review terms
- ⚠ No CI workflows detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live alda-lang/alda
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/alda-lang/alda.
What it runs against: a local clone of alda-lang/alda — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in alda-lang/alda | Confirms the artifact applies here, not a fork |
| 2 | License is still EPL-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 77 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of alda-lang/alda. If you don't
# have one yet, run these first:
#
# git clone https://github.com/alda-lang/alda.git
# cd alda
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of alda-lang/alda and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "alda-lang/alda(\\.git)?\\b" \\
&& ok "origin remote is alda-lang/alda" \\
|| miss "origin remote is not alda-lang/alda (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(EPL-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"EPL-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is EPL-2.0" \\
|| miss "license drift — was EPL-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "client/cmd/root.go" \\
&& ok "client/cmd/root.go" \\
|| miss "missing critical file: client/cmd/root.go"
test -f "client/go.mod" \\
&& ok "client/go.mod" \\
|| miss "missing critical file: client/go.mod"
test -f "client/cmd/play.go" \\
&& ok "client/cmd/play.go" \\
|| miss "missing critical file: client/cmd/play.go"
test -f "client/cmd/parse.go" \\
&& ok "client/cmd/parse.go" \\
|| miss "missing critical file: client/cmd/parse.go"
test -f "client/interop/musicxml/doc/interfacing-with-musicxml.adoc" \\
&& ok "client/interop/musicxml/doc/interfacing-with-musicxml.adoc" \\
|| miss "missing critical file: client/interop/musicxml/doc/interfacing-with-musicxml.adoc"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 77 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~47d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/alda-lang/alda"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Alda is a text-based music programming language that lets musicians compose and play MIDI music from the command line using human-readable syntax (e.g., piano: o3 g8 a b > c d e f+ g). It consists of a Go CLI client that parses Alda code and a Kotlin/Java player that synthesizes MIDI output, bridging the gap between music composition and algorithmic/live coding. Monorepo structure with separate client/ (Go CLI, ~741KB) and player/ (Kotlin/Java, ~56KB visible here—full player code likely in player/ directory not shown). Client has modular cmd/ structure (cmd/play.go, cmd/export.go, cmd/repl.go, etc.), color/ for terminal output, and dev/ utilities (ast_to_plantuml, note_timing, osc). Build scripts in bin/ (bin/build, bin/release) and CI config in .circleci/.
👥Who it's for
Musicians who want to compose using text editors instead of DAWs, programmers interested in algorithmic composition or live coding, and anyone combining musical creativity with programmatic control—no prior music theory or programming expertise required.
🌱Maturity & risk
Actively maintained and production-ready. The project has semantic versioning (CHANGELOG.md and CHANGELOG-1.X.X.md show v1 releases), CircleCI CI/CD configured in .circleci/config.yml, and a clear roadmap in the README (planned features for browser support, waveform synthesis, MusicXML export). Multiple example scores exist, and the team maintains a Slack community (slack.alda.io).
Low-to-moderate risk. The Go client has ~30 dependencies (manageable), but the project is dual-language (Go + Kotlin), increasing onboarding friction. The player component (Kotlin) is less visible in the file structure shown, so Java/JVM expertise is a hidden requirement. No explicit indication of test coverage in the file list, and the development velocity appears moderate (changelog spans multiple versions but structure suggests stable maintenance rather than rapid iteration).
Active areas of work
Active feature development toward v2+: README lists planned work on browser execution, waveform synthesis, MusicXML export, and Raspberry Pi support (GitHub discussions referenced). bin/watch-circleci-pipeline and bin/download-circleci-artifacts suggest active CI/CD iteration. The telemetry.go and update.go commands indicate ongoing infrastructure investment.
🚀Get running
git clone https://github.com/alda-lang/alda.git
cd alda
client/bin/build
player/bin/build
Built executables appear in client/target and player/target. Go 1.19+ required (per client/go.mod).
Daily commands:
To play a score: alda play --file myfile.alda (inferred from cmd/play.go). To launch REPL: alda repl (cmd/repl.go). To export: alda export --file score.alda (cmd/export.go). To format: alda format (cmd/format.go). Player must be running (started by client if not present, or managed via cmd/shutdown.go / cmd/stop.go).
🗺️Map of the codebase
client/cmd/root.go— Entry point for the CLI application; all commands are registered and configured here.client/go.mod— Defines all Go dependencies and module version; critical for build reproducibility and dependency management.client/cmd/play.go— Core command that orchestrates music playback; bridges Alda parsing with the player backend.client/cmd/parse.go— Handles parsing of Alda music syntax into intermediate representations used by all downstream operations.client/interop/musicxml/doc/interfacing-with-musicxml.adoc— Documents the MusicXML export/import layer; essential for understanding interoperability with standard notation tools.client/help/errors.go— Centralized error handling and user-facing error messages; critical for CLI UX consistency.README.md— Project overview, installation instructions, and design philosophy; every contributor must understand the language's purpose.
🧩Components & responsibilities
- root.go (Command Router) (Cobra, Go stdlib) — Registers all Cobra commands, manages global flags, coordinates entry point dispatch
- Failure mode: Fails silently or panics on malformed command; prevents entire CLI from starting
- parse.go (Parser) (Go (parser logic, likely calls external parser binary or embedded grammar)) — Transforms Alda text syntax into AST/intermediate representation; validates grammar
- Failure mode: Syntax errors reported with line/column; subsequent operations skip on parse failure
- play.go (Playback Orchestrator) (OSC (daveyarwood/go-osc), player IPC) — Coordinates parsed music → OSC message serialization → player process communication → audio playback
- Failure mode: Player crash or unresponsive OSC stops playback; no graceful degradation
- errors.go (Error Handling) — Centralizes user-facing error formatting,
🛠️How to make changes
Add a New CLI Command
- Create a new command file in
client/cmd/following the pattern of existing commands likeplay.go(client/cmd/newcommand.go) - Define a
*cobra.Commandstruct with Run callback that handles the command logic (client/cmd/newcommand.go) - Register the command by calling
rootCmd.AddCommand(newCmd)in the init function (client/cmd/root.go) - Use
help/errors.goutilities for consistent error messaging and user feedback (client/help/errors.go)
Add MusicXML Import/Export Support for a New Notation Element
- Add test case with input musicxml file and expected output PNG in examples directory (
client/interop/musicxml/examples/) - Update the MusicXML conversion logic to handle the new element type (
client/interop/musicxml/doc/musicxml-testcases.adoc) - Implement element mapping in import/export pipeline (
client/cmd/import.go) - Document the mapping in interfacing guide (
client/interop/musicxml/doc/interfacing-with-musicxml.adoc)
Improve CLI User Experience with Better Messages
- Define new error types or message templates in the help module (
client/help/errors.go) - Use color utilities for better visual distinction of errors and success messages (
client/color/color.go) - Apply messages consistently across relevant command files (play.go, parse.go, etc.) (
client/cmd/play.go)
🔧Why these technologies
- Go (golang) — Compiles to single binary for cross-platform distribution; fast startup and execution critical for CLI responsiveness
- Cobra CLI framework — Mature, standard Go CLI framework; provides command routing, flags, help, and consistency across subcommands
- OSC (Open Sound Control) — Language-agnostic protocol for sending musical instructions to background player process; enables loose coupling between parser and audio engine
- MusicXML interop — Enables import from/export to industry-standard notation format (MuseScore, Finale); broadens ecosystem compatibility
- Zerolog — Structured JSON logging for telemetry and debugging; minimal overhead critical for real-time music applications
⚖️Trade-offs already made
-
Client-server architecture (CLI talks to background player process via OSC)
- Why: Allows long-running audio engine separate from CLI; decouples user interaction from audio rendering
- Consequence: Added complexity of process lifecycle management and IPC, but enables persistent playback and background operation
-
Text-based Alda syntax instead of graphical notation
- Why: Enables version control, programmatic composition, and fast keyboard-driven workflows
- Consequence: Steeper learning curve for musicians trained on standard notation; less intuitive visual feedback
-
Single-binary CLI distribution
- Why: Trivial installation, no runtime dependencies, works across Linux/macOS/Windows
- Consequence: Go binary size larger than scripted alternatives; no dynamic plugin system
🚫Non-goals (don't propose these)
- Real-time MIDI editing in graphical DAW
- Native sheet music visualization (relies on MusicXML export to external tools)
- Competing as a full-featured DAW (focused on composition workflow, not mixing/effects)
- Network audio streaming or remote player execution
- Support for non-Western musical scales built-in (extensible via custom instruments)
🪤Traps & gotchas
Dual-language build requirement: client/bin/build and player/bin/build must both succeed; player build details are opaque (likely Maven or Gradle, not shown). OSC port assumption: Client communicates with player via OSC (go-osc library); default port likely hardcoded or configurable via flags—verify before running. MIDI Java dependency: Player requires JVM; system MIDI availability varies by OS (macOS/Windows differ from Linux). Missing file list: player/ directory structure is NOT shown; you'll need to explore player/README.md and player/bin/build to understand Kotlin build. Slack integration: FUNDING.yml may reference donation/community URLs; actual API keys or telemetry endpoints likely in env vars or config files not listed.
🏗️Architecture
💡Concepts to learn
- Abstract Syntax Tree (AST) — Alda's parser converts text syntax into an AST that the player consumes; cmd/dev/ast_to_plantuml proves AST is a first-class data structure, essential for understanding how music notation becomes playback instructions
- Open Sound Control (OSC) — Client-player communication uses OSC (go-osc library); it's a lightweight, network-friendly alternative to MIDI for real-time control, enabling future browser/remote player features
- MIDI (Musical Instrument Digital Interface) — Core output format—Alda compiles to MIDI via the player, limiting it to General MIDI instruments (~128 presets) and enabling DAW integration; understanding MIDI constraints is critical for feature requests
- Domain-Specific Language (DSL) — Alda IS a DSL for music; the syntax (o3, g8, >, <, +) is custom-designed for musicians, not general-purpose—this shapes all parsing, error messaging, and language evolution decisions
- Live Coding — The REPL (cmd/repl.go) enables live-coding—real-time music performance by editing code; this is a core UX pillar, distinct from batch file playback
- Monorepo Build Orchestration — Alda's dual-language build (client/bin/build and player/bin/build) must be orchestrated; understanding cross-language dependency management and artifact coordination is essential for contributing to both layers
- Cobra CLI Framework — All client commands (play, repl, export, parse, etc.) are implemented as Cobra subcommands (see client/cmd/); mastering Cobra's flag parsing and command structure is prerequisite for CLI feature work
🔗Related repos
supercollider/supercollider— Live-coding music synthesis engine; similar real-time audio feedback model but lower-level (unit generators vs. Alda's MIDI abstraction)tidalcycles/Dirt-Samples— Companion repo to TidalCycles (live-coding music language in Haskell); Alda users exploring algorithmic composition will find similar community-driven sample packsovertone/overtone— Clojure-based music programming language layered on SuperCollider; direct competitor in the 'text-based music language' space with different syntax philosophyalda-lang/alda-core— If it exists, the core language/parser library split from CLI client; check GitHub org for shared parsing/AST logicgolang/go— Required runtime for the client; alda requires Go 1.19+ (from go.mod)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add GitHub Actions workflow for automated client binary releases
The repo currently uses CircleCI (config.yml) for CI/CD, but the client/ Go module could benefit from a GitHub Actions workflow that automatically builds and tests Go binaries across multiple platforms (Linux, macOS, Windows). This would reduce friction for contributors testing the client locally and provide faster feedback on build issues. The bin/build and bin/run scripts already exist, so the workflow would be a thin wrapper around these.
- [ ] Create .github/workflows/go-client-build.yml that runs on push and PRs
- [ ] Add matrix strategy for GOOS/GOARCH (linux, darwin, windows; amd64, arm64)
- [ ] Run 'go test ./...' in client/ directory
- [ ] Run 'go build' with proper version injection using client/gen/version/main.go
- [ ] Test against Go 1.19+ (from go.mod)
- [ ] Document new workflow in client/README.md
Add comprehensive error handling tests for client/cmd/ commands
The client/cmd/ directory contains 12+ CLI commands (play.go, parse.go, export.go, repl.go, etc.) but there are no visible test files (no *_test.go files in the structure). Error paths like invalid instrument selection, malformed Alda syntax, MIDI device failures, and telemetry errors should have coverage. The client/help/errors.go file suggests structured error handling that should be tested.
- [ ] Create client/cmd/play_test.go with tests for missing files, invalid instruments, and MIDI device errors
- [ ] Create client/cmd/parse_test.go testing malformed Alda syntax and edge cases
- [ ] Create client/cmd/export_test.go testing unsupported export formats
- [ ] Create client/cmd/repl_test.go testing telemetry disable/enable flows
- [ ] Use client/help/errors.go assertions in tests
- [ ] Ensure all tests pass with 'go test ./cmd' from client/ directory
Document MusicXML interop features and add integration tests
The client/interop/musicxml path exists, suggesting MusicXML import/export functionality (visible in client/cmd/import.go and client/cmd/export.go), but there's no documentation explaining the scope, limitations, or format compatibility. The beevik/etree and other XML dependencies support this feature, but new contributors won't know how to contribute improvements without clear docs and integration tests.
- [ ] Create client/doc/notes/musicxml-interop.adoc documenting supported MusicXML elements, limitations, and known issues
- [ ] Create client/interop/musicxml/musicxml_test.go with round-trip tests (Alda → MusicXML → Alda)
- [ ] Add example MusicXML files in examples/ or client/testdata/ for manual testing
- [ ] Document which MusicXML 3.x/4.x features are supported in the interop docs
- [ ] Add a section to CONTRIBUTING.md linking to the MusicXML interop guide
🌿Good first issues
- Add unit tests for cmd/parse.go: The parse command lacks visible test coverage in the file list. Write tests that verify AST structure for basic Alda syntax (e.g.,
piano: c d e→ correct note sequence) using cmd/dev/ast_to_plantuml as reference for expected output format. - Document OSC message format: The client/dev/osc/ utility exists but no API docs visible. Create markdown docs/osc-protocol.md explaining the OSC messages sent from client to player (note events, tempo, instrument changes) with concrete examples.
- Extend examples/ with beginner scores: README mentions examples/ but file list doesn't show them. Add 3–5 simple .alda files (nursery rhymes, pop melodies) with inline comments explaining syntax; link from docs/
⭐Top contributors
Click to expand
Top contributors
- @daveyarwood — 39 commits
- @OWALabuy — 28 commits
- @cewno — 19 commits
- @De-Alchmst — 5 commits
- @ManakRaj-7 — 3 commits
📝Recent commits
Click to expand
Recent commits
d826f0c— 2.4.2: RestorepartLisp function from Alda 1 (daveyarwood)7941229— Merge pull request #520 from CodeForBeauty/lisp-part-fix (daveyarwood)649ef77— Add doc: attempt at a Kotlin Multiplatform / in-browser player (daveyarwood)11e0ebe— part function defined in lisp (CodeForBeauty)37d41d5— Merge pull request #519 from WildTrueshin/patch-1 (daveyarwood)8b39236— Fix parseFloatFrom to use startIndex correctly (xoxwa)52a8ac0— Use latest Xcode in CircleCI config (daveyarwood)82c6ef6— Update Mac resource class in CircleCI config (daveyarwood)b3a08e8— Merge pull request #518 from myfloss/fix-typos (daveyarwood)67fdfb4— Fix typos (kianmeng)
🔒Security observations
- High · Outdated Go version —
client/go.mod. The project specifies Go 1.19 in go.mod, which reached end-of-life in September 2023. Using outdated Go versions exposes the project to known security vulnerabilities in the Go runtime and standard library. Fix: Update to Go 1.21 or later (current stable version). Run 'go mod tidy' and test thoroughly after upgrading. - High · Outdated dependency: golang.org/x/sys —
client/go.mod (indirect dependency). The project uses golang.org/x/sys v0.22.0, which is significantly outdated. This low-level system package may contain security vulnerabilities affecting network operations, process handling, and system calls. Fix: Run 'go get -u golang.org/x/sys' to update to the latest version and run 'go mod tidy'. - High · Outdated dependency: golang.org/x/term —
client/go.mod (indirect dependency). The project uses golang.org/x/term v0.0.0-20210927222741-03fcf44c2211, which is significantly outdated. This package handles terminal operations and may have security issues. Fix: Run 'go get -u golang.org/x/term' to update to the latest version. - Medium · Outdated dependency: chzyer/readline —
client/go.mod. The project uses chzyer/readline v0.0.0-20180603132655-2972be24d48e from 2018, which is unmaintained and may contain unpatched vulnerabilities in interactive input handling. Fix: Consider replacing with an actively maintained alternative like 'github.com/urfave/cli' or modern readline implementations. If continuing with this version, audit for known vulnerabilities. - Medium · Outdated dependency: logrusorgru/aurora —
client/go.mod. The project uses logrusorgru/aurora v2.0.3+incompatible from 2019. While primarily for terminal colors, unmaintained dependencies increase technical debt and potential vulnerabilities. Fix: Update to the latest version or consider switching to a maintained alternative for terminal color output. - Medium · Unmaintained Go OSC library —
client/go.mod. The project uses daveyarwood/go-osc v0.0.0-20200229013406-0675d0af5e0b from 2020. This custom fork may not receive security updates. OSC (Open Sound Control) handling could be vulnerable to network attacks. Fix: Verify this fork has security patches. Consider switching to an actively maintained OSC library or implementing thorough input validation for OSC messages. - Low · Outdated dependency: google/uuid —
client/go.mod. The project uses google/uuid v1.1.1 from 2019. While UUID generation is low-risk, newer versions may have performance improvements and bug fixes. Fix: Run 'go get -u github.com/google/uuid' to update to the latest version. - Low · Outdated dependency: beevik/etree —
client/go.mod. The project uses beevik/etree v1.1.0. While XML parsing is generally safe, using current versions ensures compatibility with security patches. Fix: Review the latest version for any security improvements or API changes. - Medium · Potential XXE vulnerability in XML parsing —
client/interop/musicxml/. The project includes XML/MusicXML interoperability features (client/interop/musicxml/). XML parsing libraries can be vulnerable to XML External Entity (XXE) attacks if not properly configured. Fix: Ensure all XML parsing is done with XXE prevention enabled. For etree library, disable external entity processing when parsing untrusted XML documents. - Low · Potential command injection in OSC/MIDI handling —
undefined. The project handles system commands through bin/ scripts and integrates with external MIDI Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.