Skip to content

Export code

Export a landing page frame, switch React, Svelte and HTML, download the project and open it in a browser: the breakpoints reflow at phone width.

Export code turns a whole frame, with every nested frame, text, image, vector and component instance inside it, into a project a developer can keep. Keyframed animation comes along: Motion for React, CSS @keyframes for HTML and Svelte.

  1. Select a frame, or any layer inside it. Code mode always exports the frame that contains the selection.
  2. Switch to Code in the mode switch at the left end of the bottom bar (Shift+D), or open the … menu and choose Export code…: both open Code mode.
  3. With a layer picked, its CSS sits at the top of the right bar and the frame’s code below it. Pick a target in the framework dropdown: React + Tailwind (default), HTML + CSS or SvelteKit.
  4. The header has Copy and Download .zip icon buttons; a floating copy button also sits on the code. Two dropdowns above the code pick the framework and the file; it opens on the main file. Code is syntax-highlighted in light and dark.
  5. With a layer picked, its section lists size, layout, typography, fill and variables as rows: click a value to copy it. The CSS toggle shows the CSS and Tailwind snippets. The page title and the zip are named after the frame (Landing page gives landing-page-react.zip).
In the designIn the code
Auto layout (horizontal, vertical)display: flex with gap, padding, alignment and wrap
Auto layout griddisplay: grid with its columns (grid-cols-12) and column/row spans
Fill, hug, fixed sizingflex: 1, align-self: stretch, no size, or a width (fluid with max-width from 320 px)
A frame without a stack whose layers sit one below the othera column (flex-direction: column), each layer offset by margins; wide layers stretch up to their design width
A frame without a stack whose layers overlapposition: relative, its layers position: absolute, pinned by their constraints; layers 320 px or wider pinned left get percentage widths
Breakpointsthe same markup, with max-[390px]: classes (Tailwind) or @media (max-width: …) rules for what each breakpoint overrides
Components and instancesone file per component; text, images, colours and visibility that differ between instances become typed props; an override on an instance nested inside another component becomes a prop of the outer one (feature1LabelColor) forwarded to the inner one
Texth1 for the largest heading on the page, then h2/h3 by size and weight, p for body copy, a for linked text
Layers named Nav, Header, Footer, Hero, Features, Pricing, Card…nav, header, footer, section, article
Component sets with variantsone component named after the set with a prop per variant (variant?: 'outline', disabled?: boolean), picking one file per variant (ButtonOutline); instances write <Button variant="outline" /> and leave out Default values (React and Svelte; HTML writes each variant inline)
Components named Button or Linkbutton type="button" and a href
Colours, fonts, radii, spacinga tokens file (@theme for Tailwind, CSS variables otherwise); colour variables keep their names
Imagesimg pointing at a file bundled in the project (public/assets/ for React, static/assets/ for Svelte, assets/ for HTML)
Vectors, polygons, starsinline svg

Class names come from layer names (Feature card becomes FeatureCard and .feature-card), and the same frame always gives the same files.

In the designReact (Motion)HTML and Svelte (CSS)
Keyframes on position, scale, rotation, opacity, text colourmotion.* element with keyframe arrays and times (src/animations.ts)@keyframes per property (styles/animations.css, or inside the Svelte component)
A bezier curveease: [x1, y1, x2, y2]cubic-bezier(x1, y1, x2, y2)
Easing presets and springs (Standard, Ease out, Overshoot, Elastic, Bounce…)the exact curve sampled into a function (src/lib/easing.ts)the exact curve sampled into linear(…)
Hold keyframesholdstep-end
Start timedelayanimation-delay
Loop (interactive settings)repeat: Infinity over the work areainfinite over the work area
Playback “when scrolled into view”whileInViewpaused until an IntersectionObserver adds is-inview
A layer with a “While hovering” interactionwhileHover:hover

Position moves are written as translate (CSS variables --tx/--ty registered with @property, so x and y keep their own timing).

  • Effects with no CSS equivalent (noise, displacement, chromatic aberration…) are left out and listed under Not exported. Drop shadow, inner shadow, layer blur and background blur are kept.
  • Shaders, 3D, particles and video effects are not exported.
  • Animation of anything but position, scale, rotation, opacity and text colour (blur, skew, 3D rotation, fills, masks, effect parameters…) is listed under Not exported, as is animation on a whole component instance: animate the layers inside it.
  • Scroll-scrubbed and paused playback play on load instead.
  • A frame without a stack whose layers overlap stays absolutely positioned: it does not reflow on a phone. Wrap the layers with a stack (Shift+A) before exporting for responsive code.
  • An image that cannot be downloaded at export time keeps its original link, which expires.
Terminal window
feega motion code <nodeId> --target svelte --out ./site

The export_code MCP tool returns the same files as JSON, free and without AI:

{ "node_id": "<frameId>", "target": "react" }
{ "name": "Landing", "target": "react", "files": [{ "path": "src/components/Button.tsx", "content": "…" }], "assets": [{ "path": "public/assets/<assetId>.png", "ref": "/assets/<assetId>.png", "url": "https://…" }], "notes": [] }

feega motion code downloads each assets entry to its path; url is a link that expires, so fetch it right away.

The endpoint behind both is GET /api/v1/motion/{nodeId}/code?target=react|html|svelte.