CueDown — easy-to-manage track markers you can share
CueDown mark CueDown v1 · draft Full spec GitHub — soon
CueDown logo — a vinyl record and a down arrow

CueDown

Easy-to-manage track markers you can share.

CueDown is a minimal, human-writable cue sheet format for tracklists and DJ sets. A tracklist in the common forum notation — 0:00 Artist - Title — is already almost valid CueDown, and normalizing a file is always safe.

One cue per line. One canonical form. Strict errors, never guesses. Files end in .cd.

TIMECODE [FLAG] [SPEED] - TRACK STRING
Paste a tracklist
Canonical .cd {{ modeLabel }}
{{ outText }}
File rejected — stop early, never guess
{{ errText }}

Simple to write by hand

Timecode and track text are the MVP; everything else is optional. A forum tracklist pasted whole just works — the file-level fallback grammar reads it and rewrites it canonically.

One canonical form

Every accepted line maps to exactly one canonical line, and canonical lines are fixed points: parse → serialize returns them byte-for-byte. Normalization is idempotent — safe to run on every save.

Strict, never guesses

Anything outside the accept grammar is an error — nine of them, E01 through E09, each with the line number of first failure. Parsers stop early and never silently degrade.

Two grammars, one fallback

Accept loosely. Write one way.

A permissive accept grammar tolerates hearts, lowercase tokens, any token order and overflowing timecodes. The strict write grammar is a single canonical subset. The delimiter is  -  — everything after it is the track string, verbatim.

Accepted input
0:00 ❤️ - Aalson – Reeds
6:56 - Alex Rusin – Ups and Down
15:50 s3 <3 - Nils Andreas – Rainbow Colors
1:04:25.5 - Koelle – Round & Round
133:16 x s2 - Some Track – Goodbye
Canonical output
00:00 <3 - Aalson – Reeds
06:56 - Alex Rusin – Ups and Down
15:50 <3 S3 - Nils Andreas – Rainbow Colors
01:04:25.500 - Koelle – Round & Round
02:13:16 X S2 - Some Track – Goodbye

The fallback is all-or-nothing. A parser first attempts the canonical grammar on the whole file; only if that fails may it read every line as TIMECODE TRACK STRING. The grammars are disjoint by construction, so a canonical file with one typo never silently degrades with its flags swallowed as text.

Token reference

Three tokens, any order in. One order out.

Required
00:00 · 02:13:16

MM:SS when hours are zero, HH:MM:SS when nonzero, fields zero-padded to 2.

Field overflow normalizes: 133:16 → 02:13:16. Bare integers are rejected.

Fractions use . only, 1–3 digits, written as exactly 3 — and never stripped once present: 4:20.0 → 04:20.000.

Flag · optional
<3 · X

<3 — loved. Any heart emoji is accepted on input (❤️ 💜 🩵 …); always written <3.

X — never show me this again. No emoji aliases, deliberately: people go the distance for tracks they love; the never-play list gets the minimal product.

Mutually exclusive — both on one line is E02.

Speed · optional
S0–S9

Relative intensity of the set at this cue, S0 lowest. Purely advisory — it exists to show the shape of a set: where's the fast part?

Single digit, never zero-padded (S03 is E06). s3 accepted, written S3.

Default is S0; an explicit S0 is preserved on write.

Errors

Fail the file. Stop early.

Every error reports the line number of first failure. When both grammar passes fail, the canonical-pass error is the primary diagnostic.

CodeMeaning
E01Duplicate token — timecode, flag, or speed appears twice
E02<3 and X on the same line
E03Missing timecode
E04Empty or whitespace-only track string
E05Malformed timecode — bare integer, bad field shape, "," fraction separator
E06Zero-padded speed (S03) or out-of-range speed
E07Timecodes not strictly ascending / duplicate timecode
E08Unrecognized token before the delimiter (canonical grammar)
E09Mixed-grammar file — parses under neither the canonical nor the fallback grammar
Adoption

Apps that use CueDown

