Create a Design System with Turborepo, React, Tailwind — connect it to Figma variables (1/3)

Fokker Chartier
4 min readOct 3, 2023

--

In this series I show how to create a link between design and code in a TurboRepo , Figma variables, Tailwind CSS. At the end compare this with my current setup of NX, React, SCSS and Token Studio. Let’s get started.

Create a new Turborepo

npx create-turbo@latest
>> TURBOREPO

>>> Welcome to Turborepo! Let's get you set up with a new codebase.

? Where would you like to create your turborepo? tailwindDS
? Which package manager do you want to use? yarn workspaces

Downloading files. This might take a moment.

>>> Created a new Turborepo with the following:

apps
- apps/docs
- apps/web
packages
- packages/eslint-config-custom
- packages/tsconfig
- packages/ui

Installing packages. This might take a couple of minutes.

>>> Success! Created a new Turborepo at "tailwindDS".
Inside that directory, you can run several commands:

yarn run build
Build all apps and packages

yarn run dev
Develop all apps and packages

yarn run lint
Lint all apps and packages

Turborepo will cache locally by default. For an additional
speed boost, enable Remote Caching with Vercel by
entering the following command:

npx turbo login

We suggest that you begin by typing:

cd tailwindDS
npx turbo login

Unlink from Cloud as we don’t use it , open Monorepo in VSCode and start in dev mode (depending on your setup you might also start it with npm, pnpn)

npx turbo unlink
code .
yarn dev

Project Setups in Apps

Delete default Apps (Web & Doc) in ./apps Folder and create a default new NextJS app.

cd ./apps 
npx create-next-app@latest

# anwer like this
✔ What is your project named? … website
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias? … No / Yes

cd ..
yarn

#Waaaaaaiiiiit some time

Error: website:dev: error TS6046: Argument for ‘ — moduleResolution’ option must be: ‘node’, ‘classic’, ‘node16’, ‘nodenext’.

We might edit the tsconfig.ts file in our freshly created App. But. We like to make it more verbose and will make use of the provided tsconfig module.

Add this to the dependencies in the package.json of the freshly created NextJs App.

"tsconfig": "*"

Edit the tsconfig in the new Apps folder

{
"extends": "tsconfig/nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"plugins": [
{
"name": "next"
}
]
}
}

Restart the dev server using yarn dev and everything should work.

Next clear the Next App page.tsx

const Home = () => {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
Hello
</main>
)
}

Tailwind setup

create a new module folder “tailwindsetup” in package index.ts and add

const defaultTheme = require("tailwindcss/defaultTheme");

/** @type {import('tailwindcss').Config} */
const defaultConfig = {
darkMode: ["class"],
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
"./apps/**/*.{js,ts,jsx,tsx}",
"./src/**/*.{js,ts,jsx,tsx}",
"../../packages/ui/**/*.{js,ts,jsx,tsx}", // Add the ui package
],
theme: {},
extend: {},
plugins: [],
};

export default defaultConfig;

Create the module package.json to use it accross the turoborepo and add

{
"name": "tailwindsetup",
"version": "0.0.0",
"main": "index.ts",
"license": "MIT"
}

Add the new module to the depencies of our NextJs App’s package.json . exit the dev server and type yarn into your terminal This will create the nesessary links in Turbo to use our new module accross in the nextjs app. To use it accross all apps you might also add it to the root package.sjon depencies.

Before finish part 1 of our journey let’s try if everyting works as expected.Modify the tailwind.config.ts file inside the Next app folder so it reads.

/** @type {import('tailwindcss').Config} */
import defaultConfig from "tailwindsetup";

module.exports = {
...defaultConfig,
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
};

Edit the index.ts file in the tailwind

const defaultTheme = require("tailwindcss/defaultTheme");

/** @type {import('tailwindcss').Config} */
const defaultConfig = {
darkMode: ["class"],
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
"./apps/**/*.{js,ts,jsx,tsx}",
"./src/**/*.{js,ts,jsx,tsx}",
"../../packages/ui/**/*.{js,ts,jsx,tsx}", // Add the ui package
],
theme: {
colors: {
bubblegum: "#C4FF33",
oldbubblegum: '#485C17'
},
},
extend: {},
plugins: [],
};

export default defaultConfig;

And modify the the nextjs page.tsx file

import {Card} from "ui";

const Home = () => {
return (
<main className="flex min-h-screen flex-col items-center p-24">
<h1 className="text-6xl text-bubblegum">Hello</h1>
<Card
title="End of part 01"
className="text-oldbubblegum rounded-md text-lg bg-bubblegum p-6 w-80"
href="#">Next time we focus on Figma</Card>
</main>
)
}

export default Home

Restart dev server. And the page should look like.

One pittfall I found with this setup is a problem with watching/livereload changing the Tailwind config file inside the module. If someone knows let me know;-)

Next time we will focus on a bare minimal “Design-System” Setup in Figma using Figma Token Studio or lets see Variables.

Part 2 : Figma Design
Part 3: Tailwind Setup

--

--