Nib gives you access to the full set of SwiftUI system fonts, custom size and weight control, custom font files, and rich text with attributed strings.
System Fonts¶
System fonts are predefined on the Font class and match the macOS Dynamic Type styles:
import nib
nib.Text("Large Title", font=nib.Font.LARGE_TITLE)
nib.Text("Title", font=nib.Font.TITLE)
nib.Text("Title 2", font=nib.Font.TITLE2)
nib.Text("Title 3", font=nib.Font.TITLE3)
nib.Text("Headline", font=nib.Font.HEADLINE)
nib.Text("Subheadline", font=nib.Font.SUBHEADLINE)
nib.Text("Body", font=nib.Font.BODY)
nib.Text("Callout", font=nib.Font.CALLOUT)
nib.Text("Footnote", font=nib.Font.FOOTNOTE)
nib.Text("Caption", font=nib.Font.CAPTION)
nib.Text("Caption 2", font=nib.Font.CAPTION2)
| Font | Typical Use |
|---|---|
Font.LARGE_TITLE |
Screen titles, hero text |
Font.TITLE |
Section titles |
Font.TITLE2 |
Secondary titles |
Font.TITLE3 |
Tertiary titles |
Font.HEADLINE |
Row titles, bold labels |
Font.SUBHEADLINE |
Subtitles, secondary labels |
Font.BODY |
Main content text (default) |
Font.CALLOUT |
Callout boxes, hints |
Font.FOOTNOTE |
Footer text, fine print |
Font.CAPTION |
Labels below images |
Font.CAPTION2 |
Smallest caption text |
Custom Size¶
Use Font.system() to create a system font with a specific point size and optional weight:
nib.Text("18pt Regular", font=nib.Font.system(18))
nib.Text("24pt Bold", font=nib.Font.system(24, nib.FontWeight.BOLD))
nib.Text("14pt Light", font=nib.Font.system(14, nib.FontWeight.LIGHT))
Font Weight¶
The FontWeight enum provides all standard weights:
| Weight | Constant |
|---|---|
| Ultra Light | nib.FontWeight.ULTRA_LIGHT |
| Thin | nib.FontWeight.THIN |
| Light | nib.FontWeight.LIGHT |
| Regular | nib.FontWeight.REGULAR |
| Medium | nib.FontWeight.MEDIUM |
| Semibold | nib.FontWeight.SEMIBOLD |
| Bold | nib.FontWeight.BOLD |
| Heavy | nib.FontWeight.HEAVY |
| Black | nib.FontWeight.BLACK |
You can also apply weight as a standalone modifier using font_weight:
nib.Text("Bold Body", font=nib.Font.BODY, font_weight=nib.FontWeight.BOLD)
Custom Fonts¶
Use Font.custom() to specify a font family by name. The font must be installed on the system or registered with the app.
nib.Text("Custom Font", font=nib.Font.custom("Inter", size=16))
nib.Text("Weighted", font=nib.Font.custom("Inter", size=16, weight=nib.FontWeight.SEMIBOLD))
Loading Custom Font Files¶
There are two ways to load custom font files (.ttf, .otf, .ttc):
1. Auto-detection from the assets/ directory (recommended)
Place font files anywhere inside your project's assets/ folder. Nib scans this directory on startup and registers every .ttf, .otf, .ttc, .woff, and .woff2 file it finds. The font name is derived from the filename without extension.
my_project/
main.py
assets/
Inter-Regular.ttf
Inter-Bold.ttf
JetBrainsMono-Regular.ttf
# Fonts are auto-detected from assets/ -- no registration needed
nib.Text("Hello", font=nib.Font.custom("Inter-Regular", size=16))
nib.Text("Code", font=nib.Font.custom("JetBrainsMono-Regular", size=14))
2. Manual registration via app.fonts
For fonts stored elsewhere, register them by setting app.fonts to a dictionary mapping names to absolute file paths or URLs:
def main(app: nib.App):
app.fonts = {
"CustomFont": "/Users/me/fonts/CustomFont.ttf",
"WebFont": "https://example.com/fonts/WebFont.otf",
}
app.build(
nib.Text("Custom", font=nib.Font.custom("CustomFont", size=16))
)
Note
Auto-detected fonts and manually registered fonts are merged. If the same name appears in both, the manual registration takes precedence.
TextStyle¶
TextStyle groups font, decorations, and spacing into a single reusable object. Use it with the style parameter on Text.
nib.Text("Styled", style=nib.TextStyle(bold=True, italic=True, underline=True))
Available TextStyle attributes:
| Attribute | Type | Description |
|---|---|---|
font |
Font |
Font to use |
color |
str |
Text color |
weight |
str |
Font weight |
bold |
bool |
Bold text |
italic |
bool |
Italic text |
strikethrough |
bool |
Strikethrough line |
strikethrough_color |
str |
Color of strikethrough |
underline |
bool |
Underline text |
underline_color |
str |
Color of underline |
monospaced |
bool |
Monospaced font |
monospaced_digit |
bool |
Monospaced digits (for aligned numbers) |
kerning |
float |
Letter spacing |
tracking |
float |
Uniform spacing between characters |
baseline_offset |
float |
Vertical offset from baseline |
Combining decorations¶
# Bold, italic, and underlined
nib.Text(
"Fancy Text",
style=nib.TextStyle(
font=nib.Font.system(18),
bold=True,
italic=True,
underline=True,
underline_color="blue",
kerning=1.5,
),
)
Monospaced digits¶
Use monospaced_digit for numbers that need to align vertically (clocks, counters, tables):
nib.Text("12:34:56", style=nib.TextStyle(monospaced_digit=True, font=nib.Font.TITLE))
Predefined text styles¶
TextStyle also has predefined presets that mirror the system font hierarchy:
nib.Text("Title", style=nib.TextStyle.TITLE)
nib.Text("Headline", style=nib.TextStyle.HEADLINE)
nib.Text("Body", style=nib.TextStyle.BODY)
nib.Text("Caption", style=nib.TextStyle.CAPTION)
AttributedString -- Rich Text¶
AttributedString lets you combine multiple styles within a single Text view. Pass a list of attributed strings to the strings parameter:
nib.Text(
strings=[
nib.AttributedString("Bold", style=nib.TextStyle(bold=True)),
nib.AttributedString(" Normal "),
nib.AttributedString("Red", color="red"),
nib.AttributedString(" Italic", style=nib.TextStyle(italic=True)),
],
)
Each AttributedString accepts:
| Parameter | Type | Description |
|---|---|---|
content |
str |
The text segment |
style |
TextStyle |
Full style configuration |
color |
str or Color |
Color override |
font |
Font |
Font override |
Mixing fonts and colors¶
nib.Text(
strings=[
nib.AttributedString(
"Important: ",
style=nib.TextStyle(bold=True, color="red"),
),
nib.AttributedString(
"This is normal body text that follows the warning.",
font=nib.Font.BODY,
),
],
)
Status line example¶
nib.Text(
strings=[
nib.AttributedString("Status: ", style=nib.TextStyle(bold=True)),
nib.AttributedString("Connected", color="green"),
nib.AttributedString(" | "),
nib.AttributedString("3 devices", style=nib.TextStyle(monospaced_digit=True)),
],
)
Full Example¶
A complete app showcasing typography features:
import nib
def main(app: nib.App):
app.title = "Typography"
app.icon = nib.SFSymbol("textformat")
app.width = 320
app.height = 500
app.build(
nib.ScrollView(
controls=[
nib.VStack(
controls=[
# System font scale
nib.Text("System Fonts", font=nib.Font.HEADLINE),
nib.Text("Large Title", font=nib.Font.LARGE_TITLE),
nib.Text("Title", font=nib.Font.TITLE),
nib.Text("Headline", font=nib.Font.HEADLINE),
nib.Text("Body (default)", font=nib.Font.BODY),
nib.Text("Caption", font=nib.Font.CAPTION),
nib.Divider(),
# Weights
nib.Text("Font Weights", font=nib.Font.HEADLINE),
nib.Text("Ultra Light", font=nib.Font.system(16, nib.FontWeight.ULTRA_LIGHT)),
nib.Text("Light", font=nib.Font.system(16, nib.FontWeight.LIGHT)),
nib.Text("Regular", font=nib.Font.system(16, nib.FontWeight.REGULAR)),
nib.Text("Medium", font=nib.Font.system(16, nib.FontWeight.MEDIUM)),
nib.Text("Bold", font=nib.Font.system(16, nib.FontWeight.BOLD)),
nib.Text("Black", font=nib.Font.system(16, nib.FontWeight.BLACK)),
nib.Divider(),
# Text decorations
nib.Text("Text Styles", font=nib.Font.HEADLINE),
nib.Text("Bold", style=nib.TextStyle(bold=True)),
nib.Text("Italic", style=nib.TextStyle(italic=True)),
nib.Text("Underline", style=nib.TextStyle(underline=True)),
nib.Text("Strikethrough", style=nib.TextStyle(strikethrough=True)),
nib.Text("Monospaced", style=nib.TextStyle(monospaced=True)),
nib.Divider(),
# Attributed string
nib.Text("Rich Text", font=nib.Font.HEADLINE),
nib.Text(
strings=[
nib.AttributedString("Hello ", color="blue"),
nib.AttributedString("World", style=nib.TextStyle(bold=True, color="red")),
nib.AttributedString("!", font=nib.Font.TITLE),
],
),
],
spacing=6,
alignment=nib.HorizontalAlignment.LEADING,
padding=16,
),
],
)
)
nib.run(main)