Renders the Guitar Pro file "Iron Waltz" (public/iron-waltz.gp) with alphaTab and plays it back, in an Angular
21 app built with the default application builder (@angular/build:application, esbuild).
- Angular 21,
@angular/build:applicationand@angular/build:dev-server @coderline/alphatab1.9- Standalone, zoneless component;
afterNextRenderfor client-only creation
The alphaTab setup is the same as in angular-22-esbuild (which also shows server-side rendering).
npm install
npm start # dev server on http://localhost:4200
npm run build # production build to dist/angular-21-esbuild/browseralphaTab renders in a Web Worker and synthesizes audio in an Audio Worklet, started from alphaTab's ES module
with new Worker(new URL('./alphaTab.worker.mjs', import.meta.url)) and
audioWorklet.addModule(new URL('./alphaTab.worklet.mjs', import.meta.url)). Angular's application builder has
no plugin API and bundles new Worker(new URL(...)) only in your own TypeScript files, not inside dependencies.
A plain import of alphaTab therefore works with ng serve (Vite pre-bundling resolves the URLs) but not in the
production build: the worker file is missing and the score never renders.
The sample loads alphaTab's own ES modules instead of bundling them; page, workers and worklet share one copy of alphaTab's core:
angular.json→externalDependencies: ["@coderline/alphatab"]keeps the import of@coderline/alphatabas a bare import in the output.angular.json→assetscopies fromnode_modules/@coderline/alphatab/dist:alphaTab.min.mjs,alphaTab.core.min.mjs,alphaTab.worker.min.mjsandalphaTab.worklet.min.mjsto/alphatab/,font/*to/font/(core.fontDirectory) andsoundfont/sonivox.sf3to/soundfont/(player.soundFont).src/index.htmlmaps@coderline/alphatabto/alphatab/alphaTab.min.mjswith an import map. alphaTab then finds its worker and worklet next to that file.angular.json→index.preloadInitial: falseprevents a<link rel="modulepreload" href="@coderline/alphatab">in the productionindex.html; browsers do not resolve it through the import map and report an error.
The initial bundle stays at about 110 kB, so the default budgets apply.
The component creates alphaTab in afterNextRender (browser only, also when server-side rendering is added
later) and destroys it via DestroyRef.
- The files under
/alphatab/are not content-hashed; make sure browsers fetch the new files after an alphaTab update. - The copied files are alphaTab's minified set:
alphaTab.min.mjsimportsalphaTab.core.min.mjs(1.2 MB, about 300 kB gzip) and startsalphaTab.worker.min.mjsandalphaTab.worklet.min.mjs, which import the same core. For debugging, copyalphaTab.{mjs,core.mjs,worker.mjs,worklet.mjs}and map@coderline/alphatabto/alphatab/alphaTab.mjsinstead; each set references only its own files, so copy and map one set completely. - Bundling alphaTab and copying
alphaTab.{core,worker,worklet}.mjsto the output root also works (verified with Angular 22) but loads 2 copies of the core; seeangular-22-esbuildfor the comparison.