muwav
The full specification v1 · draft · 2026-09-12 click to expand

1 · Design principles

  1. Simple to write by hand. Timecode and track text are the MVP; everything else is optional.
  2. Two grammars, one fallback. A permissive accept grammar and a strict write grammar (the single canonical form, a subset of the accept grammar) — plus an all-or-nothing, file-level fallback grammar for tracklists pasted from the web.
  3. Round-trip guarantee. Every accepted line maps to exactly one canonical line. Canonical lines are fixed points: parse → serialize returns them byte-for-byte, so normalization is idempotent and safe on every save.
  4. Strict errors. Anything outside the accept grammar is an error. Stop early; never guess.

2 · File rules

  • Encoding UTF-8. Line endings LF on write; CRLF accepted on input.
  • Extension .cd (.cue is taken by CDRWIN cue sheets).
  • Exactly one cue per line. Blank lines ignored on parse, not emitted on write.
  • No comment syntax in v1.
  • Timecodes strictly ascending within a file; out-of-order or duplicates are an error.

3 · Line grammar

TIMECODE [FLAG] [SPEED] - TRACK STRING
  • Tokens separated by exactly one space on write.
  • The delimiter is - written as space-hyphen-space, and it is the only delimiter. : is not accepted — it collides with timecode syntax and may appear freely in track text.
  • Everything after the first delimiter is the track string, verbatim. No escaping, no exceptions.
  • Config tokens may appear in any order before the delimiter on input, but are always written in canonical order. Duplicate tokens of any kind are an error.
  • Track string is required; empty or whitespace-only is an error. Preserved exactly; the line's leading/trailing whitespace is stripped before parsing.

Fallback grammar — forum tracklists. TIMECODE TRACK STRING: everything after the timecode is the track string, verbatim, hyphens included. All-or-nothing at file level: the canonical pass runs first, and only if it fails may the fallback pass run — then every line must parse as fallback. The grammars are disjoint by construction; when both passes fail the result is E09 with the canonical-pass error as the primary diagnostic. On write, a fallback file is rewritten to canonical CueDown.

4 · Tokens

Timecode (required). Write MM:SS when hours are zero, HH:MM:SS when nonzero, fields zero-padded to 2. Milliseconds only if sub-second data exists, as . + exactly 3 digits; a zero fraction still counts (4:20.0 → 04:20.000). Accept 2 or 3 fields of 1+ digits; field overflow normalizes (133:16 → 02:13:16). Fraction separator . only, a decimal fraction of a second, 1–3 digits. Bare integers rejected — minimum shape is M:SS.

Flag (optional). <3 or X, mutually exclusive. Accept any heart emoji with or without U+FE0F; always written <3. x accepted on input; no emoji aliases for X.

Speed (optional). S0–S9, single digit, never zero-padded. s3 accepted, written S3. Default is S0; an explicit S0 is preserved on write, and a token-free line stays token-free.

5 · Case & whitespace

Token matching is case-insensitive on input; tokens are written uppercase. Input tokens may be separated by one or more spaces/tabs; on write, exactly one space between tokens and around the delimiter.

6 · Errors

Strict — fail the file, stop early. The nine codes E01–E09 are listed in the table above.

7 · Semantics

The format carries intent; interpretation is application-defined. <3 — loved, the track the listener will go the distance for. X — never show me this again; excluded from future play. S0–S9 — relative intensity of the set at this cue, purely advisory. muwav's intended use: map BPM across the set, visualize intensity, and potentially skip the wind-down track at the end.

8 · Conformance checklist

  1. normalize(normalize(f)) == normalize(f) byte-for-byte (idempotence).
  2. Every canonical line round-trips unchanged.
  3. Property test: random valid cues → serialize → parse → serialize → byte equality.
  4. All E01–E09 cases rejected with the line number of first failure.
  5. Grammar disjointness: a canonical-valid file is never parsed under the fallback grammar; when both passes fail, the canonical-pass error is primary.
00:00 <3 - CueDown

Starts at 00:00.
Ends in .cd