# ibm/plex architecture

> Architecture diagram of the GitHub repository ibm/plex, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-24). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ibm/plex
- Repository: https://github.com/ibm/plex

## Overview

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`](https://github.com/ibm/plex/tree/master/scripts) (Scripts), [`lerna.json`](https://github.com/ibm/plex/blob/master/lerna.json) (Lerna), [`.github/workflows`](https://github.com/ibm/plex/blob/master/.github/workflows) (GitHub Actions), [`gulp-tasks`](https://github.com/ibm/plex/tree/master/gulp-tasks) (Gulp tasks)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_g_build["Build & data"]
  node_n_gulpfile["Gulpfile<br/>orchestrator<br/>[gulpfile.js]"]
  node_n_gulp_tasks["Gulp tasks<br/>task layer"]
  node_n_scripts["Scripts<br/>transform layer"]
  node_n_data[("Coverage data<br/>metadata")]
end

subgraph group_g_packages_core["Core packages"]
  node_n_sans["Plex Sans<br/>font package"]
  node_n_serif["Plex Serif<br/>font package"]
  node_n_mono["Plex Mono<br/>font package"]
  node_n_math["Plex Math<br/>font package"]
  node_n_sans_var["Sans variable<br/>font package"]
  node_n_serif_var["Serif variable<br/>font package"]
end

subgraph group_g_packages_locale["Locale packages"]
  node_n_sans_jp["Sans JP<br/>locale package"]
  node_n_sans_kr["Sans KR<br/>locale package"]
  node_n_sans_sc["Sans SC<br/>locale package"]
  node_n_sans_tc["Sans TC<br/>locale package"]
  node_n_sans_arabic["Sans Arabic<br/>locale package"]
  node_n_sans_deva["Sans Devanagari<br/>locale package"]
  node_n_sans_hebrew["Sans Hebrew<br/>locale package"]
end

subgraph group_g_verify["Verify & publish"]
  node_n_cypress["Cypress<br/>browser tests"]
  node_n_test_pages["Test pages<br/>static preview"]
  node_n_github_actions["GitHub Actions<br/>ci/release<br/>[workflows]"]
end

subgraph group_g_tooling["Repo tooling"]
  node_n_lerna["Lerna<br/>monorepo coordinator<br/>[lerna.json]"]
  node_n_yarn[("Yarn cache<br/>workspace toolchain<br/>[.yarn]")]
end

node_n_gulpfile -->|"orchestrates"| node_n_gulp_tasks
node_n_gulp_tasks -->|"invokes"| node_n_scripts
node_n_scripts -->|"reads"| node_n_data
node_n_scripts -->|"builds"| node_n_sans
node_n_scripts -->|"builds"| node_n_serif
node_n_scripts -->|"builds"| node_n_mono
node_n_scripts -->|"builds"| node_n_math
node_n_scripts -->|"builds"| node_n_sans_var
node_n_scripts -->|"builds"| node_n_serif_var
node_n_scripts -->|"builds"| node_n_sans_jp
node_n_scripts -->|"builds"| node_n_sans_kr
node_n_scripts -->|"builds"| node_n_sans_sc
node_n_scripts -->|"builds"| node_n_sans_tc
node_n_scripts -->|"builds"| node_n_sans_arabic
node_n_scripts -->|"builds"| node_n_sans_deva
node_n_scripts -->|"builds"| node_n_sans_hebrew
node_n_gulp_tasks -->|"validates"| node_n_cypress
node_n_cypress -->|"loads"| node_n_test_pages
node_n_github_actions -->|"runs"| node_n_scripts
node_n_github_actions -->|"checks"| node_n_cypress
node_n_github_actions -->|"publishes"| node_n_lerna
node_n_lerna -->|"coordinates"| node_n_sans
node_n_lerna -->|"coordinates"| node_n_serif
node_n_lerna -->|"coordinates"| node_n_mono
node_n_lerna -->|"coordinates"| node_n_sans_jp
node_n_yarn -->|"toolchain"| node_n_gulpfile

click node_n_gulpfile "https://github.com/ibm/plex/blob/master/gulpfile.js"
click node_n_gulp_tasks "https://github.com/ibm/plex/tree/master/gulp-tasks"
click node_n_scripts "https://github.com/ibm/plex/tree/master/scripts"
click node_n_data "https://github.com/ibm/plex/tree/master/scripts/data"
click node_n_sans "https://github.com/ibm/plex/tree/master/packages/plex-sans"
click node_n_serif "https://github.com/ibm/plex/tree/master/packages/plex-serif"
click node_n_mono "https://github.com/ibm/plex/tree/master/packages/plex-mono"
click node_n_math "https://github.com/ibm/plex/tree/master/packages/plex-math"
click node_n_sans_var "https://github.com/ibm/plex/tree/master/packages/plex-sans-variable"
click node_n_serif_var "https://github.com/ibm/plex/tree/master/packages/plex-serif-variable"
click node_n_sans_jp "https://github.com/ibm/plex/tree/master/packages/plex-sans-jp"
click node_n_sans_kr "https://github.com/ibm/plex/tree/master/packages/plex-sans-kr"
click node_n_sans_sc "https://github.com/ibm/plex/tree/master/packages/plex-sans-sc"
click node_n_sans_tc "https://github.com/ibm/plex/tree/master/packages/plex-sans-tc"
click node_n_sans_arabic "https://github.com/ibm/plex/tree/master/packages/plex-sans-arabic"
click node_n_sans_deva "https://github.com/ibm/plex/tree/master/packages/plex-sans-devanagari"
click node_n_sans_hebrew "https://github.com/ibm/plex/tree/master/packages/plex-sans-hebrew"
click node_n_cypress "https://github.com/ibm/plex/tree/master/cypress"
click node_n_test_pages "https://github.com/ibm/plex/tree/master/test"
click node_n_github_actions "https://github.com/ibm/plex/blob/master/.github/workflows"
click node_n_lerna "https://github.com/ibm/plex/blob/master/lerna.json"
click node_n_yarn "https://github.com/ibm/plex/blob/master/.yarn"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_n_gulpfile,node_n_gulp_tasks,node_n_scripts,node_n_data toneBlue
class node_n_sans,node_n_serif,node_n_mono,node_n_math,node_n_sans_var,node_n_serif_var toneAmber
class node_n_sans_jp,node_n_sans_kr,node_n_sans_sc,node_n_sans_tc,node_n_sans_arabic,node_n_sans_deva,node_n_sans_hebrew toneMint
class node_n_cypress,node_n_test_pages,node_n_github_actions toneRose
class node_n_lerna,node_n_yarn toneIndigo
```

