How ibm/plex works
1. What this repository is
- This is a monorepo for the IBM Plex typeface family, not an application runtime.
- Its primary product is distributable font packages: Sans, Serif, Mono, Condensed, Math, and several locale-specific Sans families.
2. Top-level structure
- The repo is organized around packages/, scripts/, gulp-tasks/, cypress/, and .github/workflows/.
- That layout strongly suggests a pipeline that takes font assets and metadata, transforms them, tests them, and publishes them as npm packages and CDN/release artifacts.
3. Package boundary: one font family per package
- Each folder under packages/ is a publishable package such as plex-sans, plex-serif, plex-mono, plex-math, and language/script variants like plex-sans-jp, plex-sans-kr, plex-sans-arabic, etc.
- These package directories contain font binaries plus package metadata (package.json, telemetry.yml, license files, README).
- This is the main architectural boundary: each font family is distributed independently, even when they share naming conventions and build logic.
4. Artifact formats inside each package
- Packages ship multiple font formats: typically EOT, OTF, TTF, WOFF, and WOFF2.
- Some packages also include split CSS files under fonts/split/... that expose one-face-per-file distribution.
- The repo distinguishes complete font bundles from split bundles; variable font packages are a special case and only include the relevant variable formats and CSS.
5. Shared build and generation layer
- The scripts/ directory is the main transformation layer.
- Important tasks include:
- generate-cdn.js for CDN artifact creation
- generate-scss.js for stylesheet generation
- compile-css.js for CSS compilation
- prepare-zip.js and clean-zip.js for release packaging
- parse-unicodes.js and scripts/data/unicodes/* for glyph coverage mapping
- load-non-latin-plex.js and families.js for family/script-specific handling
- These scripts are likely the bridge from upstream font source data to package-ready assets.
6. Metadata-driven font coverage
- scripts/data/ contains family and weight definitions plus Unicode coverage maps per writing system.
- This implies the build pipeline is data-driven: scripts use these definitions to decide which glyph ranges belong in which family/package and how to generate per-script outputs.
7. Release and CDN publishing path
- .github/workflows/publish-cdn.yml and publish-cdn-test.yml indicate an automated publish-to-CDN flow.
- The repo also has docs/release.md, reinforcing that releases are a first-class output.
- In practice, the publish path appears to be: build assets → package/zip them → publish to CDN and/or release artifacts.
8. Build orchestration
- gulpfile.js and gulp-tasks/ define higher-level build steps.
- The presence of gulp-tasks/build, deploy-preview.js, and config.js suggests a coordinated pipeline for local builds, preview deployments, and release packaging.
- The architecture here is orchestration-focused rather than app-server-focused.
9. Testing and visual verification
- cypress/ contains end-to-end tests and Percy integration (.percy.json), which is notable for a font repo because it implies rendering verification rather than API tests.
- test/index.html, test/index-cdn.html, and test/inject.txt suggest browser-based checks for local and CDN-delivered font behavior.
- So the verification boundary is: build output must render correctly in a browser.
10. Monorepo tooling and package management
- The repo uses Yarn with a checked-in cache, plus Lerna (lerna.json) for monorepo package coordination.
- husky, lint-staged, and commitlint enforce contribution quality at the git boundary.
- nvmrc indicates a fixed Node runtime expectation for the build toolchain.
11. Key data flow
- The core flow is:
- font source/materials and metadata
- script-driven transformation and formatting
- package-local assets generated under packages/*/fonts
- zip/CDN/release packaging
- browser-based validation
- npm/CDN publication
- There is no persistent backend or live service in this repository; the output is static distributable assets.
12. How to diagram the repo
- A good architecture diagram would show:
- a shared build/metadata layer in scripts/ and gulp-tasks/
- multiple independent font package nodes under packages/
- a test/preview lane using Cypress/Percy and static HTML pages
- a CI/CD lane in GitHub Actions publishing packages and CDN artifacts
- The main boundary to emphasize is between generic build logic and family-specific packaged outputs.
Main entry points: scripts Scripts · lerna.json Lerna · workflows GitHub Actions · gulp-tasks Gulp tasks
Components 22
Build & data
Shared transformation scripts, coverage maps, and orchestration for font package generation.
- Gulpfile · Top-level build entrypoint that wires Gulp tasks together.
gulpfile.js - Gulp tasks · Build and preview task definitions used by the orchestration layer.
gulp-tasks - Scripts · Main asset-generation layer for CSS, CDN artifacts, zips, and Unicode mapping.
scripts - Coverage data · Family, weight, and Unicode coverage definitions used to drive package generation.
scripts/data
Core packages
Primary distributable Plex families and variable-font bundles.
- Plex Sans · Primary Sans family package with complete and split web/font bundles.
packages/plex-sans - Plex Serif · Serif family package distributed as complete and split bundles.
packages/plex-serif - Plex Mono · Monospace family package distributed as complete and split bundles.
packages/plex-mono - Plex Math · Math companion package with complete font formats.
packages/plex-math - Sans variable · Variable Sans bundle with Roman and Italic CSS entrypoints.
packages/plex-sans-variable - Serif variable · Variable Serif bundle with Roman and Italic CSS entrypoints.
packages/plex-serif-variable
Locale packages
Script- and locale-specific Sans packages built from shared family rules.
- Sans JP · Japanese Sans package with hinted and unhinted outputs.
packages/plex-sans-jp - Sans KR · Korean Sans package with hinted and unhinted outputs.
packages/plex-sans-kr - Sans SC · Simplified Chinese Sans package with split web assets.
packages/plex-sans-sc - Sans TC · Traditional Chinese Sans package with split web assets.
packages/plex-sans-tc - Sans Arabic · Arabic Sans package distributed independently from the core family.
packages/plex-sans-arabic - Sans Devanagari · Devanagari Sans package distributed independently from the core family.
packages/plex-sans-devanagari - Sans Hebrew · Hebrew Sans package distributed independently from the core family.
packages/plex-sans-hebrew
Verify & publish
Browser-based validation and GitHub Actions release flows.
- Cypress · End-to-end rendering checks and Percy-integrated visual verification.
cypress - Test pages · Browser fixtures used to validate local and CDN-delivered fonts.
test - GitHub Actions · Automated publish-to-CDN workflows for release and test channels.
.github/workflows
Repo tooling
Monorepo management, commit hooks, and workspace packaging.
- Lerna · Coordinates package-level publishing and workspace management.
lerna.json - Yarn cache · Pinned Yarn toolchain with checked-in cache for reproducible builds.
.yarn
Connections 26
- Gulpfile → Gulp tasks: orchestrates · The root gulpfile delegates to task modules.
- Gulp tasks → Scripts: invokes · Build tasks call into generation scripts.
- Scripts → Coverage data: reads · Scripts use family and Unicode metadata to decide outputs.
- Scripts → Plex Sans: builds · Shared scripts produce the primary Sans package assets.
- Scripts → Plex Serif: builds · Shared scripts produce the Serif package assets.
- Scripts → Plex Mono: builds · Shared scripts produce the Mono package assets.
- Scripts → Plex Math: builds · Shared scripts produce the Math package assets.
- Scripts → Sans variable: builds · Scripts emit variable Sans CSS and font bundles.
- Scripts → Serif variable: builds · Scripts emit variable Serif CSS and font bundles.
- Scripts → Sans JP: builds · Scripts generate locale-specific Sans packages.
- Scripts → Sans KR: builds · Scripts generate locale-specific Sans packages.
- Scripts → Sans SC: builds · Scripts generate locale-specific Sans packages.
- Scripts → Sans TC: builds · Scripts generate locale-specific Sans packages.
- Scripts → Sans Arabic: builds · Scripts generate locale-specific Sans packages.
- Scripts → Sans Devanagari: builds · Scripts generate locale-specific Sans packages.
- Scripts → Sans Hebrew: builds · Scripts generate locale-specific Sans packages.
- Gulp tasks → Cypress: validates · Build output is checked through browser-based tests and visual snapshots.
- Cypress → Test pages: loads · Cypress exercises local and CDN test fixtures.
- GitHub Actions → Scripts: runs · CI workflows execute the build and publish scripts.
- GitHub Actions → Cypress: checks · Release automation includes verification before publish.
- GitHub Actions → Lerna: publishes · Workflow publishes package releases and CDN artifacts through the monorepo.
- Lerna → Plex Sans: coordinates · Monorepo publishing treats each family package independently.
- Lerna → Plex Serif: coordinates · Monorepo publishing treats each family package independently.
- Lerna → Plex Mono: coordinates · Monorepo publishing treats each family package independently.
- Lerna → Sans JP: coordinates · Monorepo publishing treats each package independently.
- Yarn cache → Gulpfile: toolchain · Yarn provides the pinned Node/package environment used by the build.