This document outlines the current state of the Music Blocks module system as of January 2026. The architecture is currently in a transition phase between global-scope scripts and an asynchronous module definition (AMD) system using RequireJS.
The application initialization follows a multi-phase approach:
- Phase 0 (HTML/Splash):
index.htmlloads early scripts and CSS. - Phase 1 (Loader):
js/loader.jsconfigures RequireJS and initializesi18next. - Phase 2 (Core Load): RequireJS loads
activity/activityandutils/utils. - Phase 3 (App Initialization): The
Activityclass initializes the UI, Canvas, and secondary modules.
Music Blocks primarily uses two methods for dependency management:
- RequireJS (AMD): Used for external libraries (Tone.js, p5.js, i18next) and some internal utilities.
- Global Namespace: Most internal modules (
Logo,Blocks,Turtles) are loaded via RequireJS but register themselves on thewindowobject or rely on other globals being present.
Internal dependencies are manually managed in js/activity.js via the MYDEFINES array. Analysis shows 97 modules are orchestrated this way.
Based on automated analysis of 123 modules and 792 implicit dependencies via globals, the following "Bottleneck Modules" have been identified:
| Module | Incoming Dependencies | Role |
|---|---|---|
js/utils/musicutils.js |
177 | Core music logic, pitch/frequency conversions. |
js/artwork.js |
118 | Visual assets and block icons. |
js/logo.js |
99 | Execution engine and core state. |
js/utils/utils.js |
97 | General-purpose helpers (DOM, math, browser). |
js/protoblocks.js |
56 | Block definitions and structure. |
A change in musicutils.js potentially affects 177 other modules. This is the highest-risk area for regressions.
- Implicit Globals (792 instances): Most module "dependencies" are not managed by RequireJS but are instead implicit. If
musicutils.jsfails to load or registers its globals late, 177 other modules may crash. - Circular Dependencies: Since variables are registered globally, it is easy to create cycles where
logo.jsusesmusicutils.jswhich in turn might use a constant fromlogo.js. - Global Namespace Overcrowding: There are over 468 unique symbols exported to the global namespace, increasing the likelihood of name collisions.
graph TD
index.html --> loader.js
loader.js --> lib/require.js
loader.js --> i18next
loader.js --> activity.js
loader.js --> utils.js
subgraph "Core Cluster"
activity.js --> logo.js
activity.js --> blocks.js
activity.js --> turtles.js
activity.js --> palette.js
end
logo.js --> synthutils.js
logo.js --> musicutils.js
blocks.js --> logo.js
turtles.js --> logo.js
subgraph "External Libraries"
tone.js
p5.js
createjs
end
To maintain a clean repository and avoid merge conflicts on binary/large generated files:
- Source Files (Committed): The Python analysis script (
scripts/analyze-dependencies.py), the Graphviz source (Docs/architecture/dependency-graph.dot), and the rendered SVG (Docs/architecture/dependency-graph.svg) are versioned for easier review. - Generated Data (Ignored): Output reports (
.json) are excluded from Git to prevent merge conflicts.
To update the dependency analysis data after making module changes, run:
python3 scripts/analyze-dependencies.pyThis script will automatically update the .dot, .json, and .svg files (if Graphviz is installed).
A local visualizer is provided for deep-dive architecture audits:
- Location:
Docs/architecture/dev_architecture.html - Regeneration: This file can be updated to point to the latest
dependency-graph.dotfor interactive exploration. - Audience: This is an internal tool for maintainers and contributors during the refactoring of #2632.