Figma has an awesome tool to easily generate and iterate over web apps design called Figma AI. It is a great way to get started fast with your ideas. It reminds of FlutterFlow a little bit, in the sense that it generates the frontend code for you. The generated design is decent to be used as an MVP, although your product will very likely look highly generic. I can definitely use this as a prop maker for movies and what nots.

The issue that I found however is that it was a bit confusing to get it running outside of their platform, mainly due to the fact that I have very little knowledge about webdev. So here is how I got things running (90%, some things are still missing).

1. Download the code

The generated code gave a folder structure similar to this:

$ tree .
.
├── App.tsx
├── Attributions.md
├── components
   ├── figma
   └── ImageWithFallback.tsx
   ├── ui
   ├── accordion.tsx
   ├── alert-dialog.tsx
   ├── alert.tsx
   ├── (...)
   └── utils.ts
   ├── HelpPage.tsx
   ├── (...)
   └── Configuration.tsx
├── guidelines
   └── Guidelines.md
└── styles
    └── globals.css

Taking a look at App.tsx you can see what sort of tech slop was used on the generated design. Mine had:

  • Tailwind CSS
  • Framer Motion (motion/react)
  • Radix UI
  • lucide-react (for icons)
  • shadcn/ui (components style)
  • localStorage
  • require for loading

The use of localStorage apparently means that it is not React Native (it only runs on browser) and for some god-forsaken reason it was using require (I had no idea most modern projects don’t use it to be honest, but it proved to be a hassle later on).

2. Create a project with Vite, React, and TypeScript

npm create vite@latest my-project -- --template react-ts
cd my-project

3. Replace the template with your downloaded content from Figma

  • Delete the contents from the src/ folder
  • Copy the files to my-project/
  • Put App.tsx inside src/
  • Create a main.tsx inside src/ (new entry point for the application)

4. Install the dependencies

I had to install these and a few more later. Maybe you can grep the files for the imports if you don’t want to go through the trial-and-error loop of “missing dependency X”.

npm install tailwindcss@3 postcss autoprefixer \
react-dom react \
framer-motion motion \
lucide-react \
class-variance-authority clsx \
@radix-ui/react-accordion \
@radix-ui/react-alert-dialog \
@radix-ui/react-aspect-ratio \
@radix-ui/react-avatar \
@radix-ui/react-checkbox \
@radix-ui/react-collapsible \
@radix-ui/react-context-menu \
@radix-ui/react-dialog \
@radix-ui/react-dropdown-menu \
@radix-ui/react-hover-card \
@radix-ui/react-label \
@radix-ui/react-menubar \
@radix-ui/react-navigation-menu \
@radix-ui/react-popover \
@radix-ui/react-progress \
@radix-ui/react-radio-group \
@radix-ui/react-scroll-area \
@radix-ui/react-select \
@radix-ui/react-separator \
@radix-ui/react-slider \
@radix-ui/react-slot \
@radix-ui/react-switch \
@radix-ui/react-tabs \
@radix-ui/react-toggle \
@radix-ui/react-toggle-group \
@radix-ui/react-tooltip

5. Configure Tailwind

Important thing about Tailwind install

I’m dumb and spent too long trying to fix this, so listen up so you don’t fuck it up as well. To set up Tailwind with the command below, you need to have version 3, hence the npm install tailwindcss@3. They changed a bunch of things with installation with newer version. You can see more here. If you want to use the new one I guess you can just try to create the files manually as well (?)

npx tailwindcss init -p

Edit the newly created tailwind.config.js:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./App.tsx",
    "./components/**/*.{ts,tsx}",
    "./styles/**/*.css"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

In styles/globals.css insert:

@tailwind base;
@tailwind components;
@tailwind utilities;

If you have issues such as:

[plugin:vite:css] [postcss] /my-project/styles/globals.css:2:1: The `border-border` class does not exist. If `border-border` is a custom class, make sure it is defined within a `@layer` directive.
 
/my-project/styles/globals.css:2:0
 
1  |  @custom-variant dark (&:is(.dark *));
2  |  @tailwind base;
   |  ^
3  |  @tailwind components;
4  |  @tailwind utilities;

You may need to declare the variables inside the tailwind.config.js. I had to edit mine to the following:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./App.tsx",
    "./components/**/*.{ts,tsx}",
    "./styles/**/*.css"
  ],
  theme: {
    extend: {
      colors: {
        border: "var(--border)",
        ring: "hsl(var(--ring))",
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [],
}

5. Edit main.tsx

Edit main.tsx to something similar to this:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import '../styles/globals.css'
 
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

6. Run it

npm run dev

Other Errors I Had Issues With

1. Using require() (Not supported in Vite)

Replace:

const Component = require('./components/MyComponent');

With:

import { MyComponent } from './components/MyComponent';

Otherwise your components won’t render.

2. Import Errors

I would get some errors like:

Failed to resolve import "@radix-ui/react-progress@1.1.2"
Failed to resolve import "@radix-ui/react-label@2.1.2"

For some reason Figma generates code with the versions in the imports, which is not valid for local ESModules. So stuff like import * as ProgressPrimitive from "@radix-ui/react-progress@1.1.2"; won’t work. All you have to do is remove the @x.y.z and things should work. Like this:

import * as ProgressPrimitive from "@radix-ui/react-progress";
import * as LabelPrimitive from "@radix-ui/react-label";

You can use a regex to find all occurrences. I use this on my IDE: @[0-9]+\.[0-9]+\.[0-9]+