Dev Mode

Code Generation

How SXL Studio code generation works in Dev Mode: Vue 3, React, JSON (Design), SwiftUI, UIKit, Kotlin, DivKit, view modes, settings, sections, and debugging.

Codegen architecture

SXL Studio has one core codegen pipeline used in two places:

  • Native Figma Code panel (figma.codegen.on("generate"))
  • Plugin Dev Inspect → Code section (main-thread requests)

This keeps output behavior aligned across both surfaces.


Targets and outputs

Supported targets:

  • Vue 3
  • React
  • JSON (Design)
  • SwiftUI
  • UIKit
  • Kotlin
  • DivKit

Native Figma Code panel: typical tabs

Vue 3

  • All — <ComponentName> (or All — <ComponentSetName> (<variants>))
  • Script Setup
  • Template
  • Styles
  • Variables
  • Reference components
  • Optional Code Connect tabs (Import & Usage, file tabs, etc.)
  • Optional Debug tab (when debug trace exists)

React

  • All — <ComponentName>.tsx
  • Template
  • Script
  • Styles
  • Variables
  • Reference components
  • Optional Code Connect tabs
  • Optional Debug tab

JSON (Design)

  • JSON composition — <name>
  • Props
  • Component properties
  • Structure
  • Styles
  • Optional Transitions
  • Optional Theme binding
  • Variables
  • Reference components
  • Optional Code Connect tabs
  • Optional Debug tab

SwiftUI / UIKit / Kotlin

  • Main generated file (.swift / .kt)
  • Variables (Swift) or Variables (Kotlin)
  • Reference components
  • Optional Code Connect tabs
  • Optional Debug tab

DivKit

  • All — <name>.divkit.json
  • Template
  • Styles
  • Variables
  • References
  • Optional Code Connect tabs
  • Optional Debug tab

Plugin Dev Inspect Code section

In the plugin Dev Inspect hub, code output is shown in a single editor with selectors:

  • Language: Vue 3 / React / SwiftUI / UIKit / Kotlin / DivKit / JSON
  • Section: All, Template, Script, Styles, Variables, References
  • View mode: Styled, Decomposed, Raw

Section mapping highlights:

  • Variables and References are cross-target diagnostics.
  • Web targets (Vue 3, React) include Script; native mobile and JSON-card targets (SwiftUI, UIKit, Kotlin, DivKit) skip script-only output and focus on generated file, variables, styles, and references.
  • For JSON, section mapping is semantic:
    • Templatestructure
    • Script → root metadata ($type, name, props, componentProperties)
    • Stylesstyles

Codegen settings

Open Inspect → Code → Settings (gear button) to tune generation for the current Figma file. Empty fields fall back to SXL defaults, so teams can override only the conventions they need.

Main settings:

  • Naming: icon component, icon name pattern, boolean prop collision template, swap prop collision template.
  • Styling: root class name, CSS class case (kebab-case or camelCase), generated header comments.
  • Imports: component import path template such as @/components/{Name}.
  • Mobile: Swift token enum name, Android drawable prefix, DivKit profile (Generic by default), DivKit validation mode, and optional DivKit profile JSON for project mappings.
  • Testing: optional test attribute such as data-testid.
  • Icon rules: ordered rules that map icon layers to names by page, section, set, variant, or description marker.

Icon pattern tokens:

  • {baseName} / {name} — normalized icon/layer name
  • {setName} — component set name
  • {pageName} — Figma page name
  • {sectionName} — nearest section name
  • {variant.<axis>} — component variant axis value

Rules are evaluated from top to bottom. The first matching rule wins; if no rule matches, SXL uses the default icon pattern and then its built-in icon resolver.

Example:

TEXT
Icon component: Icon
Icon name pattern: {baseName}
Component import path: @/components/{Name}
Rule: if pageName = Icons and variant.Size = 24 -> ui-{baseName}-{variant.Size}

View modes (Styled / Decomposed / Raw)

ModeToken/style behaviorTypical use
StyledPrefers composite style references (TextStyle/EffectStyle, etc.) where valid; preserves variable syntax.You want shortest, design-system-first output.
DecomposedSplits composites into atomic properties; keeps variable references where available.You need explicit properties but still token-linked output.
RawResolves to literals (no variable references).Quick prototyping or debugging resolved values.

Notes:

  • Styled mode is not "all-or-nothing": when no valid composite reference exists, generator falls back to concrete node values instead of dropping data.
  • In large trees, code or variable collection may be truncated by safety budgets; output includes a truncation note.

Component Set behavior

When the selected node is a COMPONENT_SET:

  • Vue and React output generate one component contract with variant props and class mapping.
  • DivKit output generates one card with one state per variant.
  • All tab includes a full assembled file for implementation handoff.
  • Variant count is reflected in the generated tab title.

React output notes

