Skip to content

About

render React components to Sketch/Figma βš›οΈπŸ’Ž

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Β 
Β 

Latest commit

Β 

History

799 Commits

Folders and files

Repository files navigation

react-sketchapp
render React components to Sketch; tailor-made for design systems

Quick-start πŸƒβ€

First, make sure you have installed Sketch version 50+, & a recent npm.

Open a new Sketch file, then in a terminal:

git clone https://github.com/airbnb/react-sketchapp.git
cd react-sketchapp/examples/basic-setup && npm install

npm run render

Next, check out some more examples!

readme-intro

npm Sketch.app Travis

Why?!

Managing the assets of design systems in Sketch is complex, error-prone and time consuming. Sketch is scriptable, but the API often changes. React provides the perfect wrapper to build reusable documents in a way already familiar to JavaScript developers.

What does the code look like?

import * as React from 'react';
import { render, Text, Artboard } from 'react-sketchapp';

const App = props => (
  <Artboard>
    <Text style={{ fontFamily: 'Comic Sans MS', color: 'hotPink' }}>{props.message}</Text>
  </Artboard>
);

export default context => {
  render(<App message="Hello world!" />, context.document.currentPage());
};

What can I do with it?

  • Manage design systemsβ€” react-sketchapp was built for Airbnb’s design system; this is the easiest way to manage Sketch assets in a large design system
  • Use real components for designsβ€” Implement your designs in code as React components and render them into Sketch
  • Design with real dataβ€” Designing with data is important but challenging; react-sketchapp makes it simple to fetch and incorporate real data into your Sketch files
  • Build new tools on top of Sketchβ€” the easiest way to use Sketch as a canvas for custom design tooling

Found a novel use? We'd love to hear about it!

Read more about why we built it

Backends

react-sketchapp renders your React tree into a design-app-neutral intermediate tree (pages, frames, shapes, text with style runs, fills, strokes, effects, auto-layout, etc.) and then hands that tree to a backend that converts it to a native output format. Backend selection is explicit, and new backends can be registered without touching the core reconciler/layout code.

Two backends ship today:

  • sketch β€” the original, unchanged renderer. Produces Sketch file-format JSON headlessly (no behavior change from previous versions).
  • figma β€” new. Produces Figma's REST-API-like file-format JSON headlessly (no Figma API/ network calls, no live/hot renderer). A separate Figma plugin imports this JSON and creates the corresponding pages, frames, text, styles, etc.

Using the Sketch backend (unchanged)

import { render, renderToJSON, Text, Artboard } from 'react-sketchapp';

export default context => {
  render(<App message="Hello world!" />, context.document.currentPage());
};

Using the Figma backend

import * as React from 'react';
import { renderToJSON, Text, Artboard } from 'react-sketchapp/figma';

const App = () => (
  <Artboard name="Page 1">
    <Text style={{ fontFamily: 'Open Sans', fontSize: 40 }}>Hello Figma!</Text>
  </Artboard>
);

const figmaFileJSON = renderToJSON(<App />);
// write `figmaFileJSON` to disk / hand it to the Figma plugin to import

Or, from the main package, using renderToFigmaJSON directly:

import { renderToFigmaJSON } from 'react-sketchapp';

const figmaFileJSON = renderToFigmaJSON()(<App />);

You can also pick a backend explicitly through a single, generic entry point:

import { renderToDesignJSON } from 'react-sketchapp';

const json = renderToDesignJSON(<App />, { backend: 'figma' }); // or 'sketch'

renderToDesignJSON/renderToFigmaJSON use a pure Node.js PlatformBridge by default (no native addon required), so the Figma backend β€” and headless Sketch JSON generation β€” both run in plain Node.js environments (CI, servers, etc.) without Sketch or its native node-sketch-bridge dependency installed. You may still pass a custom PlatformBridge (e.g. the native macOS one used by the sketch backend when run inside Sketch) via the platformBridge option.

Figma JSON output format

The Figma backend outputs the same shape returned by Figma's GET /v1/files/:key REST endpoint: a document (DOCUMENT β†’ CANVAS pages β†’ nodes such as FRAME/RECTANGLE/TEXT/VECTOR), plus top-level components, componentSets, styles, schemaVersion, name, version, etc. Frames carry Figma auto-layout fields (layoutMode, paddingLeft/Right/Top/Bottom, itemSpacing, primaryAxisAlignItems, counterAxisAlignItems, cornerRadius, …) derived from your flexbox styles, and text nodes carry rich-text styling via characterStyleOverrides + styleOverrideTable when you nest <Text> spans with different styles. <Svg> trees are serialized to a flat SVG string carried on a VECTOR node's svg field (a custom extension, since Figma's own file format has no raw-SVG field) for the companion plugin to turn into real vector geometry β€” see Backends: SVG handling for details.

Generated node ids (e.g. "1:2") are a JSON-document-local addressing scheme only β€” Figma's plugin API does not allow assigning custom ids when creating real nodes. These generated ids are useful as stable references inside the JSON document itself (e.g. for a future diff/update interface built into the companion Figma plugin), but they are not literal Figma node ids.

Adding a new backend (e.g. Penpot)

Backends implement the RenderBackend interface (src/backends/types.ts):

type RenderBackend<Json, Options> = {
  name: string;
  defaultPlatformBridge: PlatformBridge;
  renderToJSON: (element: React.ReactElement, options?: Options, platformBridge?: PlatformBridge) => Json;
};

and register themselves with the backend registry (src/backends/registry.ts):

import { registerBackend } from 'react-sketchapp';

registerBackend({
  name: 'penpot',
  defaultPlatformBridge: myHeadlessBridge,
  renderToJSON(element, options, platformBridge = myHeadlessBridge) {
    // build the shared intermediate tree (same `buildTree`/Yoga layout core
    // used by the Sketch and Figma backends) and emit Penpot's native format
  },
});

Once registered, it becomes selectable via renderToDesignJSON(<App />, { backend: 'penpot' }). A Penpot backend is not implemented yet β€” this is only the extension point for one.

Documentation

About

render React components to Sketch/Figma βš›οΈπŸ’Ž

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages