Every song folder must contain aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/cocreating/4StemPlayer/llms.txt
Use this file to discover all available pages before exploring further.
song.json file that describes the song’s metadata. This file is read by the validation and manifest-generation scripts at ingestion time, and its contents are served to the browser as part of the song bundle. This page covers every supported field, the accepted chord formats, section marker syntax, and the validation rules enforced by scripts/validate-songs.ts.
Required Fields
These five fields must be present and non-empty in everysong.json. Validation fails and the manifest will not be regenerated if any are missing.
The song’s display title shown in the song selector and metadata panel. Example:
"Glory Box".The performing artist or band name. Example:
"Portishead".The musical key of the song as a human-readable string. Examples:
"D#m", "A minor", "Gm". There is no enforced format — use whatever is most readable for your band.Tempo in beats per minute. Must be a JSON number, not a string. Example:
120. Validation will fail with bpm must be a number if you write "120" instead of 120.Time signature as a string. Example:
"4/4".Optional Fields
Human-readable duration formatted as
m:ss. Example: "3:32". If present, must be a string — not a number.Total duration in seconds as a plain number. Example:
212. If present, must be a finite number.Chord progressions for the song. Accepts either a simple string or a structured section object. See Chord Formats below.
Freeform rehearsal notes displayed in the metadata panel. Useful for arrangement cues, historical context, or performance tips.
Inline lyrics as a Markdown string. Use this as an alternative to a separate
lyrics.md file when lyrics are short or when embedding them directly in the JSON is more convenient.An array of named section markers used to build the section navigation buttons in the metadata panel. See Sections Array Format below.
Chord Formats
Thechords field accepts two formats.
1. Simple String
Use a plain string for a single, unsectioned chord progression:2. Section Object (Recommended)
Use an object whose keys are stable section identifiers. Each value can be either a plain string (compact form) or a full section object:The chord progression text displayed in the chords panel. Required when the section value is an object.
Display label for the section. Defaults to the title-cased version of the section key when omitted — so
"verse" becomes "Verse" and "preChorus" becomes "Pre Chorus".Optional note displayed below the progression, useful for arrangement or performance reminders.
Sections Array Format
Thesections array populates the section-jump buttons in the metadata panel. Each entry marks a named point in the song timeline.
Display name for the section. Shown on the navigation button.
Offset in seconds from the beginning of the song. Clicking the button seeks the playhead to this position.
Optional end offset in seconds. Not currently used for playback gating, but stored in the bundle for future use.
Validation Rules
Thescripts/validate-songs.ts script enforces these rules when you run npm run songs:validate, npm run songs:prepare, or npm run songs:release:
title,artist,key,bpm, andtimeSignaturemust all be present and non-empty.bpmmust be a JSON number, not a string.duration, if present, must be a string (e.g."3:32").durationSeconds, if present, must be a finite number.chords, if present, must be either a string or a plain object. Each section value must be either a string or an object containing a non-emptyprogressionstring. Optionallabelandnotesfields must also be strings when provided.sections, if present: every entry must have a non-emptylabelstring and a numericstart.lyrics.mdmust exist in the song folder. An emptylyrics.mdproduces a validation warning (not an error) and ingestion continues.- Every required MP3 stem (
bass,drums,vocals) must exist in the folder and must be non-empty.
Complete Example
The following is the fullsong.json for the bundled La bambola demo, showing all supported fields:
TypeScript Interface
TheSongMetadata interface in src/lib/types.ts precisely matches the validated shape: