vercel-labs / vercel-labs/native
Canvas: support native macOS system fonts
Nobody has claimed this yet.
- Dominant language
- Zig
- Stars
- 7.7k
- Forks
- 314
- Avg merge
- 5h
- Merged PRs (30d)
- 13
Description
Problem
Canvas typography currently cannot explicitly select the native macOS system font.
With Native SDK CLI 0.6.2, setting:
tokens.typography.font_id = canvas.default_sans_font_id;
tokens.typography.font_family = .system_sans;
does not make Canvas text use SF Pro. FontFamily.system_sans only maps to the CSS name system-ui, while the macOS Canvas packet carries a font_id. In appkit_host.m, the built-in resolver for the default sans IDs tries Geist family names first and only falls back to [NSFont systemFontOfSize:] when Geist is unavailable.
Registering a TTF is not an equivalent workaround: Apple's system font is not a font apps should bundle, and a bundled face loses the native metrics/rendering chosen by macOS.
Expected behavior
Provide an explicit Canvas-native way to select system fonts, for example reserved system sans/mono font IDs or a family channel that reaches native text measurement and drawing:
system_sansresolves throughNSFont systemFontOfSize:weight:on macOSsystem_monoresolves throughNSFont monospacedSystemFontOfSize:weight:- medium, bold, italic, and bold-italic span variants stay in the same system family
- measurement and drawing use the same resolver
- existing Geist defaults remain unchanged for apps that do not opt in
Reproduction
- Create a macOS Canvas app with Native SDK 0.6.2.
- Set
typography.font_family = .system_sansand keepdefault_sans_font_id. - Render text while Geist is available.
- The rendered face remains Geist rather than the macOS system face.
Relevant current implementation:
src/primitives/canvas/tokens.zig:FontFamily.system_sansmaps tosystem-uisrc/platform/macos/appkit_host.m:NativeSdkBuiltInFontForFontIdprioritizes Geist for default sans IDs;NativeSdkPacketPreferredFontresolves only the packetfontID
This would let native Canvas apps use the platform's intended typography without shipping a substitute TTF.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/primitives/canvas/tokens.zig to trace the system_sans family mapping, then inspect NativeSdkBuiltInFontForFontId and NativeSdkPacketPreferredFont in src/platform/macos/appkit_host.m. Define the native system-font selection and ensure measurement and drawing use the same resolver, while preserving existing Geist defaults. Done when the requested sans and mono variants select the corresponding macOS fonts and retain their span variants.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, zig
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100