audio-tag

Docs

Every function, where each field goes in each format, all 104 ID3v2 frames, the 148 genres and the byte layout of every tag.

MP3 · ID3M4A · MP4FLACOggAIFFWAV

Introduction

audio-tag reads a file's tags into a metadata object that is the same for every format, and also gives you each format's own structures: ID3v2 frames, MP4 atoms, Vorbis comments, RIFF and AIFF chunks. Writing takes the same metadata shape and changes only what you pass.

Install

npm install audio-tag

There are three entry points. Each one includes everything from audio-tag.

ImportWorks withRuns in
audio-tagBytes (Uint8Array)Any JavaScript runtime
audio-tag/browserBlob and FileBrowsers, Deno, Bun, workers
audio-tag/nodePaths on diskNode

Offline docs: the package includes this website, with the docs and the playground. Open your installed copy with npx audio-tag --open (or yarn audio-tag --open, bunx audio-tag --open). It serves on port 5173; add --port 8080 to use another one.

Usage

The "any file" functions detect the format and call the right reader or writer. Pick your runtime:

import { readFromBlob, writeToBlob } from 'audio-tag/browser'

// reads only the tag regions of large files
const { format, metadata } = await readFromBlob(file)
console.log(format, metadata.title, metadata.artist, metadata.pictures?.[0])

const updated = await writeToBlob(file, { metadata: { title: 'New title', genre: ['Rock'] } })
// a File with the same name and type; the audio is never copied into memory

Note: data that is no recognised audio format (a JPEG, a text file, a bare ID3v1 tag, empty input) throws an UnknownFormatError (format-unknown) and is never changed. Use the ID3 functions for a bare ID3v1 tag. A bare ID3v2 tag counts as MPEG audio ('mpeg') and is read as one.

Functions

Every format has its own functions, and one set handles any file. Use a format's own functions when you know the format, or want its own result type and options. They refuse other formats with an error that says so.

BytesBlob / FileFiles on disk
Any fileread / writereadFromBlob / writeToBlobreadFile / writeFile
ID3readID3File / writeID3FilereadID3FromBlob / writeID3ToBlobreadID3FromFile / writeID3ToFile / removeID3FromFile
MP4readMP4File / writeMP4FilereadMP4FromBlob / writeMP4ToBlobreadMP4FromFile / writeMP4ToFile
FLACreadFLACFile / writeFLACFilereadFLACFromBlob / writeFLACToBlobreadFLACFromFile / writeFLACToFile
OggreadOggFile / writeOggFilereadOggFromBlob / writeOggToBlobreadOggFromFile / writeOggToFile
AIFFreadAIFFFile / writeAIFFFilereadAIFFFromBlob / writeAIFFToBlobreadAIFFFromFile / writeAIFFToFile
WAVreadRIFFFile / writeRIFFFilereadRIFFFromBlob / writeRIFFToBlobreadRIFFFromFile / writeRIFFToFile

To branch on the format yourself, call detectFormat(bytes). It returns 'mpeg', 'mp4', 'flac', 'ogg', 'aiff', 'riff' or 'unknown'.

Metadata

metadata is the same for every format. Each format maps the fields to its own frames, atoms or comments, and a field the format has no place for is rejected on write.

FieldTypeNotes
title, subtitle, album, albumArtist, groupingstring
artist, composer, lyricist, genre, languagestring[]Several values. ID3v1 genre numbers are resolved to names.
track, disc{ no?, of? }
bpmnumber
lengthnumberMilliseconds. For FLAC, Ogg, AIFF and WAV it comes from the audio headers.
recordingTime, releaseTime, originalReleaseTimestringISO 8601 subset, such as "2024" or "2024-05-01". yearOf() gives the year.
comments, lyrics{ language, description, text }[]
picturesPicture[]{ type, mimeType, description, data }; type 3 is the front cover.
ratings, playCountID3 only.
compilationboolean
sort{ title?, artist?, album?, albumArtist?, composer? }Sort orders.
userText, userUrlsRecord<string, string>ID3 TXXX and WXXX, and their counterparts in other formats.

Also available: setSubtitle, conductor, remixer, publisher, copyright, encodedBy, encoderSettings, isrc, mood, key, encodingTime and taggingTime.

Writing

A write changes only the fields you pass. undefined leaves a field alone and null removes it:

const cover = { type: 3, mimeType: 'image/jpeg', description: '', data: jpegBytes }

const out = await writeToBlob(file, {
  metadata: {
    title: 'New title', // set
    comments: null,     // remove
    pictures: [cover],  // replace all pictures
  },
})

