Setup a Monorepo with Turborepo, Next.js, and Tailwind CSS

Iki
5 min readApr 13, 2023

--

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 (from npx create-turbo@latest), it generates docs and web applications (Next.js).
  • packages this file contains shared configurations — including eslint, tsconfig, and a unified UI — 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. The package.json also contains the dependencies and scripts necessary to run the monorepo's applications in the apps 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, the build pipeline may depend on the topological dependencies with dependsOn 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

  1. To begin, we will create a configs folder within the packages directory. Inside this folder, we will create several essential files for our setup, including package.json, tailwind.config.js, and postcss.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/

  1. 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.

--

--

Iki

Software Engineer | Interests: self-growth, tech, health, and neuroscience