figr-html-to-figma-nodes
v1.0.9
Published
Convert HTML elements to Figma-compatible node structures with support for styles, gradients, SVGs, and more
Maintainers
Readme
@figr-design/html-to-figma
A powerful library to convert HTML elements to Figma-compatible node structures. Preserves styles, layouts, gradients, SVGs, images, and more for seamless HTML-to-Figma workflows.
Installation
This package is hosted on GitHub Packages. First, create a .npmrc file in your project root:
@figr-design:registry=https://npm.pkg.github.comThen install the package:
npm install @figr-design/html-to-figmaUsage
ES Module / TypeScript
import { htmlToFigma } from '@figr-design/html-to-figma';
// Convert an HTML element to Figma node structure
const element = document.getElementById('my-element');
const figmaNode = htmlToFigma(element);
// Send to Figma plugin
figma.createNodeFromSvg(figmaNode); // or use your own rendering logicCommonJS
const { htmlToFigma } = require('@figr-design/html-to-figma');
const element = document.getElementById('my-element');
const figmaNode = htmlToFigma(element);Browser (Standalone Script)
For use as a standalone script (e.g., injected via <script> tag), use the IIFE bundle:
<script src="path/to/browser.global.js"></script>The browser bundle automatically listens for postMessage events:
// From parent window, request Figma data
iframe.contentWindow.postMessage({
type: 'REQUEST_FIGMA_FRAME',
selector: '#my-element' // optional, defaults to '#render-target'
}, '*');
// Listen for response
window.addEventListener('message', (event) => {
if (event.data.type === 'FIGMA_FRAME_DATA') {
const figmaNode = event.data.data;
// Use the Figma node data
}
if (event.data.type === 'FIGMA_FRAME_ERROR') {
console.error('Error:', event.data.error);
}
});API Reference
htmlToFigma(element: HTMLElement): FigmaNode
Converts an HTML element and all its children to a Figma-compatible node structure.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| element | HTMLElement | The root HTML element to convert |
Returns: FigmaNode - A tree structure representing Figma nodes
Type Definitions
FigmaNode
The main node structure returned by htmlToFigma:
interface FigmaNode {
name: string; // Node name (tag name or text content)
type: string; // "FRAME", "TEXT", "RECTANGLE", "VECTOR", etc.
x?: number; // X position relative to parent
y?: number; // Y position relative to parent
width?: number; // Node width
height?: number; // Node height
// Visual properties
fills?: Paint[]; // Background fills (solid, gradient, image)
strokes?: Paint[]; // Border strokes
strokeWeight?: number; // Border width
strokeAlign?: string; // "INSIDE", "OUTSIDE", "CENTER"
cornerRadius?: number; // Border radius (uniform)
topLeftRadius?: number; // Individual corner radii
topRightRadius?: number;
bottomLeftRadius?: number;
bottomRightRadius?: number;
opacity?: number; // Node opacity (0-1)
clipsContent?: boolean; // Whether to clip overflow
// Layout properties
layoutMode?: string; // "HORIZONTAL", "VERTICAL", "NONE"
primaryAxisAlignItems?: string; // Main axis alignment
counterAxisAlignItems?: string; // Cross axis alignment
itemSpacing?: number; // Gap between children
paddingLeft?: number; // Padding values
paddingRight?: number;
paddingTop?: number;
paddingBottom?: number;
// Text properties (for TEXT nodes)
characters?: string; // Text content
fontSize?: number; // Font size in pixels
fontName?: { family: string; style: string };
fontWeight?: number; // Font weight (400, 700, etc.)
textAlignHorizontal?: string; // "LEFT", "CENTER", "RIGHT", "JUSTIFIED"
textAlignVertical?: string; // "TOP", "CENTER", "BOTTOM"
lineHeight?: LineHeight; // Line height configuration
letterSpacing?: number; // Letter spacing in pixels
textDecoration?: string; // "NONE", "UNDERLINE", "STRIKETHROUGH"
textAutoResize?: string; // "NONE", "HEIGHT", "WIDTH_AND_HEIGHT"
// Effects
effects?: Effect[]; // Shadows, blurs, etc.
// SVG data (for VECTOR nodes)
svgData?: string; // Raw SVG string
// Children
children?: FigmaNode[]; // Child nodes
}Paint
Fill and stroke definitions:
interface Paint {
type: string; // "SOLID", "GRADIENT_LINEAR", "GRADIENT_RADIAL", "IMAGE"
color?: RGBColor; // Solid color (r, g, b values 0-1)
opacity?: number; // Paint opacity (0-1)
visible?: boolean; // Whether paint is visible
// Gradient properties
gradientStops?: GradientStop[]; // Color stops for gradients
gradientTransform?: number[][]; // 2x3 transformation matrix
// Image properties
scaleMode?: string; // "FILL", "FIT", "CROP", "TILE"
imageRef?: string; // Image reference or data URL
}
interface RGBColor {
r: number; // Red (0-1)
g: number; // Green (0-1)
b: number; // Blue (0-1)
}
interface GradientStop {
position: number; // Position along gradient (0-1)
color: RGBColor & { a?: number }; // Color with optional alpha
}Effect
Shadow and blur effects:
interface Effect {
type: string; // "DROP_SHADOW", "INNER_SHADOW", "LAYER_BLUR", "BACKGROUND_BLUR"
visible: boolean; // Whether effect is visible
radius: number; // Blur radius
color?: RGBColor & { a: number }; // Shadow color with alpha
offset?: { x: number; y: number }; // Shadow offset
spread?: number; // Shadow spread
}LineHeight
Text line height configuration:
interface LineHeight {
value: number;
unit: "PIXELS" | "PERCENT" | "AUTO";
}Features
Layout Support
- Flexbox: Converts
display: flexto Figma Auto Layoutflex-direction→layoutModejustify-content→primaryAxisAlignItemsalign-items→counterAxisAlignItemsgap→itemSpacing
- Grid: Basic CSS Grid support
- Positioning: Handles absolute/relative positioning
Visual Styling
- Colors: Hex (#RGB, #RRGGBB, #RRGGBBAA), RGB, RGBA, HSL, HSLA
- Gradients: Linear and radial gradients with multiple stops
- Borders: Width, color, style, and individual corner radii
- Shadows: Box shadows converted to Figma drop shadows
- Opacity: Element and color opacity
Text
- Font family, size, weight, and style
- Text alignment (horizontal and vertical)
- Line height (px, %, unitless)
- Letter spacing
- Text decoration (underline, strikethrough)
- Inline styled elements (
<em>,<strong>,<b>,<i>)
Images & SVG
<img>elements with data URLs- Background images
- Inline SVG conversion to Figma vectors
- SVG icons preservation
Advanced
- Z-Index: Preserves stacking order in Figma layers
- Overflow:
overflow: hidden→clipsContent: true - CSS Units: px, em, rem, vh, vw, %
Example: Figma Plugin Integration
import { htmlToFigma, FigmaNode } from '@figr-design/html-to-figma';
// In your web app
const element = document.querySelector('.my-component');
const figmaData = htmlToFigma(element);
// Send to Figma plugin
parent.postMessage({
pluginMessage: {
type: 'create-frame',
data: figmaData
}
}, '*');
// In your Figma plugin (plugin code)
figma.ui.onmessage = async (msg) => {
if (msg.type === 'create-frame') {
const node = await createFigmaNode(msg.data);
figma.currentPage.appendChild(node);
figma.viewport.scrollAndZoomIntoView([node]);
}
};
function createFigmaNode(data: FigmaNode): FrameNode | TextNode | ... {
// Recursively create Figma nodes from the data structure
// Implementation depends on your specific needs
}Browser Bundle Events
When using dist/browser.global.js, the following message types are supported:
| Event Type | Direction | Description |
|------------|-----------|-------------|
| FIGMA_SCRIPT_READY | Script → Parent | Fired when script is loaded and ready |
| REQUEST_FIGMA_FRAME | Parent → Script | Request conversion of an element |
| FIGMA_FRAME_DATA | Script → Parent | Successful conversion result |
| FIGMA_FRAME_ERROR | Script → Parent | Conversion error |
Contributing
- Clone the repository
- Install dependencies:
npm install - Build:
npm run build - Run in watch mode:
npm run dev
License
MIT
