# VibeFigma turns Figma frames into Tailwind-styled React components

> VibeFigma is a TypeScript CLI and REST service that reads a Figma file through the official Figma API and emits React and TypeScript components with Tailwind classes. It is a good fit for a team that wants generated components in a repo, and a poor fit for anyone who needs editable design intent rather than generated markup.

**vibeflowing-inc/vibe_figma** — Figma to React Converter

- Repository: https://github.com/vibeflowing-inc/vibe_figma
- Website: https://vibeflow.ai/
- Stars: 848 · Forks: 79
- Language: TypeScript
- License: AGPL-3.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/vibeflowing-inc-vibe-figma

## A converter for people who already have the Figma file

VibeFigma takes a Figma file and node URL and produces React components styled with Tailwind CSS. The stated promise in the README is production-ready React components with Tailwind generated automatically, and the feature list is short: direct integration with the Figma API for design extraction, conversion of Figma frames to React and TypeScript components, automatic Tailwind class generation enabled by default, and an optional AI-powered code cleanup pass.

That places the tool in a narrow and specific spot. It is not a design tool and it is not a component library. It is a code generator that reads design data and writes files, for a developer who already has the design finished and wants the first draft of the markup to arrive in the repository rather than in a text editor.

The project is the open-source core powering VibeFlow UI, and a hosted version is offered at ui.vibeflow.ai where you paste a Figma URL and skip the setup entirely. The distinction matters for anyone assessing the project: the repository is the local, self-hosted path, and the cloud service is a separate product built on it. The README positions the commercial route for custom work and enterprise needs, and there is a Discord invite and a contact address for the founders.

## The pipeline runs on the Figma API, Babel and PostCSS

The dependency list in package.json describes how the conversion actually happens, and it is more informative than the feature list.

On the Figma side there is no scraping of the design canvas. The package depends on the official Figma API, and the README names the token as a Personal Access Token generated under Figma Account Settings, where the note warns that the token is shown only once and should be stored in a .env file or passed with the --token flag.

The code generation side is Babel. Four Babel packages appear in the dependencies: @babel/parser, @babel/generator, @babel/traverse and @babel/types. Parsing and printing JavaScript AST nodes is how a generator emits clean .tsx rather than string concatenation, and the presence of a traverse package is consistent with rewriting nodes as they are visited.

Between Figma and React sits a style conversion step. htmltojsx handles markup, postcss and postcss-safe-parser handle stylesheet parsing, css-what parses CSS selectors, and @colordx/core handles colour values. The colour library is the clue to what the converter is doing: it reads the fill and stroke values Figma reports and turns them into something Tailwind can express.

The optional cleanup step is a separate model call. The --clean flag uses an AI code cleaner and needs GOOGLE_GENERATIVE_AI_API_KEY, and the project pulls in the ai and @ai-sdk/google packages for it. Note what this means: the cleanup is optional and unkeyed by default, and a token in the environment is what switches it on.

## Three entry points, and the one flag that overrides all of them

The CLI is the primary interface and it can be driven three ways.

The interactive route is the shortest to type and the easiest to learn, because the CLI asks for the URL, the token and the output paths itself:

```bash
npx vibefigma --interactive
```

The direct route passes everything on the command line, and the --force variant skips the overwrite confirmation when a file already exists:

```bash
npx vibefigma "https://www.figma.com/design/4i8Tp5btFPRqtkYXplnfT6/50-Web-Sign-up-log-in-designs--Community-?node-id=26-2944&t=d8ZfhZOwcLuUz0Jz-4" --token YOUR_TOKEN

# Add --force to overwrite existing files without confirmation
npx vibefigma "https://www.figma.com/design/4i8Tp5btFPRqtkYXplnfT6/50-Web-Sign-up-log-in-designs--Community-?node-id=26-2944&t=d8ZfhZOwcLuUz0Jz-4" --token YOUR_TOKEN --force
```

The third route sets the token once in the environment, which is the sensible option for a shell where you convert several files:

```bash
export FIGMA_TOKEN=your_figma_access_token
npx vibefigma "https://www.figma.com/design/4i8Tp5btFPRqtkYXplnfT6/50-Web-Sign-up-log-in-designs--Community-?node-id=26-2944&t=d8ZfhZOwcLuUz0Jz-4"
```

The help output spells out the precedence: -t, --token <token> is the Figma access token that overrides the FIGMA_TOKEN env var. There is also a third installation route for Claude Code users, where the skill is added with npx skills add vibeflowing-inc/vibe_figma --skill vibefigma, and a skills/ directory at the top of the repository backs it.

## Defaults, output paths and the flags that switch features off

The command options are worth reading as a set of opinions about generated code.

