I ported Meta's MMS forced aligner to TypeScript: word-level timestamps in Node.js, 42% faster than Python
Description and use
The mms-forced-align npm package implements Meta's MMS forced alignment in Node.js, achieving 42 % faster inference and 32 % less memory than Python while matching reference timings exactly.
Problem
Need word-level timestamps for captions in a Node.js service without running a heavy Python sidecar.
Outcome
The TypeScript port matches Python outputs exactly, runs 42 % faster, uses 32 % less memory, and supports 17 Indic languages via a romanizer.
Workflow
- 1. Accept mono 16 kHz Float32Array audio
- 2. Normalize audio (zero mean, unit variance)
- 3. Split into 20 ms frames (320 samples)
- 4. Run ONNX model to get logits per frame
- 5. Apply log_softmax to obtain log-probabilities
- 6. Convert transcript words to extended CTC sequence with blanks
- 7. Run custom TypeScript CTC Viterbi decoder over the grid
- 8. Map Viterbi path to letter and word spans in seconds
Evidence
mms-forced-align runs Meta's MMS forced-aligner model in Node.js through ONNX Runtime, with a CTC Viterbi decoder I wrote from scratch in TypeScript (~170 lines).
~42% faster than Python's torchaudio on the same fp32 model, with ~32% less peak memory.
37 of 37 reference words match torchaudio to 0.0 ms. On a real 116-word clip, 110 words are identical.
- Record date: 2026-10-10T00:41:02.687Z