OpenType.js
OpenType.js is a JavaScript library designed for parsing and writing TrueType and OpenType fonts, providing deep access to font data and glyph outlines. The current stable version on npm is 1.3.4, released in 2021, though active development continues on the `master` branch with many bug fixes and new features awaiting a 2.0.0 release. It supports a wide range of font formats including WOFF, OTF, and TTF (both TrueType `glyf` and PostScript `cff` outlines). Key differentiators include its ability to create Bezier paths from text, handle composite glyphs, kerning (GPOS/kern table), ligatures, and TrueType font hinting. It runs seamlessly in both browser environments and Node.js, offering a low memory mode option for efficiency.
Common errors
-
ReferenceError: document is not defined
cause Attempting to use `opentype.js` rendering methods (e.g., `path.draw(ctx)`) or `opentype.load()` directly in a Node.js environment without a canvas implementation or polyfill.fixIn Node.js, use a headless canvas library like `canvas` (e.g., `npm install canvas`) and pass its context. Alternatively, use `opentype.parse()` with a font buffer read from the file system and perform path operations without drawing. -
Font could not be loaded: [error message]
cause The `opentype.load()` callback reports an error, usually due to an invalid font URL, network issues, CORS restrictions in a browser, or a corrupt/unsupported font file.fixVerify the font URL is correct and accessible. Check browser console for network errors (CORS). Ensure the font file is valid TrueType or OpenType format. Consider using `opentype.parse()` if loading local files in Node.js or pre-fetching the ArrayBuffer. -
TypeError: font.getPath is not a function
cause The `font` object returned by `opentype.load` or `opentype.parse` is `null` or `undefined` because the font failed to load or parse.fixAlways check for errors after `opentype.load()` (e.g., `if (err) { ... }`) or handle rejections in `async/await` blocks. Ensure `opentype.parse()` receives a valid `ArrayBuffer`.
Warnings
- gotcha The npm package (v1.3.4) has not been updated since 2021, despite active development on the `master` branch. Many bug fixes and new features are unreleased on npm.
- breaking Bower support for installation is deprecated and no longer actively maintained by the Bower project itself.
- gotcha Distinguishing between `opentype.load()` (asynchronous, network-dependent) and `opentype.parse()` (synchronous, requires ArrayBuffer) is crucial for correct usage.
- gotcha When consuming in Node.js, ensure your environment supports ES Modules or correctly use CommonJS `require`. The package's source uses ES6 imports, but the distributed files are made compatible.
Install
-
npm install opentype.js -
yarn add opentype.js -
pnpm add opentype.js
Imports
- opentype
const opentype = require('opentype.js').defaultimport opentype from 'opentype.js'
- load
import { opentype } from 'opentype.js'import { load } from 'opentype.js' - parse
opentype.parse() directly in CommonJS without requiring the default export first.
import { parse } from 'opentype.js'
Quickstart
import opentype from 'opentype.js';
// Simulate a canvas environment for Node.js or ensure this runs in a browser.
// In a browser, getContext('2d') would work directly on a <canvas> element.
// For Node.js, a library like 'canvas' would be needed.
// Mocking a canvas context for demonstration purposes
const mockCanvasContext = {
beginPath: () => console.log('beginPath'),
moveTo: (x, y) => console.log(`moveTo(${x}, ${y})`),
lineTo: (x, y) => console.log(`lineTo(${x}, ${y})`),
quadraticCurveTo: (cx, cy, x, y) => console.log(`quadraticCurveTo(${cx}, ${cy}, ${x}, ${y})`),
bezierCurveTo: (c1x, c1y, c2x, c2y, x, y) => console.log(`bezierCurveTo(${c1x}, ${c1y}, ${c2x}, ${c2y}, ${x}, ${y})`),
closePath: () => console.log('closePath'),
fill: () => console.log('fill'),
stroke: () => console.log('stroke')
};
async function loadAndDrawFont() {
try {
// Replace with a real font URL or path.
// For a local file in Node.js, you'd use fs.readFileSync and opentype.parse.
// For browser, 'fonts/Roboto-Black.ttf' would be relative to the HTML.
const font = await opentype.load('https://raw.githubusercontent.com/opentypejs/opentype.js/master/fonts/Roboto-Black.ttf');
console.log('Font loaded successfully.');
const text = 'Hello, World!';
const fontSize = 72;
const x = 0;
const y = 150;
// Construct a Path object containing the letter shapes
const path = font.getPath(text, x, y, fontSize);
console.log(`Generated path for text: "${text}"`);
// To draw on a real canvas:
// const ctx = document.getElementById('myCanvas').getContext('2d');
// path.draw(ctx);
// Using the mock context to show operations:
path.draw(mockCanvasContext);
console.log('Path drawing operations logged.');
} catch (err) {
console.error('Error loading or drawing font:', err);
}
}
loadAndDrawFont();