## Components

### Build & data

Shared transformation scripts, coverage maps, and orchestration for font package generation.

- [Gulpfile](https://github.com/ibm/plex/blob/master/gulpfile.js): orchestrator · Top-level build entrypoint that wires Gulp tasks together. · `gulpfile.js`
- [Gulp tasks](https://github.com/ibm/plex/tree/master/gulp-tasks): task layer · Build and preview task definitions used by the orchestration layer. · `gulp-tasks`
- [Scripts](https://github.com/ibm/plex/tree/master/scripts): transform layer · Main asset-generation layer for CSS, CDN artifacts, zips, and Unicode mapping. · `scripts`
- [Coverage data](https://github.com/ibm/plex/tree/master/scripts/data): metadata · 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](https://github.com/ibm/plex/tree/master/packages/plex-sans): font package · Primary Sans family package with complete and split web/font bundles. · `packages/plex-sans`
- [Plex Serif](https://github.com/ibm/plex/tree/master/packages/plex-serif): font package · Serif family package distributed as complete and split bundles. · `packages/plex-serif`
- [Plex Mono](https://github.com/ibm/plex/tree/master/packages/plex-mono): font package · Monospace family package distributed as complete and split bundles. · `packages/plex-mono`
- [Plex Math](https://github.com/ibm/plex/tree/master/packages/plex-math): font package · Math companion package with complete font formats. · `packages/plex-math`
- [Sans variable](https://github.com/ibm/plex/tree/master/packages/plex-sans-variable): font package · Variable Sans bundle with Roman and Italic CSS entrypoints. · `packages/plex-sans-variable`
- [Serif variable](https://github.com/ibm/plex/tree/master/packages/plex-serif-variable): font package · 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](https://github.com/ibm/plex/tree/master/packages/plex-sans-jp): locale package · Japanese Sans package with hinted and unhinted outputs. · `packages/plex-sans-jp`
- [Sans KR](https://github.com/ibm/plex/tree/master/packages/plex-sans-kr): locale package · Korean Sans package with hinted and unhinted outputs. · `packages/plex-sans-kr`
- [Sans SC](https://github.com/ibm/plex/tree/master/packages/plex-sans-sc): locale package · Simplified Chinese Sans package with split web assets. · `packages/plex-sans-sc`
- [Sans TC](https://github.com/ibm/plex/tree/master/packages/plex-sans-tc): locale package · Traditional Chinese Sans package with split web assets. · `packages/plex-sans-tc`
- [Sans Arabic](https://github.com/ibm/plex/tree/master/packages/plex-sans-arabic): locale package · Arabic Sans package distributed independently from the core family. · `packages/plex-sans-arabic`
- [Sans Devanagari](https://github.com/ibm/plex/tree/master/packages/plex-sans-devanagari): locale package · Devanagari Sans package distributed independently from the core family. · `packages/plex-sans-devanagari`
- [Sans Hebrew](https://github.com/ibm/plex/tree/master/packages/plex-sans-hebrew): locale package · Hebrew Sans package distributed independently from the core family. · `packages/plex-sans-hebrew`

### Verify & publish

Browser-based validation and GitHub Actions release flows.

- [Cypress](https://github.com/ibm/plex/tree/master/cypress): browser tests · End-to-end rendering checks and Percy-integrated visual verification. · `cypress`
- [Test pages](https://github.com/ibm/plex/tree/master/test): static preview · Browser fixtures used to validate local and CDN-delivered fonts. · `test`
- [GitHub Actions](https://github.com/ibm/plex/blob/master/.github/workflows): ci/release · Automated publish-to-CDN workflows for release and test channels. · `.github/workflows`

### Repo tooling

Monorepo management, commit hooks, and workspace packaging.

- [Lerna](https://github.com/ibm/plex/blob/master/lerna.json): monorepo coordinator · Coordinates package-level publishing and workspace management. · `lerna.json`
- [Yarn cache](https://github.com/ibm/plex/blob/master/.yarn): workspace toolchain · Pinned Yarn toolchain with checked-in cache for reproducible builds. · `.yarn`

## Connections

- 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.
