LeCodesdocs

Fonts

Custom fonts are registered with registerFont, then referenced by fontFamily in text styles. System families need no registration: "serif", "sans-serif", "monospaced" work as fontFamily values out of the box.

At a glance

TypeScript
const screen = UIScreen([
  UIText("Custom type").style({ fontFamily: "Inter", fontWeight: 700, fontSize: 24, color: "white" }),
]).style({ bgColor: "black", p: 20 })

Promise.all([
  registerFont("Inter", asset('./fonts/Inter.ttf'), { weight: 400 }),
  registerFont("Inter", asset('./fonts/Inter-Bold.ttf'), { weight: 700 }),
]).then(() => screen.open())

registerFont

TypeScript
registerFont(fontFamily: string, url: string, options?: {
  weight?: number,                 // which fontWeight this file serves (400, 700, …)
  style?: "normal" | "italic",
}): Promise<void>
  • fontFamily is the name you'll use in .style({ fontFamily }). Register one call per file: a family with regular + bold is two registerFont calls with the same name and different weights.
  • url — a project font file via asset('./fonts/X.ttf') (or an import), or a remote https://… URL as a plain string.
  • The promise resolves when the font is loaded and usable, and rejects on failure (bad URL, unparsable file).

Load fonts before opening the screen

A font applies reliably only to screens opened after it has loaded — text already on screen may keep the fallback font on some hosts. The standard pattern is to gate the entry point on the fonts:

TypeScript
Promise.all([
  registerFont("Inter", asset('./fonts/Inter.ttf'), { weight: 400 }),
  registerFont("Inter", asset('./fonts/Inter-Bold.ttf'), { weight: 700 }),
]).then(() => Router.init(homeScreen))     // or screen.open()
Note

there is no style inheritance — fontFamily is set per UIText (extract a shared Style<UIText> object rather than relying on a parent).

Pitfalls

TypeScript
// ✗ bare path — resolves only for remote http(s) URLs
registerFont("Inter", "./fonts/Inter.ttf")
// ✓ project files go through asset() (compile-time macro, literal string only)
registerFont("Inter", asset('./fonts/Inter.ttf'))

// ✗ opening the screen before the font resolves — text renders with the fallback
registerFont("Inter", asset('./fonts/Inter.ttf'))
screen.open()
// ✓ await it (Promise.all for several weights), then open

See also