React output is designed for React 19 projects:

  • function component in .tsx
  • typed props with ReactNode for slots and instance swaps
  • CSS Modules and clsx
  • configurable component imports through the import path template
  • optional data-testid when configured
  • explicit Figma modes represented as data-fig-mode-* attributes for web targets

Component SLOT layers map to children. Nested component instances become imported PascalCase tags when SXL can infer the component name.


UIKit output notes

UIKit output generates an imperative Swift UIView subclass:

  • UIStackView for auto-layout-like structure
  • UILabel / UIImageView for text and image/icon nodes
  • token-aware colors, dimensions, typography, borders, and effects where supported
  • nested component instances expanded into UIKit subtrees
  • explicit Figma modes emitted as comments, because UIKit has no web-like data-* attributes

The Swift token enum name is configurable in Codegen settings. Raw mode resolves tokens to literals for debugging or quick prototypes.


DivKit output notes

DivKit output is a copy-ready JSON document for mobile handoff. The default profile is Generic; it is project-neutral and does not emit fake assets, actions, payloads, or arbitrary custom_type values.

Document contract

  • All returns { card } or { templates, card }.
  • card.log_id is always present.
  • card.states is always non-empty.
  • A selected COMPONENT_SET produces one state per variant; a selected component, variant, or plain node produces one state.
  • Template returns template diagnostics and extracted templates when safe extraction was possible.
  • Variables returns the same card.variables fragment that is used by the generated card.
  • References contains warnings for placeholders, unsupported Figma/SXL semantics, invalid profile JSON, and host-specific requirements.

Variables and modes

DivKit output does not contain CSS variable syntax such as var(--token). Figma/SXL token references are converted to DivKit variables:

  • simple single-mode values use @{token_name};
  • multi-mode collections generate a mode variable plus a dictionary variable;
  • dictionary reads use typed helpers such as @{getOptIntegerFromDict(12, sxl_tokens_typography, sxl_mode_typography, 'fs_label_sm')};
  • string literals inside expressions use single quotes, so the output stays compatible with the DivKit expression DSL;
  • integer DivKit fields such as font_size, line_height, font_weight_value, max_lines, and border.corner_radius use integer variables/getters.

Structure mapping

  • FRAME and COMPONENT map to container.
  • TEXT maps to text.
  • RECTANGLE and ELLIPSE map to visual containers with background, border, radius, size, and opacity where supported.
  • LINE maps to separator.
  • Inline SLOT children are compiled as ordinary containers.
  • Reference-mode SLOT, INSTANCE, and ICON stay safe placeholders in Generic unless a project mapping tells SXL how to generate a real DivKit node.

Profiles and validation

Validation mode controls which runtime assumptions are allowed:

  • Strict Playground is the Generic default. It keeps output compatible with the public DivKit playground and blocks host-only schemes/custom blocks.
  • Host App is intended for project profiles. It allows only the schemes and custom blocks permitted by the active profile.

Profiles are stored in the Figma file, not only in local browser storage:

  • Generic is the default for every file and every user.
  • NewMain BDUI is explicit opt-in. It uses host-provided app_theme for light/dark color modes and only allows contract-approved asset/action schemes and custom blocks.
  • Custom is for teams that own their own DivKit host app contract.

Project mappings

The DivKit profile JSON can define project mappings:

JSON
{
  "icons": {
    "circle-info": { "image_url": "https://cdn.example.com/icons/circle-info.svg" }
  },
  "slots": {
    "slot.class:progress": { "type": "custom", "custom_type": "new_main_story_progress" }
  },
  "actions": {
    "cta": "div-action://open/details"
  },
  "fonts": {
    "SF Pro Display": "display"
  },
  "customTypes": ["new_main_story_progress"]
}

Mappings are explicit by design:

  • icon mappings turn ICON / icon-like INSTANCE nodes into image nodes with image_url, optional tint_color, size, and accessibility metadata;
  • slot mappings can produce a container, custom block, gallery, data node, or named template reference;
  • action mappings can emit tap, longtap, visibility, or selected actions from explicit metadata/profile aliases;
  • font mappings can convert Figma font family names into host font aliases.

When a mapping is missing or blocked by the active validation mode, SXL keeps valid placeholder output and writes the reason to References.

Host app requirements

Mobile apps that consume non-generic output must provide the matching runtime contract:

  • custom fonts registered in the DivKit host;
  • asset resolvers for custom image URL schemes;
  • action handlers for project action schemes;
  • custom div implementations for allowed custom_type values;
  • a mode variable such as app_theme when a profile uses host-provided theme switching.

Debugging unexpected output

Use these tools in order:

  1. Switch Styled/Decomposed/Raw to isolate token-vs-literal behavior.
  2. Check Variables section for the exact bindings collected from the subtree.
  3. In native Figma Code panel, open Debug tab (if present) to inspect last generation trace.
  4. Confirm you selected the intended node scope (component vs nested layer vs component set).