Skip to content
Skillv1.0.0

opentype-js

Parse and manipulate OpenType/TrueType fonts with opentype.js — read font metadata, access glyph outlines, measure text, generate font subsets, and render text to SVG paths. Use when tasks involve cus

by terminalskills(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from terminalskills/skills (skills/opentype-js/SKILL.md). Install upstream with npx skills add terminalskills/skills --skill opentype-js. Copyright stays with the author (Apache-2.0).

opentype.js

Read and write OpenType fonts. Access every glyph, measure text, convert to SVG paths.

Setup

# Install opentype.js for font parsing and manipulation.
npm install opentype.js

Loading a Font

// src/fonts/load.ts — Load a font from file or URL and read metadata.
import opentype from "opentype.js";
import fs from "fs";

// From file (Node.js)
const buffer = fs.readFileSync("./fonts/Inter-Regular.otf");
const font = opentype.parse(buffer.buffer);

console.log(font.names.fontFamily);       // "Inter"
console.log(font.names.designer);         // designer name
console.log(font.unitsPerEm);             // 2048
console.log(font.numGlyphs);              // total glyph count

Measuring Text

// src/fonts/measure.ts — Calculate text width and bounding box at a given size.
// Useful for layout engines and canvas text positioning.
import opentype from "opentype.js";

export function measureText(font: opentype.Font, text: string, fontSize: number) {
  const path = font.getPath(text, 0, 0, fontSize);
  const bb = path.getBoundingBox();
  const advance = font.getAdvanceWidth(text, fontSize);

  return {
    width: advance,
    height: bb.y2 - bb.y1,
    boundingBox: { x1: bb.x1, y1: bb.y1, x2: bb.x2, y2: bb.y2 },
  };
}

Rendering Text to SVG

// src/fonts/to-svg.ts — Convert a text string to an SVG path element.
// This produces resolution-independent text that doesn't require the font file.
import opentype from "opentype.js";

export function textToSvg(
  font: opentype.Font,
  text: string,
  fontSize: number,
  x: number,
  y: number
): string {
  const path = font.getPath(text, x, y, fontSize);
  const pathData = path.toPathData(2); // precision
  const bb = path.getBoundingBox();

  return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${bb.x1} ${bb.y1} ${bb.x2 - bb.x1} ${bb.y2 - bb.y1}">
  <path d="${pathData}" fill="currentColor"/>
</svg>`;
}

Accessing Individual Glyphs

// src/fonts/glyphs.ts — Extract glyph outlines and metadata for specific characters.
import opentype from "opentype.js";

export function getGlyphInfo(font: opentype.Font, char: string) {
  const glyph = font.charToGlyph(char);
  const path = glyph.getPath(0, 0, 72);

  return {
    name: glyph.name,
    unicode: glyph.unicode,
    advanceWidth: glyph.advanceWidth,
    pathData: path.toPathData(2),
    commands: path.commands,
  };
}

// List all glyphs in a font
export function listGlyphs(font: opentype.Font) {
  const glyphs: { index: number; name: string; unicode: number | undefined }[] = [];
  for (let i = 0; i < font.numGlyphs; i++) {
    const g = font.glyphs.get(i);
    glyphs.push({ index: i, name: g.name, unicode: g.unicode });
  }
  return glyphs;
}

Font Subsetting

// src/fonts/subset.ts — Create a subset font containing only the glyphs needed
// for a specific string. Reduces font file size for web embedding.
import opentype from "opentype.js";
import fs from "fs";

export function subsetFont(font: opentype.Font, chars: string, outputPath: string) {
  const glyphs = [font.glyphs.get(0)]; // always include .notdef
  const seen = new Set<number>();

  for (const char of chars) {
    const glyph = font.charToGlyph(char);
    if (glyph.index !== 0 && !seen.has(glyph.index)) {
      glyphs.push(glyph);
      seen.add(glyph.index);
    }
  }

  const subset = new opentype.Font({
    familyName: font.names.fontFamily?.en || "Subset",
    styleName: font.names.fontSubfamily?.en || "Regular",
    unitsPerEm: font.unitsPerEm,
    ascender: font.ascender,
    descender: font.descender,
    glyphs,
  });

  const buffer = Buffer.from(subset.download() as any);
  fs.writeFileSync(outputPath, buffer);
}

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/terminalskills-skills-opentype-js/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

terminalskills-skills-opentype-js.ocm.jsonjson
{
  "ocm": "1",
  "id": "terminalskills-skills-opentype-js",
  "kind": "skill",
  "name": "opentype-js",
  "description": "Parse and manipulate OpenType/TrueType fonts with opentype.js — read font metadata, access glyph outlines, measure text, generate font subsets, and render text to SVG paths. Use when tasks involve custom text rendering, font analysis, glyph extraction, or building font tools.",
  "publisher": "terminalskills",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "fonts",
      "typography",
      "opentype",
      "glyphs",
      "text-rendering",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Parse and manipulate OpenType/TrueType fonts with opentype.js — read font metadata, access glyph outlines, measure text, generate font subsets, and render text to SVG paths. Use when tasks involve custom text rendering, font analysis, glyph extraction, or building font tools."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/terminalskills/skills",
      "path": "skills/opentype-js/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/terminalskills/skills/blob/HEAD/skills/opentype-js/SKILL.md",
      "key": "terminalskills/skills/skills/opentype-js/SKILL.md"
    },
    "compatibility": "Node.js 14+ or browser",
    "license": "Apache-2.0"
  },
  "instructions": "# opentype.js\n\nRead and write OpenType fonts. Access every glyph, measure text, convert to SVG paths.\n\n## Setup\n\n```bash\n# Install opentype.js for font parsing and manipulation.\nnpm install opentype.js\n```\n\n## Loading a Font\n\n```typescript\n// src/fonts/load.ts — Load a font from file or URL and read metadata.\nimport opentype from \"opentype.js\";\nimport fs from \"fs\";\n\n// From file (Node.js)\nconst buffer = fs.readFileSync(\"./fonts/Inter-Regular.otf\");\nconst font = opentype.parse(buffer.buffer);\n\nconsole.log(font.names.fontFamily);       // \"Inter\"\nconsole.log(font.names.designer);         // desi",
  "cost": {
    "context_tokens": 942
  }
}

Fetch it by URL: GET /api/v1/registry/terminalskills-skills-opentype-js/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.