Font Management
How to load and configure fonts for rendered Stream Deck UI.
Why Fonts Are Required
The renderer cannot access system fonts from the Stream Deck runtime. It needs font file data (ArrayBuffer or Buffer) passed explicitly.
Supported formats by backend:
| Format | Native Binding (default) | WASM |
|---|---|---|
.ttf | ✅ | ✅ |
.otf | ✅ | ✅ |
.woff | ✅ | ❌ |
.woff2 | ✅ | ❌ |
If you're using the WASM backend (takumi: "wasm"), only TTF and OTF fonts are supported.
Google Fonts (Recommended)
The googleFont() helper downloads TTF fonts directly from Google Fonts — no npm package needed. Font files are cached to .google-fonts/ in your project directory, so only the first run requires network access.
import { createPlugin, googleFont } from "@fcannizzaro/streamdeck-react";
const inter = await googleFont("Inter");
const plugin = createPlugin({
fonts: [inter],
actions: [...],
});Multiple Weights
const fonts = await googleFont("Inter", [
{ weight: 400 },
{ weight: 700 },
]);
const plugin = createPlugin({ fonts, actions: [...] });Single Variant
const bold = await googleFont("Inter", { weight: 700 });
const italic = await googleFont("Inter", { weight: 400, style: "italic" });Multiple Families
const [inter, robotoMono] = await Promise.all([
googleFont("Inter"),
googleFont("Roboto Mono"),
]);
const plugin = createPlugin({
fonts: [inter, robotoMono],
actions: [...],
});Disk Cache
Downloaded fonts are saved to .google-fonts/ in the current working directory. Subsequent calls read from disk without any network access. Add this directory to your .gitignore:
.google-fonts/To force a re-download, delete the cache directory.
GoogleFontVariant
interface GoogleFontVariant {
weight?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
style?: "normal" | "italic";
}Both fields are optional. Defaults: weight: 400, style: "normal".
FontConfig Interface
interface FontConfig {
name: string;
data: ArrayBuffer | Buffer;
weight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
style: "normal" | "italic";
}Loading Fonts Manually
If you need fonts not available on Google Fonts, you can load them manually via readFile:
import { readFile } from "node:fs/promises";
const fonts = [
{
name: "Inter",
data: await readFile("./fonts/Inter-Regular.ttf"),
weight: 400 as const,
style: "normal" as const,
},
{
name: "Inter",
data: await readFile("./fonts/Inter-Bold.ttf"),
weight: 700 as const,
style: "normal" as const,
},
];If using the WASM backend (takumi: "wasm"), use .ttf or .otf files only. WOFF and WOFF2 are
not supported in WASM mode. The default native-binding backend supports all formats including
.woff and .woff2.
Using Fonts in Components
The renderer resolves fonts by matching fontFamily, fontWeight, and fontStyle:
<span style={{ fontFamily: 'Inter', fontWeight: 700 }}>Bold text</span>
<span style={{ fontFamily: 'Inter', fontWeight: 400 }}>Regular text</span>If a requested weight isn't loaded, the nearest available weight is used.
Font Bundle Size
Each font weight/style is a separate file:
- Latin-only subset: ~50-300KB
- CJK character sets: ~1-5MB
Plugins shipping multiple fonts will have a larger bundle. Consider subsetting fonts to reduce size.