Figma Font Loading Requirements Before Text Operations: Complete Plugin Guide
Every font must be explicitly loaded via await figma.loadFontAsync({ family, style }) before reading or writing any text property in Figma plugins, or the script will throw a "font not loaded" runtime error.
When developing Figma plugins using the use_figma skill in the figma/mcp-server-guide repository, understanding font loading requirements before text operations is essential for successful script execution. The Figma Plugin API operates within a sandboxed JavaScript environment that requires explicit font initialization prior to any text manipulation. Failing to adhere to these mandatory loading sequences results in invisible text, clipped layouts, and complete script failures.
Why Font Loading Is Mandatory in the Figma Plugin Sandbox
The requirement to load fonts before text operations stems from four architectural constraints enforced by the Figma plugin runtime as documented in the MCP server guide.
-
Sandboxed Runtime Isolation: The plugin executes in a separate JavaScript sandbox that maintains its own memory space and cannot access the Figma editor's native font cache. According to the repository documentation, this isolation prevents automatic font availability.
-
Asynchronous Font Acquisition: Fonts may reside on local disks or remote servers, requiring asynchronous fetching. The
figma.loadFontAsync()method returns aPromisethat resolves only after the font data is fully available in the sandbox memory. -
Runtime Error Prevention: Attempting to set
fontName,characters,fontSize, or any glyph-dependent property without prior loading immediately throws the"font not loaded"error. As noted inskills/figma-use/SKILL.md(Critical Rule #8, lines 28-30), this error halts the entire atomic script execution. -
Rendering Consistency: Loaded fonts ensure accurate text measurements for line height, width calculations, and layout positioning, preventing visual glitches like clipped text lines or incorrect bounding boxes.
The Four-Step Font Loading Workflow
The figma/mcp-server-guide repository establishes a strict workflow for font initialization before text operations. Following this sequence prevents runtime exceptions and ensures proper node creation.
-
Collect Unique Font Descriptors: Gather distinct
{ family, style }objects for every font variant required by your script. -
Execute Parallel Loading: Use
await Promise.all(fonts.map(f => figma.loadFontAsync(f)))to load multiple fonts simultaneously, optimizing performance when handling multiple styles. -
Modify Text Properties Only After Await: Create or modify TextNode and TextStyle objects only after the font loading Promise resolves.
-
Return Node IDs: Always return the created or mutated node IDs in the response object, as required by the
use_figmaskill specification.
Code Implementation Patterns for Font Loading
Creating a Simple Text Node
The most basic pattern requires loading the font before instantiating the text node. This follows the example in skills/figma-use/references/text-style-patterns.md (lines 91-93) and enforces Critical Rule #8 from skills/figma-use/SKILL.md.
// Load the font first
await figma.loadFontAsync({ family: 'Inter', style: 'Regular' })
// Create the text node and set its content
const txt = figma.createText()
txt.characters = 'Hello, world!'
txt.fontSize = 24
txt.fontName = { family: 'Inter', style: 'Regular' }
// Position the node away from (0,0) to avoid overlap
txt.x = 100
txt.y = 50
return { createdNodeIds: [txt.id] }
Bulk Loading for Multiple Styles
When working with design systems or multiple text styles, deduplicate font descriptors and load them in parallel. This pattern appears in skills/figma-generate-library/references/token-creation.md (line 699) and skills/figma-use/references/common-patterns.md.
// Define all fonts you will need
const fontSet = new Set()
fontSet.add(JSON.stringify({ family: 'Inter', style: 'Bold' }))
fontSet.add(JSON.stringify({ family: 'Inter', style: 'Medium' }))
// Load them in parallel
await Promise.all(
[...fontSet].map(f => figma.loadFontAsync(JSON.parse(f)))
)
// Now safely create several styled text nodes
const headings = [
{ text: 'Title', size: 32, font: { family: 'Inter', style: 'Bold' } },
{ text: 'Subtitle', size: 24, font: { family: 'Inter', style: 'Medium' } },
]
return { createdNodeIds: headings.map(item => {
const node = figma.createText()
node.fontName = item.font
node.fontSize = item.size
node.characters = item.text
node.x = 100
node.y = 50 + 60 * headings.indexOf(item)
return node.id
})}
Updating Existing Text Styles
When modifying existing TextStyle objects, you must load the font even if it was previously used elsewhere. The skills/figma-use/references/working-with-design-systems/wwds-text-styles.md (lines 79-80) explicitly requires this for any fontName modification.
// Assume you already have a TextStyle object `style`
await figma.loadFontAsync(style.fontName) // must load before modification
style.fontSize = 18
style.lineHeight = { unit: 'PIXELS', value: 24 }
// Return the updated style ID
return { mutatedNodeIds: [style.id] }
Common Pitfalls and Solutions
| Pitfall | Symptom | Fix |
|---|---|---|
Omitted await on loadFontAsync |
Script proceeds, then throws "font not loaded" | Always await the Promise; see SKILL rule #17 in skills/figma-use/SKILL.md |
Incorrect Style String (e.g., "SemiBold" vs "Semi Bold") |
loadFontAsync rejects with error |
Probe with try/catch or use figma.listAvailableFontsAsync() to discover exact style names as noted in wwds-text-styles.md (line 80) |
| Loading Fonts in Tight Loops | Unnecessary promises, slower execution | Deduplicate first using a Set of JSON-stringified descriptors before mapping to load calls |
Setting fontName Before Loading |
Immediate runtime error on property assignment | Load before any property assignment; the rule is enforced by the plugin sandbox per plugin-api-standalone.d.ts (line 1585) |
| Forgetting to Return IDs | Subsequent steps cannot reference created nodes | Follow SKILL checklist item "MUST return ALL created/mutated node IDs" |
Key Repository Files for Font Management
The figma/mcp-server-guide repository contains authoritative documentation for font handling across these specific files:
skills/figma-use/SKILL.md: Contains Critical Rule #8 (lines 28-30) mandating font loading before text operationsskills/figma-use/references/working-with-design-systems/wwds-text-styles.md: Provides detailed guidance on loading fonts before creating or modifying TextStyle objects (lines 79-80)skills/figma-use/references/text-style-patterns.md: Demonstrates practical implementation patterns withloadFontAsynccalls (lines 91-93)skills/figma-use/references/plugin-api-standalone.index.md: ListsloadFontAsyncas a required precondition for text edits (line 77)skills/figma-use/references/plugin-api-standalone.d.ts: Contains TypeScript definitions and method signatures with documentation comments (line 1585)skills/figma-generate-library/references/token-creation.md: Shows bulk-loading patterns for design token generation workflows (line 699)skills/figma-use/references/common-patterns.md: Provides reusable loading snippets for common plugin scenarios
Summary
- Font loading is mandatory: Every script must call
await figma.loadFontAsync({ family, style })before accessing any text properties. - Load before create: Always initialize fonts prior to calling
figma.createText()or modifyingfontNameon existing nodes. - Parallelize for performance: Use
Promise.all()with deduplicated font sets when handling multiple styles. - Return node IDs: Always return created or mutated node IDs to satisfy the
use_figmaskill contract. - Reference authoritative sources: Follow the specific file paths and line references in
skills/figma-use/SKILL.mdand related documentation.
Frequently Asked Questions
What happens if I skip font loading before setting text properties?
The Figma plugin sandbox immediately throws a "font not loaded" runtime error that halts the entire script execution. According to the source code in skills/figma-use/SKILL.md, this is Critical Rule #8 because the sandboxed runtime cannot access the editor's font cache without explicit asynchronous loading.
Can I load multiple fonts simultaneously in Figma plugins?
Yes. The figma.loadFontAsync() method returns a Promise, allowing you to use Promise.all() to load multiple font families and styles in parallel. The repository recommends deduplicating your font descriptors first (using a Set of JSON-stringified objects) to avoid redundant loading operations, as shown in skills/figma-generate-library/references/token-creation.md.
How do I find the correct style string for a font family?
Use figma.listAvailableFontsAsync() to retrieve the exact style names available for each font family. As documented in skills/figma-use/references/working-with-design-systems/wwds-text-styles.md (line 80), style names must match exactly (e.g., "Semi Bold" versus "SemiBold"), and this API call reveals the correct formatting for the style parameter in loadFontAsync().
Do I need to reload fonts for every plugin execution?
Yes. Because the plugin runs in a sandboxed environment that does not persist state between executions, you must call figma.loadFontAsync() every time your script runs, even for fonts that were loaded in previous executions. The font cache is isolated per script invocation according to the architectural constraints described in the repository documentation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →