As modern web applications continue to grow in both size and complexity, developers are looking for ways to manage codebases more efficiently. Monorepos offer a solution, allowing multiple projects to be managed in a single repository.
However, setting up a monorepo manually can be a daunting task. This is where Turborepo comes in. Turborepo is a tool that simplifies the process of creating a monorepo by automating many of the steps involved. In this article, I’ll use Turborepo to set up a monorepo that includes a Next.js (default project) as a project-base and Tailwind CSS for styling.
Let’s get started!
1. Create a New Monorepo
Let’s start by creating a Turborepo monorepo with the following command:
npx create-turbo@latest
When running the command, you’ll be prompted to choose the location where it should be created and select a package manager. For this article, I will be using yarn
, you can choose whichever package manager you prefer, such as npm
or pnpm
.
After the setup is complete, navigate to the directory (cd yourProjectName
)and open the project in your preferred IDE.
Now you can test running it with the following command
yarn install && yarn dev
If your terminal looks like below, then the starting setup is complete.
2. Directories Explanation
Now, let’s discuss the folder structure and project that are created by Turborepo.
apps
is all the applications we have in this monorepo. By default (fromnpx create-turbo@latest
), it generatesdocs
andweb
applications (Next.js).packages
this file contains shared configurations — includingeslint
,tsconfig
, and a unifiedUI
— that govern elements across the entire monorepo.package.json
one notable aspect of this setup is the use of Yarn workspaces which allow us to manage multiple packages and dependencies within a single monorepo. Thepackage.json
also contains the dependencies and scripts necessary to run the monorepo's applications in theapps
directory.
turbo.json
is a configuration file used by Turborepo to organize and manage pipelines, sequences of commands run in a specific order. For instance, thebuild
pipeline may depend on the topological dependencies withdependsOn
symbolized by^
for reliability and efficiency.
3. Setup Tailwind CSS
To ensure that the tailwind.config.js
file serves as a single source of truth across all projects, I will create a new configuration package within the packages
folder. This allows the use of Tailwind classes in both the apps
and packages/ui
directories.
The following steps will be taken:
A. Setup Tailwind CSS config in packages folder
- To begin, we will create a
configs
folder within thepackages
directory. Inside this folder, we will create several essential files for our setup, includingpackage.json
,tailwind.config.js
, andpostcss.config.js
.
package.json
It’s worth noting that Turborepo documentation recommends using a specific package name format, such as
@organizationName/packageName
, to avoid any potential collisions with existing packages on the NPM library.
{
"name": "@mrizkiaiman/configs",
"version": "0.0.0",
"private": true
}
tailwind.config.js
module.exports = {
content: [
"../../packages/ui/**/*.{js,ts,jsx,tsx}",
"./**/*.{js,ts,jsx,tsx}",
"./pages/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
};
postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
B. Implement Tailwind CSS config in apps/
- In the root directory, run the following command
yarn workspace docs add -D tailwindcss autoprefixer
2. Create tailwind.config.js
and postcss.config.js
files
This configuration will reference the single source of truth we established in the package
configs/tailwind
within the monorepo.
tailwind.config.js
module.exports = require("@mrizkiaiman/configs/tailwind/tailwind.config");
postcss.config.js
module.exports = require("@mrizkiaiman/configs/tailwind/postcss.config");
3. Navigate to the packages/ui
folder and create the following files: tailwind.config.js
, postcss.config.js
, and styles.css
tailwind.config.js
module.exports = require("@mrizkiaiman/configs/tailwind/tailwind.config");
postcss.config.js
module.exports = require("@mrizkiaiman/configs/tailwind/postcss.config");
As a note, I’ve decided to create the global styles in the
packages/ui
directory, thus providing easy access and usage across all apps within the monorepo.
styles.css
@tailwind base;
@tailwind components;
@tailwind utilities;
4. Return to the apps/docs
folder and navigate to the pages
directory. Create a _app.tsx
file that will import the global styles we previously created for the monorepo's initialization of Tailwind CSS.
_app.tsx
import "ui/styles.css";
import type { AppProps } from "next/app";
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
The setup should be done and let’s test it!
Testing:
You can follow the same steps for any remaining apps within the monorepo, such as apps/web
.
In conclusion, building a monorepo with Turborepo could revolutionize your workflow. With an organized structure and streamlined processes, this combination can help you easily manage large-scale projects and multiple applications while saving you time and improving reliability. Try it out for yourself and see how it can transform the way you work.
Thanks for reading and any kind of feedback will be so much appreciated.
GitHub Repository: https://github.com/mrizkiaiman/turborepo-withtailwind