September 24, 2025 8:01 AM (GMT+2)

I considered all songs to be composed of one of these sections:

  1. Title
  2. Intro
  3. Verse
  4. Pre-chorus
  5. Chorus
  6. Bridge
  7. Outro

Of course many songs will break out of this structure, but this is a typical structure of a pop song.

This structure is a bit rigid as compared to a format like markdown. But it enable me to have styling control over how I display different sections of the song, however I want. It introduces challenges like, how do you display streaming lyrics?

Another option could be to not format the lyrics in this structure at all and solely rely on the LLM markdown format output. This would make it easy to stream the lyrics. I just kinda went with the other option because it works okay for this particular use case.

The types definitions are defined as:

export type LyricsSection = {
  type:
    | "intro"
    | "chorus"
    | "verse"
    | "bridge"
    | "title"
    | "pre-chorus"
    | "outro";
  content: string;
};

export type Lyrics = LyricsSection[];