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
insidesrc/
- Create a
main.tsx
insidesrc/
(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]+