The goal of this project is to extend FontTools TTX's reach beyond Python / Command Line to Web and Node environments.
Note: This is a vibe-coded project, it may not be suitable for critical workflows. If there are any issues or feedback, let us know over at GitHub issues.
import { TTX } from 'ttx-wasm';
// Initialize (loads Pyodide + FontTools in WebAssembly)
await TTX.initialize();
// Convert font to TTX
const fontFile = await fetch('font.ttf').then(r => r.arrayBuffer());
const ttxContent = await TTX.dumpToTTX(new Uint8Array(fontFile));import { TTX } from 'ttx-wasm';
// Initialize (uses native Python + FontTools)
await TTX.initialize({ pythonExecutable: 'python3' });
// Convert font to TTX
const fontData = await fs.readFile('font.ttf');
const ttxContent = await TTX.dumpToTTX(fontData);npm install ttx-wasm
# No additional dependencies needed - includes WebAssembly runtimenpm install ttx-wasm
# Install Python FontTools (one of these):
pip install fonttools
# or
pip3 install fonttools
# or
python -m pip install fonttoolsimport { TTX } from 'ttx-wasm';
// Automatically uses browser or Node.js backendimport { TTX } from 'ttx-wasm/browser';
// Forces browser/WebAssembly backendimport { TTX } from 'ttx-wasm/node';
// Forces Node.js/Python backend- β No server required - Pure client-side processing
- β No Python installation - WebAssembly handles everything
- β Secure - Runs in browser sandbox
- β Offline capable - Works without internet after initial load
- β Native performance - Direct Python execution
- β Smaller package size - No WebAssembly runtime
- β Better memory handling - Native file operations
- β Full FontTools compatibility - Uses official Python implementation
// Browser configuration
await TTX.initialize({
pyodideIndexURL: './custom-pyodide-path/',
});
// Node.js configuration
await TTX.initialize({
pythonExecutable: '/usr/local/bin/python3.11',
tempDir: '/tmp/ttx-working',
});
// Check current environment
console.log('Runtime:', TTX.getRuntime()); // 'browser' | 'node' | 'worker'All methods work identically in both environments:
TTX.initialize(config?)- Initialize the TTX processorTTX.isInitialized()- Check if ready to useTTX.detectFormat(fontData)- Detect font formatTTX.getFontInfo(fontData)- Get font metadataTTX.dumpToTTX(fontData, options?)- Convert font to TTXTTX.compileFromTTX(ttxContent, options?)- Convert TTX to font
TTX.validateFont(fontData)- Validate font structureTTX.roundTripTest(fontData)- Test conversion integrityTTX.compareTTXContent(ttx1, ttx2)- Compare TTX files
To build for both environments:
# Install dependencies
npm install
# Build all targets
npm run build:dual
# Test in both environments
npm run test:node
npm run test:browser| Environment | Bundle Size | Runtime Dependencies |
|---|---|---|
| Browser | ~7MB | None (self-contained) |
| Node.js | ~50KB | Python + FontTools |
| Use Case | Recommendation |
|---|---|
| Web apps/sites | Browser version - No server setup needed |
| Node.js tools | Node.js version - Better performance |
| Library authors | Universal version - Works everywhere |
| Electron apps | Universal version - Flexibility for both processes |
Check out the examples directory for:
- Browser integration samples
- Node.js CLI tools
- Universal library usage
- Migration guides