Output goes to ./src/components/[ComponentName].tsx by default, with assets in ./public, and both can be redirected. -c, --component <path> takes a directory or a specific file, and -a, --assets <dir> takes an asset directory:

```bash
# Save to specific directory
npx vibefigma [url] -c ./src/components -a ./public/assets

# Save to specific file
npx vibefigma [url] -c ./src/components/Hero.tsx
```

Tailwind is on by default, and --no-tailwind switches to regular CSS instead. The remaining flags are all subtractive, which tells you what the generator does when left alone: --no-classes stops CSS class generation, --no-absolute stops absolute positioning, --no-responsive disables responsive design, --no-fonts leaves fonts out. --optimize and --clean are the two additive flags, and only --clean reaches an external model.

The full option list is reproduced in the README as a usage block, and it is the fastest way to see the whole surface of the tool:

```
Usage: vibefigma [options] [url]

Convert Figma designs to React components

Arguments:
  url                           Figma file/node URL

Options:
  -V, --version                 Output the version number
  -t, --token <token>           Figma access token (overrides FIGMA_TOKEN env var)
  -u, --url <url>               Figma file/node URL
  -c, --component <path>        Component output path (default: ./src/components/[ComponentName].tsx)
  -a, --assets <dir>            Assets directory (default: ./public)
  --no-tailwind                 Disable Tailwind CSS (enabled by default)
```

```
  --optimize                    Optimize components
  --clean                       Use AI code cleaner (requires GOOGLE_GENERATIVE_AI_API_KEY)
  --no-classes                  Don't generate CSS classes
  --no-absolute                 Don't use absolute positioning
  --no-responsive               Disable responsive design
  --no-fonts                    Don't include fonts
  --interactive                 Force interactive mode
  -f, --force                   Overwrite existing files without confirmation
  -h, --help                    Display help for command
```

The two flag groups, one additive and the other subtractive, describe a generator whose defaults are aimed at producing markup that already looks like a Tailwind project rather than raw translated layout.

## A REST service with rate limits and a body size cap

The repository is not only a CLI. It also contains a REST API server built on hono, with hono-rate-limiter for throttling, and the README points to docs/API.md for the full API documentation. The conversion endpoint is a POST to /v1/api/vibe-figma.

Running it locally takes two commands, and the server listens on port 3000 by default:

```bash
# Install dependencies
bun install

# Run development server
bun run dev

# Server runs on http://localhost:3000
```

The .env.example file in the repository root is where the tunables live, and it is more informative than the README section on configuration:

```env
PORT=3000
HOST=0.0.0.0
CORS_ORIGIN=*
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=10
MAX_REQUEST_SIZE=10mb
REQUEST_TIMEOUT_MS=300000
LOG_LEVEL=info
ENABLE_METRICS=false
GOOGLE_GENERATIVE_AI_API_KEY=""
FIGMA_TOKEN=""
```

Three of these matter for anyone exposing the service. CORS_ORIGIN=* allows requests from any origin, which is convenient in development and wrong for a shared deployment without a change. The rate limiter allows ten requests per sixty second window. The request body is capped at 10mb and the timeout is 300000 milliseconds, five minutes, which is generous because a Figma file with many assets is a large request. Metrics are off by default, so a self-hosted instance gives you no request telemetry unless you switch it on.

Note that the example also carries both GOOGLE_GENERATIVE_AI_API_KEY and FIGMA_TOKEN, so the service can run the AI cleanup and fetch designs on its own without a browser session.

## AGPL-3.0 for the code, MIT for the borrowed converter

The project is licensed under the GNU Affero General Public License v3.0, and the README points to the LICENSE file for the full text. The repository has an AGPL-3.0 entry in package.json as well, and a NOTICE file for details about third-party code.

AGPL-3.0 is the part of the licence decision that deserves attention rather than a passing mention. It is a copyleft licence with a network clause, and it is a different regime from the MIT and Apache licences that most component generators carry. Whether the obligations are comfortable for your distribution model is a question for whoever handles licensing in your organisation, and this is not legal advice. What can be said factually is that the licence is stronger than the permissive default, and that the generated output is a separate question from the licence of the generator, which the README does not address.

The NOTICE file exists because one dependency is derived work. The README acknowledges code derived from css-to-tailwindcss by Salakhutdinov Salavat, licensed under the MIT License. That is the practical reason the MIT attribution appears inside an AGPL project, and it is the kind of detail that is worth reading in the NOTICE file before you redistribute anything.

The project is also not versioned through GitHub releases, since the repository has none. The version lives in package.json, which reads 1.0.3, and the last push to the repository was on 2026-10-09. A one-point-oh version on a project that has been pushed to within the last two weeks tells you the project is moving, and it tells you that there is no release history to consult when a new version lands and changes output.

## The container exposes a different port than the configuration

