Allow this plugin to be used from outside of the Figma context

#259 · open · 7 comments

View on GitHub ↗

heinvv

## Problem `packages/backend` — the actual conversion logic (auto-layout → CSS/gradients/etc. across HTML, Tailwind, Flutter, SwiftUI, Compose) — currently only runs inside a live Figma plugin sandbox. Several core builders read the `figma` global directly (`figma.mixed`, `figma.getNodeByIdAsync()`/`exportAsync()`, `figma.variables.getVariableByIdAsync()`), not just the plugin-messaging bridge. That means the conversion engine can't be reused outside the plugin — e.g. server-side, converting a node tree already fetched via the Figma REST API, with no live document connection available. ## Use case Running this conversion logic headlessly on a server, on top of REST API data, instead of re-implementing equivalent auto-layout/CSS/gradient resolution by hand. ## Proposed fix #258 adds a small injectable seam (`setBackendHost()` / `getBackendHost()` in `packages/backend/src/host.ts`) so a caller can supply a REST-backed (or otherwise non-plugin) implementation of the handful of `figma.*` calls the conversion path needs. Left unset, it falls back to wrapping the real `figma` global, so the plugin app's behavior is unchanged.

Comments

bernaferrari

I surely could do all that. I'm just wondering what you are trying to do.

heinvv

@bernaferrari I would like to convert Figma to html using the Figma URLs. From the browser.

bernaferrari

Using rest api?

heinvv

@bernaferrari Yes, using the Figma rest api.

bernaferrari

The plugin codebase is messy because Figma team told me the old version was too inneficient and I should use REST api, but there is a bad flaw in REST api for a few months that crashed the plugin, so I kept both and it made the codebase be a mess. If I merge what you did, will it help you? I probably should remove the old plugin soon, that will make things a bit easier.

heinvv

I wasn't aware of this. Let me study this.

heinvv

Note: this comment was written by Claude Code automatically. > Yes — merging #258 directly unblocks our use case. Once `setBackendHost()` exists, we can point `packages/backend` at a REST-backed host instead of a live plugin document, which is exactly what we needed. > > On removing the old plugin codepath: that sounds like it'd make this cleaner for both of us, not just simpler for you. The reason `packages/backend`'s core builders (`html`, `tailwind`, `flutter`, `swiftui`, `compose`) needed a host seam at all is that they call `figma.mixed` / `figma.getNodeByIdAsync().exportAsync()` directly — assuming a live document. If the codebase converges on REST API internally (i.e. even the plugin itself builds its node tree from REST JSON rather than live plugin API traversal, going by what `altNodes/jsonNodeConversion.ts` already does), then that live-document assumption in the builders was probably a holdover from the old codepath rather than something intentional — and #258's seam is the boundary that lets you remove it without having to touch every builder again. > > Two things worth flagging, not blockers to merging now: > - `mixed` still needs to mean something either way — it's about a single node's own heterogeneous styling (e.g. a text node with multiple run styles), not about a multi-node selection, so it should carry over cleanly to a REST-only model. > - `common/retrieveUI/retrieveColors.ts`'s `getSelectionColors()` is different — that's the *current UI selection*, which has no REST equivalent and is genuinely plugin-only. Its only caller (`code.ts`) is already plugin-only too, so it wouldn't be affected by dropping the old traversal codepath. > > Happy to help however's useful — including taking a pass at removing the old codepath in a follow-up PR once #258 is in, if that'd save you time.