@fekit/harfbuzz
v1.0.0
Published
ESM wrapper for HarfBuzz font shaping engine with bidirectional text support
Readme
@fekit/harfbuzz
ESM wrapper for HarfBuzz font shaping engine with bidirectional text support for browsers.
Features
- ✅ Pure ESM - Modern ES Module support
- ✅ Browser-only - Optimized for browser environments
- ✅ Bidirectional Text - Built-in bidi support using bidi-js
- ✅ WebAssembly - Fast font shaping using HarfBuzz WASM
- ✅ TypeScript - Full TypeScript type definitions
- ✅ Zero Configuration - Works out of the box in Vite/Webpack
- ✅ Zero Runtime Requests - WASM inlined at build time
Installation
npm install @fekit/harfbuzzUsage
Basic Example
import harfbuzz from '@fekit/harfbuzz';
// Initialize HarfBuzz (zero configuration!)
await harfbuzz.init();
// Load a font file
const fontData = await fetch('/path/to/font.ttf').then(r => r.arrayBuffer());
// Create a font instance
const font = harfbuzz.createFont('my-font', fontData);
// Shape text (automatic bidirectional support)
const result = font.shape('Hello مرحبا');
console.log(result.glyphs); // Array of glyph information
console.log(result.bounds); // Text boundsHow It Works
The library automatically handles WASM loading with zero configuration:
- In Vite/Webpack: WASM is automatically inlined at build time using
import('./hb.wasm?init') - Zero runtime requests - No need to fetch
.wasmfiles - Fallback support - Works in all environments with automatic detection
Bidirectional Text
The library automatically handles bidirectional text (Arabic, Hebrew, mixed):
// Arabic text
const arabicResult = font.shape('مرحبا بك');
// Hebrew text
const hebrewResult = font.shape('שלום עולם');
// Mixed LTR/RTL
const mixedResult = font.shape('Hello مرحبا World');Advanced Usage
// Get glyph information
const glyphName = font.glyphName(42);
const glyphPath = font.glyphPath(42); // SVG path string
const glyphGeometry = font.glyphGeometry(42); // Path segments
// Variable fonts
const axisInfos = font.getAxisInfos();
font.setVariations({ 'wght': 700, 'wdth': 100 });
// Set font scale
font.setScale(1000, 1000);
// Get supported Unicode codepoints
const unicodes = font.collectUnicodes();
// Access OpenType tables
const gsubTable = font.referenceTable('GSUB');
// Clean up when done
font.destroy();
harfbuzz.freeFont('my-font');Managing Multiple Fonts
await harfbuzz.init();
// Create multiple fonts
const font1 = harfbuzz.createFont('font1', data1);
const font2 = harfbuzz.createFont('font2', data2);
// Get font by ID
const myFont = harfbuzz.getFont('font1');
// List all loaded fonts
console.log(harfbuzz.fontIds); // ['font1', 'font2']
// Free individual font
harfbuzz.freeFont('font1');Using Bidi Separately
If you need direct access to the bidirectional text algorithm:
import bidiFactory from 'bidi-js';
const bidi = bidiFactory();
const result = bidi.getEmbeddingLevels('مرحبا Hello');
console.log(result.levels);API Reference
HarfBuzzSingleton (default export)
init(options?): Promise<void>
Initialize HarfBuzz. Must be called before using any other methods.
Options (all optional):
wasmURL(string): Custom WASM file URLlocateFile(function): Custom file locator functionwasmBinary(Uint8Array): Pre-loaded WASM binary
Examples:
// Zero configuration (recommended)
await harfbuzz.init();
// (Optional) With custom WASM URL if needed
import wasmURL from '@fekit/harfbuzz/src/hb.wasm?url';
await harfbuzz.init({ wasmURL });createFont(id, data, index?): Font
Create a new font instance.
id: Unique identifier for the fontdata: Font binary data (ArrayBuffer or Uint8Array)index: Font index for TTC/OTC files (default: 0)
getFont(id): Font | undefined
Get an existing font by ID.
freeFont(id): void
Free font resources by ID.
fontIds: string[]
Array of all loaded font IDs.
version(): VersionInfo
Get HarfBuzz version information.
versionString(): string
Get HarfBuzz version as string.
Font
shape(text): ShapeResult
Shape text with automatic bidirectional support.
Returns:
{
glyphs: Array<{ id: number, base: { x: number, y: number } }>,
bounds: { width: number, height: number }
}glyphName(id): string
Get glyph name by glyph ID.
glyphPath(id): string
Get glyph outline as SVG path string.
glyphGeometry(id): PathSegment[]
Get glyph outline as path segments.
setScale(xScale, yScale): void
Set font scale factors.
setVariations(variations): void
Set variable font variations.
font.setVariations({ 'wght': 700, 'wdth': 100 });getAxisInfos(): Record<string, AxisInfo>
Get variation axis information.
collectUnicodes(): Uint32Array
Get all supported Unicode codepoints.
referenceTable(table): Uint8Array | undefined
Get OpenType table data.
destroy(): void
Free font resources.
upem: number
Units per em (read-only).
Browser Compatibility
This library requires:
- ES Modules support
- WebAssembly support
- Modern browsers (Chrome 61+, Firefox 60+, Safari 11+, Edge 79+)
License
MIT
Credits
- HarfBuzz - Text shaping engine
- harfbuzzjs - Original WASM wrapper
- bidi-js - Unicode bidirectional algorithm
- harfbuzz-modern-wrapper - Simplified wrapper
