Files
zeekay b9b47efcda Arabic companions: Noto Kufi Arabic under Zen, Noto Sans Arabic beside it; 1.9.4
Zen draws no Arabic, so an Arabic page fell to whatever face the browser
picked. Two variable companions over Zen's own weight axis, cut to the
Arabic blocks, now ship in fonts/arabic. Each is declared under its own
family with an Arabic unicode-range, and the default under Zen and Zen
Mono too, so font-family: Zen sets Arabic and a page with no Arabic on it
requests nothing new.

They are not ours and keep their names, notices and vendor; identity.py
checks them for exactly that, from the table arabic.py builds them from,
pinned by commit and checksum. next.mjs refuses a default whose weight
range is not Zen's: faces composite only when their descriptors match,
and a companion that wins the weight match sends Latin to the system sans.
2026-10-22 19:22:13 -07:00

6.2 KiB
Raw Permalink Blame History

Zen, Zen Mono & Zen Pixel

Zen is the Hanzo type family, under the SIL Open Font License. Every copyright the licence requires is in LICENSE.txt, which ships beside the binaries.

Zen is a sans-serif typeface designed for legibility and simplicity. It is modern, geometric, and based on the principles of classic Swiss typography. It is designed to be used in body copy, headlines, logos, posters, and other large display sizes.

Zen Mono is a monospaced typeface, crafted to be the perfect partner to Zen. It is designed to be used in code editors, diagrams, terminals, and other text-based interfaces where code is rendered.

Zen Pixel is a display typeface family featuring five unique pixel-based variants, each with a distinct visual style. It is designed for decorative use in headlines, logos, and other display contexts where a pixelated aesthetic is desired.

Installation

pnpm add @hanzo/font

Using with Next.js

Zen is exported from @hanzo/font/sans, ZenMono can be found in @hanzo/font/mono, and Zen Pixel variants are available from @hanzo/font/pixel. All are NextFontWithVariable instances. You can learn more by reading the next/font docs.

Zen Pixel Variants

Zen Pixel includes five distinct variants, each exported separately:

Export CSS Variable Description
ZenPixelSquare --font-zen-pixel-square Square pixel shapes
ZenPixelGrid --font-zen-pixel-grid Grid-based pixel pattern
ZenPixelCircle --font-zen-pixel-circle Circular pixel shapes
ZenPixelTriangle --font-zen-pixel-triangle Triangular pixel shapes
ZenPixelLine --font-zen-pixel-line Line-based pixel pattern
import {
  ZenPixelSquare,
  ZenPixelGrid,
  ZenPixelCircle,
  ZenPixelTriangle,
  ZenPixelLine,
} from "@hanzo/font/pixel";

App Router

In app/layout.js:

import { Zen } from "@hanzo/font/sans";

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={Zen.className}>
      <body>{children}</body>
    </html>
  );
}

Pages Router

In pages/_app.js:

import { Zen } from "@hanzo/font/sans";

export default function MyApp({ Component, pageProps }) {
  return (
    <main className={Zen.className}>
      <Component {...pageProps} />
    </main>
  );
}

If you're using a version of Next.js that's older than 15, then in next.config.js or next.config.mjs add:

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
+  transpilePackages: ["@hanzo/font"],
};

export default nextConfig;

This is required to fix errors like:

  • TypeError: next_font_local__WEBPACK_IMPORTED_MODULE_0___default(...) is not a function
  • SyntaxError: Cannot use import statement outside a module

With Tailwind CSS

All Zen fonts can be used through CSS variables.

  • Zen: --font-zen-sans
  • ZenMono: --font-zen-mono
  • ZenPixelSquare: --font-zen-pixel-square
  • ZenPixelGrid: --font-zen-pixel-grid
  • ZenPixelCircle: --font-zen-pixel-circle
  • ZenPixelTriangle: --font-zen-pixel-triangle
  • ZenPixelLine: --font-zen-pixel-line

In app/layout.js:

import { Zen } from "@hanzo/font/sans";
import { ZenMono } from "@hanzo/font/mono";
import { ZenPixelSquare } from "@hanzo/font/pixel";

export default function RootLayout({ children }) {
  return (
    <html
      lang="en"
      className={`${Zen.variable} ${ZenMono.variable} ${ZenPixelSquare.variable}`}
    >
      <body>{children}</body>
    </html>
  );
}
Tailwind CSS V4

Then in tailwind.css:

@theme {
  /* rest of your theme config */

  --font-sans: var(--font-zen-sans);
  --font-mono: var(--font-zen-mono);
  --font-pixel-square: var(--font-zen-pixel-square);
  --font-pixel-grid: var(--font-zen-pixel-grid);
  --font-pixel-circle: var(--font-zen-pixel-circle);
  --font-pixel-triangle: var(--font-zen-pixel-triangle);
  --font-pixel-line: var(--font-zen-pixel-line);

  /* rest of your theme config */
}
Tailwind CSS V3

Then in tailwind.config.js:

module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ["var(--font-zen-sans)"],
        mono: ["var(--font-zen-mono)"],
        "pixel-square": ["var(--font-zen-pixel-square)"],
        "pixel-grid": ["var(--font-zen-pixel-grid)"],
        "pixel-circle": ["var(--font-zen-pixel-circle)"],
        "pixel-triangle": ["var(--font-zen-pixel-triangle)"],
        "pixel-line": ["var(--font-zen-pixel-line)"],
      },
    },
  },
};

Arabic

Zen draws Latin and Cyrillic and no Arabic. @hanzo/font/css carries two Arabic companions, each a variable font over the same weight axis as Zen (100–900), cut to the Arabic blocks (U+0600–06FF, U+0750–077F, U+FB50–FDFF, U+FE70–FEFC):

Family File woff2
Noto Kufi Arabic fonts/arabic/NotoKufiArabic-Variable.woff2 94.7 KB
Noto Sans Arabic fonts/arabic/NotoSansArabic-Variable.woff2 132.5 KB

Each is declared under its own family with an Arabic unicode-range, and the default (Noto Kufi Arabic, also var(--font-zen-arabic)) is declared under Zen and Zen Mono too. So font-family: Zen sets Arabic with no other change, and a page with no Arabic on it never requests an Arabic face. To set Arabic in the other companion, name it ahead of Zen: font-family: 'Noto Sans Arabic', Zen, sans-serif.

Both cover every Arabic-script language Hanzo ships (Arabic, Persian, Dari, Urdu, Pashto, Sindhi, Sorani Kurdish, Uyghur, Shahmukhi Punjabi). They are not ours: each keeps its own name and notice under the SIL Open Font License, in fonts/arabic/OFL.txt, and scripts/arabic.py rebuilds them from upstream pinned by commit and checksum. The next/font bindings carry Zen only.

License

The Zen font family is free and open sourced under the SIL Open Font License. The Arabic companions are the Noto Project's, under the same license (dist/fonts/arabic/OFL.txt).