Figma Make Local Runner
Skill by ara.so — Design Skills collection.
Overview
Figma Make Local Runner is a TypeScript/React development environment that runs code exported from Figma Make locally. It solves common issues with Figma Make exports including:
- Automatic version specifier removal from imports (e.g.,
@radix-ui/react-slot@1.1.2→@radix-ui/react-slot) - Custom asset resolution for
figma:asset/imports - Pre-installed dependencies commonly used by Figma Make
- Single HTML build capability for standalone distribution
Installation
# Clone the repository
git clone https://github.com/likang/figma-make-local-runner
cd figma-make-local-runner
# Install dependencies
npm install
Project Setup
1. Import Figma Make Code
After exporting code from Figma Make:
# Extract downloaded zip and copy src folder
cp -r /path/to/figma-make-export/src ./src
The src folder structure should contain:
App.tsxor main component filesassets/- images, fonts, SVGs- Component files generated by Figma Make
2. Start Development Server
npm run dev
Access at http://localhost:5173
3. Build for Production
Standard Build:
npm run build
Single HTML File (standalone):
npm run build:single
This creates a single HTML file in dist/ with all assets inlined - perfect for sharing or embedding.
Key Commands
# Development server with hot reload
npm run dev
# Type checking
npm run type-check
# Production build (standard)
npm run build
# Production build (single HTML file)
npm run build:single
# Preview production build
npm run preview
Common Patterns
Handling Missing Dependencies
If you encounter import errors, install the missing package:
// Error: Cannot find module 'some-package'
import { Component } from 'some-package@1.2.3';
// Solution:
// npm install some-package
The build system automatically strips version specifiers, so install the latest compatible version.
Working with Figma Assets
Figma Make exports may reference assets like:
import logo from "figma:asset/logo.svg";
import heroImage from "figma:asset/images/hero.png";
function Header() {
return (
<div>
<img src={logo} alt="Logo" />
<img src={heroImage} alt="Hero" />
</div>
);
}
The custom Vite plugin resolves these to src/assets/:
src/
assets/
logo.svg
images/
hero.png
Modifying Generated Components
Typical Figma Make component:
import React from "react";
import { Button } from "./components/ui/button";
export function App() {
return (
<div className="w-full h-screen">
<Button>Click me</Button>
</div>
);
}
Add custom logic:
import React, { useState } from "react";
import { Button } from "./components/ui/button";
export function App() {
const [count, setCount] = useState(0);
return (
<div className="w-full h-screen">
<Button => setCount(count + 1)}>
Clicked {count} times
</Button>
</div>
);
}
Styling with Tailwind
Figma Make typically exports with Tailwind CSS classes:
function Card({ title, description }: { title: string; description: string }) {
return (
<div className="rounded-lg border bg-card text-card-foreground shadow-sm">
<div className="flex flex-col space-y-1.5 p-6">
<h3 className="text-2xl font-semibold">{title}</h3>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
</div>
);
}
Extend with custom Tailwind classes or CSS modules as needed.
Configuration
Vite Configuration
The project includes custom plugins in vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
react(),
// Custom plugin removes version specifiers
removeVersionSpecifiersPlugin(),
// Custom plugin resolves figma:asset/ imports
figmaAssetPlugin()
],
resolve: {
alias: {
'@': '/src'
}
}
});
TypeScript Configuration
Standard React TypeScript setup in tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"]
}
Troubleshooting
Import Version Conflicts
Problem: Imports with version specifiers fail
import { Slot } from "@radix-ui/react-slot@1.1.2";
// Error: Cannot find module
Solution: The plugin handles this automatically, but ensure the package is installed:
npm install @radix-ui/react-slot
Missing Asset Files
Problem: figma:asset/ imports fail at runtime
import icon from "figma:asset/icon.svg";
// Error: Module not found
Solution: Verify file exists in src/assets/:
ls src/assets/icon.svg
Build Errors with External Dependencies
Problem: Dependency not pre-installed
Solution: Install explicitly:
npm install <package-name>
Common Figma Make dependencies:
npm install @radix-ui/react-slot
npm install class-variance-authority
npm install clsx
npm install tailwind-merge
npm install lucide-react
Single HTML Build Asset Issues
Problem: Assets not loading in single HTML file
Solution: Ensure build:single command is used and assets are in src/assets/:
npm run build:single
Hot Reload Not Working
Problem: Changes don't reflect in browser
Solution: Restart dev server with cleared cache:
# Stop server (Ctrl+C)
rm -rf node_modules/.vite
npm run dev
Real-World Example
Complete workflow for a Figma Make dashboard:
// src/App.tsx (generated by Figma Make, then modified)
import React, { useState } from "react";
import { Button } from "./components/ui/button";
import { Card } from "./components/ui/card";
import logo from "figma:asset/logo.svg";
interface DashboardData {
users: number;
revenue: number;
}
export function App() {
const [data, setData] = useState<DashboardData>({
users: 1234,
revenue: 56789
});
const refreshData = async () => {
// Add your API call here
const response = await fetch(process.env.VITE_API_URL + '/dashboard');
const newData = await response.json();
setData(newData);
};
return (
<div className="min-h-screen bg-background p-8">
<header className="mb-8 flex items-center justify-between">
<img src={logo} alt="Logo" className="h-12" />
<Button
</header>
<div className="grid grid-cols-2 gap-4">
<Card title="Total Users" description={data.users.toString()} />
<Card title="Revenue" description={`$${data.revenue}`} />
</div>
</div>
);
}
Environment variables (.env):
VITE_API_URL=https://api.example.com
Build and share:
npm run build:single
# Share dist/index.html as standalone file