Besides metadata, each format takes its own input: id3v2, id3v1 and lyrics3 for ID3 files (id3v2 is also the ID3 chunk of AIFF and WAV files), and mp4, flac, ogg, aiff and riff for theirs. Options that do not apply to the file, such as version for an MP4 file, are refused instead of ignored.

OptionFormatsEffect
strictAllWarnings become errors.
versionID3, AIFF, WAVID3v2 version to write (2, 3 or 4). Default: the file's version, or 4.
id3v1ID3'keep' (default), 'always' or 'never'.
paddingID3, MP4, FLAC, AIFF, WAVFree space to leave when the tags are rewritten, so later edits fit in place. For AIFF and WAV it pads the tag in the ID3 chunk. Ogg files ignore it.

Tip: the byte-level write() returns inPlace: true when the file length and the audio position did not change, so only the tag bytes need to be saved.

Results by format

read() returns a result narrowed by format. Every result has metadata, layout (the byte offsets the playground's byte map draws) and warnings, plus the format's own view:

formatOwn view
'mpeg'id3v2 (the effective tag: all ID3v2 tags in the file merged), id3v1 and lyrics3. metadata takes ID3v2 first, then Lyrics3, then ID3v1.
'mp4'mp4: the iTunes items, the QuickTime metadata and the user-data text. metadata takes them in that order.
'flac'flac: the Vorbis comment block and the picture blocks. streamInfo: sample rate, channels, length and more.
'ogg'ogg: the codec ('vorbis', 'opus' or 'flac'), the comment and its pictures. stream: the header packets and pages.
'aiff'aiff: the text chunks, the Comments chunk and the ID3 chunk's tag. common: channels, sample frames, sample size and rate.
'riff'riff: the INFO list and the ID3 chunk's tag. audio: the format chunk, and the sizes the length comes from.

Errors and warnings

Reading never fails on small problems: each one becomes a { code, message } entry in warnings. Errors carry a code too.

ErrorWhen
TagReadErrorA file can't be read, or a warning came up with strict: true.
TagWriteErrorA write was refused. MP4WriteError, FLACWriteError, OggWriteError, AIFFWriteError and RIFFWriteError extend it.
UnknownFormatErrorformat-unknown: the data is no supported audio format.
NotImplementedErrorAn Ogg codec without comment support, such as Speex or Theora.

Warning: the per-format functions refuse other formats (format-mp4 from the ID3 functions, format-not-flac, format-not-riff and so on). Check with detectFormat() first, or use read() and write().

Formats

MP3 · ID3

ID3v1 and v1.1, ID3v2.2, 2.3 and 2.4, and Lyrics3 v1 and v2.00. The library covers unsynchronisation, synchsafe sizes, zlib frame compression, encryption and grouping hooks, CRC-32, tag restrictions, SEEK, appended tags with footers, every frame layout of every version, and conversion between versions. It passes all 274 cases of the official ID3v1 test suite.

MP4 · M4A

.m4a, .m4b, .mp4 and .mov files keep their tags in metadata atoms, not ID3. When the new metadata fits in the file's free space, the file is rewritten in place. Otherwise every chunk offset (stco/co64) is moved, so the audio stays playable. Ratings and play counts are rejected.

FLAC

Tags live in a Vorbis comment block (TITLE=..., repeated for several values) and picture blocks. Field names follow MusicBrainz Picard, as RFC 9639 suggests. Unchanged blocks keep their bytes, and a write uses the old padding, so it is usually in place.

Ogg

Vorbis, Opus and FLAC-in-Ogg comment headers, with the same field names as FLAC. Covers are METADATA_BLOCK_PICTURE fields. A write rewrites only the header pages, with new CRCs. A cover that needs more pages renumbers the following pages, which rewrites the whole file.

AIFF · AIFF-C

Rich metadata goes in an ID3 chunk, created at the end of the file when missing, so the sound data does not move. The NAME, AUTH, (c) , ANNO and COMT chunks are read as fallbacks, and existing NAME/AUTH/(c) chunks are kept in step (ASCII only, as the spec requires).

WAV

The same idea as AIFF: an id3 chunk for rich metadata, and the LIST/INFO list (INAM, IART, IPRD and others) as a fallback, kept in step. Several values are joined with "; ", and INFO text is ISO 8859-1 unless a CSET chunk says otherwise.

Note: some taggers put ID3 tags in front of FLAC, Ogg, AIFF or WAV files. They are kept on write and noted on read.

Where the specs disagree

The specifications contradict themselves in a few places. Each decision is marked with a // SPEC: comment in the code:

Field mapping

Where each metadata field is written in each format. AIFF and WAV files keep every field in their ID3 chunk, as the ID3v2 columns show; the WAV INFO and AIFF text columns are the extra copies kept in step when the file already has those chunks. MP4 freeform items are shown as ----:NAME; their full key is ----:com.apple.iTunes:NAME.

“n/a”: the format has no place for the field, and a write refuses it.
FieldID3v2.4ID3v2.3ID3v2.2MP4FLAC · OggWAV INFOAIFF text
titleTIT2 TIT2 TT2 ©nam TITLE INAM NAME
subtitleTIT3 TIT3 TT3 ----:SUBTITLE SUBTITLE n/an/a
groupingTIT1 TIT1 TT1 ©grp GROUPING n/an/a
artistTPE1 TPE1 TP1 ©ART ARTIST IART AUTH
albumArtistTPE2 TPE2 TP2 aART ALBUMARTIST n/an/a
albumTALB TALB TAL ©alb ALBUM IPRD n/a
setSubtitleTSST TXXX:TSST TXX:TSST ----:DISCSUBTITLE DISCSUBTITLE n/an/a
composerTCOM TCOM TCM ©wrt COMPOSER IMUS n/a
lyricistTEXT TEXT TXT ----:LYRICIST LYRICIST n/an/a
conductorTPE3 TPE3 TP3 ©con CONDUCTOR n/an/a
remixerTPE4 TPE4 TP4 ----:REMIXER REMIXER n/an/a
publisherTPUB TPUB TPB ----:LABEL LABEL n/an/a
copyrightTCOP TCOP TCR cprt COPYRIGHT ICOP (c)
encodedByTENC TENC TEN ©enc ENCODEDBY IENC n/a
encoderSettingsTSSE TSSE TSS ©too ENCODERSETTINGS ISFT n/a
isrcTSRC TSRC TRC ----:ISRC ISRC n/an/a
languageTLAN TLAN TLA ----:LANGUAGE LANGUAGE ILNG n/a
moodTMOO TXXX:TMOO TXX:TMOO ----:MOOD MOOD n/an/a
keyTKEY TKEY TKE ----:initialkey KEY n/an/a
bpmTBPM TBPM TBP tmpo BPM n/an/a
lengthTLEN TLEN TLE n/an/an/an/a
trackTRCK TRCK TRK trkn TRACKNUMBER TRACKTOTAL ITRK n/a
discTPOS TPOS TPA disk DISCNUMBER DISCTOTAL n/an/a
genreTCON TCON TCO ©gen GENRE IGNR n/a
recordingTimeTDRC TYER TDAT TYE TDA ©day DATE ICRD n/a
releaseTimeTDRL TXXX:TDRL TXX:TDRL ----:RELEASEDATE RELEASEDATE n/an/a
originalReleaseTimeTDOR TORY TOR n/aORIGINALDATE n/an/a
encodingTimeTDEN TXXX:TDEN TXX:TDEN n/an/an/an/a
taggingTimeTDTG TXXX:TDTG TXX:TDTG n/an/an/an/a
commentsCOMM COMM COM ©cmt COMMENT ICMT n/a
lyricsUSLT USLT ULT ©lyr LYRICS n/an/a
picturesAPIC APIC PIC covr PICTURE block · METADATA_BLOCK_PICTURE n/an/a
ratingsPOPM POPM POP n/an/an/an/a
playCountPCNT PCNT CNT n/an/an/an/a
compilationTCMP TCMP TCP cpil COMPILATION n/an/a
sortTSOT TSOP TSOA TSO2 TSOC TSOT TSOP TSOA TSO2 TSOC TST TSP TSA TS2 TSC sonm soar soal soaa soco TITLESORT ARTISTSORT ALBUMSORT ALBUMARTISTSORT COMPOSERSORT n/an/a
userTextTXXX:<name> TXXX:<name> TXX:<name> ----:<name> <NAME> n/an/a
userUrlsWXXX:<name> WXXX:<name> WXX:<name> ----:<name> n/an/an/a

ID3v2 frames

Every frame of ID3v2.2, v2.3 and v2.4 is read, written and validated, along with the chapter and accessibility addenda and 8 common unofficial frames (RGAD, XRVA, and iTunes' TCMP and sort-order frames). Frames the library does not know are kept byte for byte.

104 frame types. § is the section of each version's spec; the layout is the frame body type in src/id3v2/frames/types.ts.
Framev2.2v2.3v2.4LayoutSource
Content group descriptionTT1 §4.2.1TIT1 §4.2.1TIT1 §4.2.1textspec
Title/songname/content descriptionTT2 §4.2.1TIT2 §4.2.1TIT2 §4.2.1textspec
Subtitle/Description refinementTT3 §4.2.1TIT3 §4.2.1TIT3 §4.2.1textspec
Album/Movie/Show titleTAL §4.2.1TALB §4.2.1TALB §4.2.1textspec
Original album/movie/show titleTOT §4.2.1TOAL §4.2.1TOAL §4.2.1textspec
Track number/Position in setTRK §4.2.1TRCK §4.2.1TRCK §4.2.1textspec
Part of a setTPA §4.2.1TPOS §4.2.1TPOS §4.2.1textspec
Set subtitlen/an/aTSST §4.2.1textspec
ISRC (international standard recording code)TRC §4.2.1TSRC §4.2.1TSRC §4.2.1textspec
Lead performer(s)/Soloist(s)TP1 §4.2.1TPE1 §4.2.1TPE1 §4.2.2textspec
Band/orchestra/accompanimentTP2 §4.2.1TPE2 §4.2.1TPE2 §4.2.2textspec
Conductor/performer refinementTP3 §4.2.1TPE3 §4.2.1TPE3 §4.2.2textspec
Interpreted, remixed, or otherwise modified byTP4 §4.2.1TPE4 §4.2.1TPE4 §4.2.2textspec
Original artist(s)/performer(s)TOA §4.2.1TOPE §4.2.1TOPE §4.2.2textspec
Lyricist/Text writerTXT §4.2.1TEXT §4.2.1TEXT §4.2.2textspec
Original lyricist(s)/text writer(s)TOL §4.2.1TOLY §4.2.1TOLY §4.2.2textspec
ComposerTCM §4.2.1TCOM §4.2.1TCOM §4.2.2textspec
Musician credits listn/an/aTMCL §4.2.2textspec
Involved people listn/an/aTIPL §4.2.2textspec
Encoded byTEN §4.2.1TENC §4.2.1TENC §4.2.2textspec
BPM (beats per minute)TBP §4.2.1TBPM §4.2.1TBPM §4.2.3textspec
LengthTLE §4.2.1TLEN §4.2.1TLEN §4.2.3textspec
Initial keyTKE §4.2.1TKEY §4.2.1TKEY §4.2.3textspec
Language(s)TLA §4.2.1TLAN §4.2.1TLAN §4.2.3textspec
Content typeTCO §4.2.1TCON §4.2.1TCON §4.2.3textspec
File typeTFT §4.2.1TFLT §4.2.1TFLT §4.2.3textspec
Media typeTMT §4.2.1TMED §4.2.1TMED §4.2.3textspec
Moodn/an/aTMOO §4.2.3textspec
Copyright messageTCR §4.2.1TCOP §4.2.1TCOP §4.2.4textspec
Produced noticen/an/aTPRO §4.2.4textspec
PublisherTPB §4.2.1TPUB §4.2.1TPUB §4.2.4textspec
File owner/licenseen/aTOWN §4.2.1TOWN §4.2.4textspec
Internet radio station namen/aTRSN §4.2.1TRSN §4.2.4textspec
Internet radio station ownern/aTRSO §4.2.1TRSO §4.2.4textspec
Original filenameTOF §4.2.1TOFN §4.2.1TOFN §4.2.5textspec
Playlist delayTDY §4.2.1TDLY §4.2.1TDLY §4.2.5textspec
Encoding timen/an/aTDEN §4.2.5textspec
Original release timen/an/aTDOR §4.2.5textspec
Recording timen/an/aTDRC §4.2.5textspec
Release timen/an/aTDRL §4.2.5textspec
Tagging timen/an/aTDTG §4.2.5textspec
Software/Hardware and settings used for encodingTSS §4.2.1TSSE §4.2.1TSSE §4.2.5textspec
Album sort ordern/an/aTSOA §4.2.5textspec
Performer sort ordern/an/aTSOP §4.2.5textspec
Title sort ordern/an/aTSOT §4.2.5textspec
YearTYE §4.2.1TYER §4.2.1n/atextspec
DateTDA §4.2.1TDAT §4.2.1n/atextspec
TimeTIM §4.2.1TIME §4.2.1n/atextspec
Original release yearTOR §4.2.1TORY §4.2.1n/atextspec
Recording datesTRD §4.2.1TRDA §4.2.1n/atextspec
SizeTSI §4.2.1TSIZ §4.2.1n/atextspec
User defined text information frameTXX §4.2.2TXXX §4.2.2TXXX §4.2.6user-textspec
Commercial informationWCM §4.3.1WCOM §4.3.1WCOM §4.3.1urlspec
Copyright/Legal informationWCP §4.3.1WCOP §4.3.1WCOP §4.3.1urlspec
Official audio file webpageWAF §4.3.1WOAF §4.3.1WOAF §4.3.1urlspec
Official artist/performer webpageWAR §4.3.1WOAR §4.3.1WOAR §4.3.1urlspec
Official audio source webpageWAS §4.3.1WOAS §4.3.1WOAS §4.3.1urlspec
Official Internet radio station homepagen/aWORS §4.3.1WORS §4.3.1urlspec
Paymentn/aWPAY §4.3.1WPAY §4.3.1urlspec
Publishers official webpageWPB §4.3.1WPUB §4.3.1WPUB §4.3.1urlspec
User defined URL link frameWXX §4.3.2WXXX §4.3.2WXXX §4.3.2user-urlspec
Involved people listIPL §4.4IPLS §4.4n/ainvolved-peoplespec
Unique file identifierUFI §4.1UFID §4.1UFID §4.1ufidspec
Music CD identifierMCI §4.5MCDI §4.5MCDI §4.4mcdispec
Event timing codesETC §4.6ETCO §4.6ETCO §4.5etcospec
MPEG location lookup tableMLL §4.7MLLT §4.7MLLT §4.6mlltspec
Synchronised tempo codesSTC §4.8SYTC §4.8SYTC §4.7sytcspec
Unsynchronised lyrics/text transcriptionULT §4.9USLT §4.9USLT §4.8usltspec
Synchronised lyrics/textSLT §4.10SYLT §4.10SYLT §4.9syltspec
CommentsCOM §4.11COMM §4.11COMM §4.10commentspec
Relative volume adjustmentRVA §4.12RVAD §4.12n/arvadspec
Relative volume adjustment (2)n/an/aRVA2 §4.11rva2spec
EqualisationEQU §4.13EQUA §4.13n/aequaspec
Equalisation (2)n/an/aEQU2 §4.12equ2spec
ReverbREV §4.14RVRB §4.14RVRB §4.13rvrbspec
Attached picturePIC §4.15APIC §4.15APIC §4.14picturespec
General encapsulated objectGEO §4.16GEOB §4.16GEOB §4.15geobspec
Play counterCNT §4.17PCNT §4.17PCNT §4.16pcntspec
PopularimeterPOP §4.18POPM §4.18POPM §4.17popmspec
Recommended buffer sizeBUF §4.19RBUF §4.19RBUF §4.18rbufspec
Encrypted meta frameCRM §4.20n/an/acrmspec
Audio encryptionCRA §4.21AENC §4.20AENC §4.19aencspec
Linked informationLNK §4.22LINK §4.21LINK §4.20linkspec
Position synchronisation framen/aPOSS §4.22POSS §4.21possspec
Terms of usen/aUSER §4.23USER §4.22userspec
Ownership framen/aOWNE §4.24OWNE §4.23ownespec
Commercial framen/aCOMR §4.25COMR §4.24comrspec
Encryption method registrationn/aENCR §4.26ENCR §4.25encrspec
Group identification registrationn/aGRID §4.27GRID §4.26gridspec
Private framen/aPRIV §4.28PRIV §4.27privspec
Signature framen/an/aSIGN §4.28signspec
Seek framen/an/aSEEK §4.29seekspec
Audio seek point indexn/an/aASPI §4.30aspispec
Chaptern/aCHAP §3.1CHAP §3.1chapchapters addendum
Table of contentsn/aCTOC §3.2CTOC §3.2ctocchapters addendum
Audio-textn/aATXT §4ATXT §4atxtaccessibility addendum
iTunes compilation flagTCPTCMPTCMPtextunofficial
iTunes album artist sort orderTS2TSO2TSO2textunofficial
iTunes composer sort orderTSCTSOCTSOCtextunofficial
iTunes title sort orderTSTTSOTTSOTtextunofficial
iTunes performer sort orderTSPTSOPTSOPtextunofficial
iTunes album sort orderTSATSOATSOAtextunofficial
Experimental RVA2n/aXRVAn/arva2unofficial
Replay Gain Adjustmentn/aRGADRGADrgadunofficial

ID3v1 genres

148 genres, index 0 to 147. Index 255 means no genre.
IndexGenreDefined by
0BluesID3v1 (v2.4 Appendix A)
1Classic RockID3v1 (v2.4 Appendix A)
2CountryID3v1 (v2.4 Appendix A)
3DanceID3v1 (v2.4 Appendix A)
4DiscoID3v1 (v2.4 Appendix A)
5FunkID3v1 (v2.4 Appendix A)
6GrungeID3v1 (v2.4 Appendix A)
7Hip-HopID3v1 (v2.4 Appendix A)
8JazzID3v1 (v2.4 Appendix A)
9MetalID3v1 (v2.4 Appendix A)
10New AgeID3v1 (v2.4 Appendix A)
11OldiesID3v1 (v2.4 Appendix A)
12OtherID3v1 (v2.4 Appendix A)
13PopID3v1 (v2.4 Appendix A)
14R&BID3v1 (v2.4 Appendix A)
15RapID3v1 (v2.4 Appendix A)
16ReggaeID3v1 (v2.4 Appendix A)
17RockID3v1 (v2.4 Appendix A)
18TechnoID3v1 (v2.4 Appendix A)
19IndustrialID3v1 (v2.4 Appendix A)
20AlternativeID3v1 (v2.4 Appendix A)
21SkaID3v1 (v2.4 Appendix A)
22Death MetalID3v1 (v2.4 Appendix A)
23PranksID3v1 (v2.4 Appendix A)
24SoundtrackID3v1 (v2.4 Appendix A)
25Euro-TechnoID3v1 (v2.4 Appendix A)
26AmbientID3v1 (v2.4 Appendix A)
27Trip-HopID3v1 (v2.4 Appendix A)
28VocalID3v1 (v2.4 Appendix A)
29Jazz+FunkID3v1 (v2.4 Appendix A)
30FusionID3v1 (v2.4 Appendix A)
31TranceID3v1 (v2.4 Appendix A)
32ClassicalID3v1 (v2.4 Appendix A)
33InstrumentalID3v1 (v2.4 Appendix A)
34AcidID3v1 (v2.4 Appendix A)
35HouseID3v1 (v2.4 Appendix A)
36GameID3v1 (v2.4 Appendix A)
37Sound ClipID3v1 (v2.4 Appendix A)
38GospelID3v1 (v2.4 Appendix A)
39NoiseID3v1 (v2.4 Appendix A)
40AlternRockID3v1 (v2.4 Appendix A)
41BassID3v1 (v2.4 Appendix A)
42SoulID3v1 (v2.4 Appendix A)
43PunkID3v1 (v2.4 Appendix A)
44SpaceID3v1 (v2.4 Appendix A)
45MeditativeID3v1 (v2.4 Appendix A)
46Instrumental PopID3v1 (v2.4 Appendix A)
47Instrumental RockID3v1 (v2.4 Appendix A)
48EthnicID3v1 (v2.4 Appendix A)
49GothicID3v1 (v2.4 Appendix A)
50DarkwaveID3v1 (v2.4 Appendix A)
51Techno-IndustrialID3v1 (v2.4 Appendix A)
52ElectronicID3v1 (v2.4 Appendix A)
53Pop-FolkID3v1 (v2.4 Appendix A)
54EurodanceID3v1 (v2.4 Appendix A)
55DreamID3v1 (v2.4 Appendix A)
56Southern RockID3v1 (v2.4 Appendix A)
57ComedyID3v1 (v2.4 Appendix A)
58CultID3v1 (v2.4 Appendix A)
59GangstaID3v1 (v2.4 Appendix A)
60Top 40ID3v1 (v2.4 Appendix A)
61Christian RapID3v1 (v2.4 Appendix A)
62Pop/FunkID3v1 (v2.4 Appendix A)
63JungleID3v1 (v2.4 Appendix A)
64Native AmericanID3v1 (v2.4 Appendix A)
65CabaretID3v1 (v2.4 Appendix A)
66New WaveID3v1 (v2.4 Appendix A)
67PsychedelicID3v1 (v2.4 Appendix A)
68RaveID3v1 (v2.4 Appendix A)
69ShowtunesID3v1 (v2.4 Appendix A)
70TrailerID3v1 (v2.4 Appendix A)
71Lo-FiID3v1 (v2.4 Appendix A)
72TribalID3v1 (v2.4 Appendix A)
73Acid PunkID3v1 (v2.4 Appendix A)
74Acid JazzID3v1 (v2.4 Appendix A)
75PolkaID3v1 (v2.4 Appendix A)
76RetroID3v1 (v2.4 Appendix A)
77MusicalID3v1 (v2.4 Appendix A)
78Rock & RollID3v1 (v2.4 Appendix A)
79Hard RockID3v1 (v2.4 Appendix A)
80FolkWinamp extension (v2.3 Appendix A)
81Folk-RockWinamp extension (v2.3 Appendix A)
82National FolkWinamp extension (v2.3 Appendix A)
83SwingWinamp extension (v2.3 Appendix A)
84Fast FusionWinamp extension (v2.3 Appendix A)
85BebobWinamp extension (v2.3 Appendix A)
86LatinWinamp extension (v2.3 Appendix A)
87RevivalWinamp extension (v2.3 Appendix A)
88CelticWinamp extension (v2.3 Appendix A)
89BluegrassWinamp extension (v2.3 Appendix A)
90AvantgardeWinamp extension (v2.3 Appendix A)
91Gothic RockWinamp extension (v2.3 Appendix A)
92Progressive RockWinamp extension (v2.3 Appendix A)
93Psychedelic RockWinamp extension (v2.3 Appendix A)
94Symphonic RockWinamp extension (v2.3 Appendix A)
95Slow RockWinamp extension (v2.3 Appendix A)
96Big BandWinamp extension (v2.3 Appendix A)
97ChorusWinamp extension (v2.3 Appendix A)
98Easy ListeningWinamp extension (v2.3 Appendix A)
99AcousticWinamp extension (v2.3 Appendix A)
100HumourWinamp extension (v2.3 Appendix A)
101SpeechWinamp extension (v2.3 Appendix A)
102ChansonWinamp extension (v2.3 Appendix A)
103OperaWinamp extension (v2.3 Appendix A)
104Chamber MusicWinamp extension (v2.3 Appendix A)
105SonataWinamp extension (v2.3 Appendix A)
106SymphonyWinamp extension (v2.3 Appendix A)
107Booty BassWinamp extension (v2.3 Appendix A)
108PrimusWinamp extension (v2.3 Appendix A)
109Porn GrooveWinamp extension (v2.3 Appendix A)
110SatireWinamp extension (v2.3 Appendix A)
111Slow JamWinamp extension (v2.3 Appendix A)
112ClubWinamp extension (v2.3 Appendix A)
113TangoWinamp extension (v2.3 Appendix A)
114SambaWinamp extension (v2.3 Appendix A)
115FolkloreWinamp extension (v2.3 Appendix A)
116BalladWinamp extension (v2.3 Appendix A)
117Power BalladWinamp extension (v2.3 Appendix A)
118Rhythmic SoulWinamp extension (v2.3 Appendix A)
119FreestyleWinamp extension (v2.3 Appendix A)
120DuetWinamp extension (v2.3 Appendix A)
121Punk RockWinamp extension (v2.3 Appendix A)
122Drum SoloWinamp extension (v2.3 Appendix A)
123AcapellaWinamp extension (v2.3 Appendix A)
124Euro-HouseWinamp extension (v2.3 Appendix A)
125Dance HallWinamp extension (v2.3 Appendix A)
126GoaWinamp, named only in the ID3v1 test suite
127Drum & BassWinamp, named only in the ID3v1 test suite
128Club-HouseWinamp, named only in the ID3v1 test suite
129HardcoreWinamp, named only in the ID3v1 test suite
130TerrorWinamp, named only in the ID3v1 test suite
131IndieWinamp, named only in the ID3v1 test suite
132BritPopWinamp, named only in the ID3v1 test suite
133NegerpunkWinamp, named only in the ID3v1 test suite
134Polsk PunkWinamp, named only in the ID3v1 test suite
135BeatWinamp, named only in the ID3v1 test suite
136ChristianWinamp, named only in the ID3v1 test suite
137Heavy MetalWinamp, named only in the ID3v1 test suite
138Black MetalWinamp, named only in the ID3v1 test suite
139CrossoverWinamp, named only in the ID3v1 test suite
140ContemporaryWinamp, named only in the ID3v1 test suite
141Christian RockWinamp, named only in the ID3v1 test suite
142MerengueWinamp, named only in the ID3v1 test suite
143SalsaWinamp, named only in the ID3v1 test suite
144Thrash MetalWinamp, named only in the ID3v1 test suite
145AnimeWinamp, named only in the ID3v1 test suite
146JPopWinamp, named only in the ID3v1 test suite
147SynthpopWinamp, named only in the ID3v1 test suite

How tags are built

The byte layout of every structure the library reads and writes, as the specs define it. Sizes are in bytes; BE and LE mean big- and little-endian. The playground's byte map shows these regions in your own files.

ID3v2

OffsetSizeFieldValue
03Identifier"ID3" (an appended v2.4 tag ends with a footer that starts "3DI")
32VersionMajor (2, 3 or 4), then revision
51Flagsv2.2: unsynchronisation, compression. v2.3: unsynchronisation, extended header, experimental. v2.4: those and footer.
64SizeSynchsafe: 7 bits per byte, the top bit always 0. Excludes the header (and footer).

Frame headers: v2.2 is ID (3) · size (3); v2.3 is ID (4) · size (4, plain BE) · flags (2); v2.4 is ID (4) · size (4, synchsafe) · flags (2).

FrameBody
Text (T***)Encoding (1) · text. v2.4 separates several values with a NUL.
TXXXEncoding (1) · description · NUL · value
COMM, USLTEncoding (1) · language (3, ISO 639-2) · description · NUL · text
APICEncoding (1) · MIME type · NUL · picture type (1) · description · NUL · image data
W***URL in ISO-8859-1

Text encodings: $00 ISO-8859-1, $01 UTF-16 with BOM, and in v2.4 also $02 UTF-16BE and $03 UTF-8.

ID3v1 · Lyrics3

OffsetSizeField
03"TAG"
330Title
3330Artist
6330Album
934Year
9730Comment. In v1.1: comment (28) · NUL · track number (1)
1271Genre index (0 to 147; 255 = none). See the genre list.

Lyrics3 sits just before the ID3v1 tag: v1 is "LYRICSBEGIN" · lyrics · "LYRICSEND"; v2.00 is "LYRICSBEGIN" · fields (3-letter ID, 5-digit size, data) · size of the tag (6 digits) · "LYRICS200".

MP4

Every atom is size (4, BE, including the header) · type (4) · data. The iTunes items live in moov/udta/meta/ilst (handler mdir), one atom per item, each with a data atom: type (4) · locale (4) · value. Freeform items (----) add mean and name atoms. When the metadata grows and no free space is left, every chunk offset in stco (32-bit) and co64 (64-bit) is updated so the audio is still found.

FLAC · Vorbis

A FLAC file starts with "fLaC", then metadata blocks (header: last-block flag (1 bit) · type (7 bits) · length (24 bits, BE)), then the audio frames. A Vorbis comment is vendor length (4, LE) · vendor · number of fields (4, LE) · each field: length (4, LE) · NAME=value in UTF-8.

Ogg

Each page is "OggS" · version · header type · granule position (8, LE) · serial (4) · sequence (4) · CRC-32 (4) · number of segments · segment table, then the data. The comment packet is the codec's second header packet: 0x03 "vorbis" for Vorbis, "OpusTags" for Opus, a VORBIS_COMMENT block for FLAC in Ogg.

WAV

"RIFF" · size (4, LE) · "WAVE" · chunks: ID (4) · size (4, LE) · data, plus a pad byte when the size is odd. fmt holds the format, data the audio, LIST (type INFO) the text tags, id3 a whole ID3v2 tag.

AIFF

"FORM" · size (4, BE) · "AIFF" or "AIFC" · chunks: ID (4) · size (4, BE) · data, plus a pad byte when the size is odd. COMM holds channels, sample frames, sample size and rate, SSND the audio, NAME/AUTH/(c) /ANNO/COMT the text, ID3 a whole ID3v2 tag.

Low-level ID3 API

Build, validate, convert and serialize ID3v2 tags frame by frame. Every frame type is a member of a discriminated union (frame.type), with fields named as in the spec.

import { createTag, createFrame, TextEncoding, validateID3v2, writeID3v2, readID3v2, convertID3v2 } from 'audio-tag'

const tag = createTag(4, [
  createFrame('text', 'TIT2', { encoding: TextEncoding.UTF8, values: ['Title'] }),
])
const issues = validateID3v2(tag)          // [] when valid; each issue cites its section
const { bytes } = writeID3v2(tag, { padding: 1024 })
const parsed = readID3v2(bytes)            // { tag, warnings, totalSize }
const { tag: v23 } = convertID3v2(tag, 3)  // TDRC -> TYER/TDAT/TIME, UTF-8 -> UTF-16

Bundle sizes

Each bundle loads on its own, raw and gzipped as served. Importing only the functions you need lets a bundler drop the other formats; npm run size measures single imports against their budgets.

Build 09023c7 of 2026-10-10, from dist/build-info.json.
FileSizegzip
dist/browser.min.js194.8 KB67.7 KB
dist/cjs/browser.cjs324.0 KB85.7 KB
dist/cjs/browser.min.cjs195.5 KB68.0 KB
dist/cjs/index.cjs320.9 KB84.3 KB
dist/cjs/index.min.cjs194.1 KB67.0 KB
dist/cjs/node.cjs325.5 KB86.0 KB
dist/cjs/node.min.cjs199.6 KB69.4 KB
dist/index.min.js193.4 KB66.8 KB
dist/node.min.js195.7 KB68.0 KB
ESM modules (tsc) (76 files)456.8 KB
Type declarations (79 files)265.5 KB
Source maps (161 files)8252.0 KB
Everything in dist/ (325 files)11117.8 KB

Build info

Each build writes dist/build-info.json: the version, the git commit, the build time and the byte sizes above. This page shows version 0.1.0, built 2026-10-10.