| name | alphatab |
| description | AlphaTab music notation in JS/TS apps. Use for @coderline/alphatab setup, Vite worker integration, fonts/soundfonts, playback controls, track rendering, AlphaTex, drum notation, and React integration. |
AlphaTab Skill
Use this skill when working with AlphaTab music notation library in any project.
Overview
AlphaTab is a JavaScript/TypeScript library for rendering and playing music notation (Guitar Pro files, AlphaTex). It handles sheet music display, audio synthesis, and playback.
Critical Setup Requirements
Vite Plugin (REQUIRED for audio)
Audio playback requires Web Workers. You MUST use the official Vite plugin:
bun add @coderline/alphatab @coderline/alphatab-vite
import { alphaTab } from "@coderline/alphatab-vite";
export default defineConfig({
plugins: [
react(),
alphaTab(),
],
});
Common mistake: Using import alphaTab from instead of import { alphaTab } from - it's a named export.
Required Assets
Copy to your public/ folder:
/fonts/bravura/ - Music notation font
/soundfonts/sonivox.sf2 - Audio samples for playback
Settings Configuration
import { AlphaTabApi, Settings } from "@coderline/alphatab";
const settings = new Settings();
settings.core.fontDirectory = "/fonts/bravura/";
settings.core.enableLazyLoading = true;
settings.core.engine = "svg";
settings.display.layoutMode = 1;
settings.player.enablePlayer = true;
settings.player.enableCursor = true;
settings.player.enableUserInteraction = true;
settings.player.enableAnimatedBeatCursor = true;
settings.player.enableElementHighlighting = true;
settings.player.soundFont = "/soundfonts/sonivox.sf2";
settings.player.scrollMode = 1;
settings.player.scrollSpeed = 300;
const api = new AlphaTabApi(containerElement, settings);
Required CSS
AlphaTab creates elements with these classes - you MUST style them:
.at-cursor-bar {
background: rgba(255, 242, 0, 0.25);
}
.at-cursor-beat {
background: rgba(64, 64, 255, 0.75);
width: 3px;
}
.at-highlight * {
fill: #0078ff;
stroke: #0078ff;
}
.at-selection div {
background: rgba(64, 64, 255, 0.1);
}
Loading Content
api.tex(alphaTexString);
api.load(new Uint8Array(arrayBuffer));
Event Lifecycle
Events fire in this order:
scoreLoaded - Score parsed, ready to render
renderStarted - Rendering begun
renderFinished - Notation visible
soundFontLoad - Progress loading audio samples
soundFontLoaded - Audio samples ready
midiLoaded - MIDI data generated
playerReady - NOW you can call play()
Common mistake: Trying to play before playerReady fires.
Playback Controls
api.play();
api.pause();
api.stop();
api.playPause();
api.playbackSpeed = 0.5;
api.tickPosition = masterBar.start;
api.isLooping = true;
api.playbackRange = {
startTick: startMasterBar.start,
endTick: endMasterBar.start + endMasterBar.calculateDuration(),
};
Built-in Selection (Don't reinvent this!)
When enableUserInteraction: true, AlphaTab handles selection automatically:
- User can click and drag to select a range
.at-selection CSS class shows the highlight
- Listen to
playbackRangeChanged event for selection changes
api.playbackRangeChanged.on((args) => {
if (args.playbackRange) {
console.log(args.playbackRange.startTick, args.playbackRange.endTick);
} else {
}
});
DO NOT implement your own selection with beatMouseDown/beatMouseUp - use the built-in one.
Selection Highlight API (for custom UIs)
api.highlightPlaybackRange(startBeat, endBeat);
api.applyPlaybackRangeFromHighlight();
api.clearPlaybackRangeHighlight();
Track Selection
api.scoreLoaded.on((score) => {
const drumTrack = score.tracks.find((t) => t.name === "Drums");
if (drumTrack) {
api.renderTracks([drumTrack]);
}
});
score.tracks.map((t) => ({ name: t.name, index: t.index }));
AlphaTex Drum Notation
For percussion, use articulation names with duration AFTER the note:
\title "Rock Beat"
\tempo 100
.
\track "Drums"
\instrument percussion
\articulation defaults
(KickHit HiHatClosed).8 HiHatClosed.8 (SnareHit HiHatClosed).8 HiHatClosed.8 |
Common articulations: KickHit, SnareHit, HiHatClosed, HiHatOpen, CrashCymbal, RideCymbal
Duration syntax: NoteName.duration where duration is: 1=whole, 2=half, 4=quarter, 8=eighth, 16=sixteenth
Chords: (Note1 Note2).duration
React Integration Pattern
<AlphaTabPlayer
key={`file-${fileName}-track-${trackIndex}`}
fileData={fileData}
trackIndex={trackIndex}
/>
Debugging
Check these if player doesn't work:
- Is Vite plugin installed? (check for Web Worker errors)
- Are fonts loading? (check Network tab for /fonts/bravura/)
- Is soundfont loading? (check for /soundfonts/*.sf2)
- Did
playerReady fire? (add event listener)
- Are CSS classes styled? (inspect .at-cursor-bar etc.)
Common Mistakes
- Missing Vite plugin - Audio won't work without Web Workers
- Wrong import -
{ alphaTab } not alphaTab default
- Playing too early - Wait for
playerReady event
- Missing CSS - Cursor/selection invisible without styles
- Custom selection - Use built-in
enableUserInteraction instead
- Wrong AlphaTex syntax - Duration goes AFTER note name for drums