The Dockerfile in the repository root is short, and it contradicts the default configuration in one specific way:

```dockerfile
FROM oven/bun:1

WORKDIR /usr/src/app

COPY package.json .
RUN bun install

COPY . .

EXPOSE 8000/tcp

ENTRYPOINT [ "bun", "run", "src/index.ts" ]
```

The image declares EXPOSE 8000/tcp, while .env.example sets PORT=3000 and the README states that the server runs on http://localhost:3000. Nothing in the Dockerfile copies a .env file, so the container starts with whatever the application defaults to, and the exposed port is the one thing a client cannot discover by reading the code. Anyone writing a compose file or a Kubernetes manifest against this image has to reconcile those two numbers first, and a mismatch here produces a container that starts cleanly and refuses connections.

The entrypoint runs the server directly from source rather than from a built bundle, and the build script in package.json is separate, with build:cli producing an ESM bundle under dist/cli through bun build. The published npm package ships bin/, dist/cli/, README.md, LICENSE and NOTICE, with the vibefigma binary pointing at ./bin/vibefigma.js, and it declares Node 18 or newer as the engine even though the development flow is built around bun.

That split is the second limitation worth knowing: the CLI and the server have different runtimes and different release shapes, and the container path is the one that is least documented.

## Where a Figma to React converter is the wrong answer

The clearest case for choosing something else is a codebase with an existing design system. A generator that reads a Figma frame will reproduce the geometry it sees, and it has no way to know that a button in your project must be a variant of an existing component rather than a fresh div. The output is a starting point that a person edits, and on a mature project the editing can cost more than writing the component by hand.

The second case is a design that is not a grid of frames. Auto-layout, constraints, variables and component instances in Figma all have behaviour that a frame-to-markup mapping can only approximate. The generator's own option list shows the shape of the compromise: absolute positioning and responsive behaviour are on by default and can be switched off, which is what a tool does when it cannot always choose correctly.

The third case is legal or policy sensitive. A Figma to React generator needs a Figma Personal Access Token and, in the hosted version, sends a design URL to someone else's service. Teams in regulated environments will want to check what leaves the network before they paste a link into a third party page.

Compared with the alternative of writing the component yourself, the difference in approach is narrow but real. A converter reads the finished design and translates it once, giving you a fast first draft with no design system knowledge. Building the component by hand gives you semantic markup and accessible behaviour, but costs the time of interpreting the design in the first place. The converter is quicker to start and slower to finish, and the break-even point depends entirely on how much of the generated file survives review.

## Conclusion

VibeFigma suits developers who want a Figma node turned into a committed .tsx file in one command, and teams willing to review generated code rather than trust it. It does not suit designers, and it does not replace a component library built by hand. Before adopting it, check the AGPL-3.0 terms against how you plan to ship the output, and confirm which port the service binds to, since the Dockerfile exposes 8000/tcp while the .env.example sets PORT=3000.

## FAQ

### How do I install and run VibeFigma?

The package is published to npm, so npx vibefigma --interactive starts the CLI without a global install and prompts for the Figma URL, the access token and the output paths. Node 18 or newer is the declared engine, and the local development flow uses bun.

### Where does VibeFigma get its Figma access token from?

You generate a Personal Access Token in Figma Account Settings under Personal Access Tokens, then pass it with the --token flag or store it in the FIGMA_TOKEN environment variable. The --token option takes precedence over the environment variable.

### Can VibeFigma generate plain CSS instead of Tailwind?

Yes. Tailwind class generation is on by default, and the --no-tailwind flag produces regular CSS instead. Other subtractive flags include --no-classes, --no-absolute, --no-responsive and --no-fonts.

### Does the VibeFigma API server need a Google AI key?

Only for the --clean cleanup step, which uses an AI code cleaner and requires GOOGLE_GENERATIVE_AI_API_KEY. The .env.example lists that key alongside PORT, HOST, CORS_ORIGIN and the rate limit settings, and it also lists FIGMA_TOKEN for server side fetches.

### What licence is VibeFigma released under?

The project is licensed under AGPL-3.0, with a NOTICE file covering third-party code, and the README credits code derived from css-to-tailwindcss under the MIT License. Check the LICENSE and NOTICE files directly for the terms that apply to your use.

## Sources

- [Issues](https://github.com/vibeflowing-inc/vibe_figma/issues)
- [License: AGPL-3.0](https://github.com/vibeflowing-inc/vibe_figma/blob/main/LICENSE)
- [Project website](https://vibeflow.ai/)
- [README](https://github.com/vibeflowing-inc/vibe_figma/blob/main/README.md)
- [vibeflowing-inc/vibe_figma on GitHub](https://github.com/vibeflowing-inc/vibe_figma)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vibeflowing-inc-vibe-figma
