Skip to main content
Photo from unsplash: sawyer-bengtson-umRPY9w3q1c-unsplash_aw4tur

One-stop Starter to Maximize Efficiency on Next.js & Tailwind CSS Projects

Written on January 05, 2022 by Theodorus Clarence.

9 min read
––– views


I made the ts-nextjs-tailwind-starter after I got tired of setting up a new project and have to initialize Tailwind CSS every single time. After some months, this starter has grown and is filled with a lot of development automation and tools that help me when I'm developing.

This is something that I use every project init, features are carefully curated, and put into this repository.


According to my list, these are all the features that I incorporate on ts-nextjs-tailwind-starter:

  • ⚡️ Next.js 13
  • ⚛️ React 18
  • ✨ TypeScript
  • 💨 Tailwind CSS 3 — Configured with CSS Variables to extend the primary color
  • 💎 Pre-built Components — Components that will automatically adapt with your brand color, check here for the demo
  • 🃏 Jest — Configured for unit testing
  • 📈 Absolute Import and Path Alias — Import components using @/ prefix
  • 📏 ESLint — Find and fix problems in your code, also will auto sort your imports
  • 💖 Prettier — Format your code consistently
  • 🐶 Husky & Lint Staged — Run scripts on your staged files before they are committed
  • 🤖 Conventional Commit Lint — Make sure you & your teammates follow conventional commit
  • ⏰ Release Please — Generate your changelog by activating the release-please workflow
  • 👷 Github Actions — Lint your code on PR
  • 🚘 Automatic Branch and Issue Autolink — Branch will be automatically created on issue assign, and auto linked on PR
  • 🔥 Snippets — A collection of useful snippets
  • 👀 Default Open Graph — Awesome open graph generated using og, fork it and deploy!
  • 🗺 Site Map — Automatically generate sitemap.xml
  • 📦 Expansion Pack — Easily install common libraries, additional components, and configs

Quite a lot huh? I'm going to take an in-depth look at each feature and automation with this post.

Easy Initial Config

Don't you hate it when you use a starter, then you see some branding or default configs left out unchanged?


I prepared a unique word that you can find, with some guide of what to override. You can remove the comments after you override them, and leave them if you haven't. Treat them as a to-do comment.

Pre-built Components

I prepared a set of components that is neutral and can be used to help boost your speed in development. These are components that have a high chance of being used, not just getting deleted after you finished cloning the repository.

All animations are configured to be motion-safe.

Don't like the theme?

You can change it with CSS Variables. I prepared all Tailwind CSS colors converted to CSS Variables in the styles/colors.css file that you can copy and use.


See more details about components on the demo page

SEO Enhancement

Do you want your project to be indexed to search engines? Yeah, me too. I optimized the SEO by preparing a custom Seo component and adding next-sitemap.


If you want to use the default meta tag, just add <Seo /> on top of your page.

You can also customize it per page by overriding the title, description as props

<Seo title='Next.js Tailwind Starter' description='your description' />

or if you want to still keep the site title like %s | Next.js Tailwind Starter, you can use templateTitle props.

Minimal Dependencies

I tried to keep the dependencies small, not the devDeps tho, you'll see why after you see a bunch of automation I create. Here are the 3 dependencies (excluding Next.js and React deps)

  1. clsx, a utility for constructing className strings conditionally.
  2. react-icons, easily import popular icon packs in SVG format.
  3. tailwind-merge, override tailwind CSS classes without using !important.

The tailwind-merge can be used by importing clsxm from @/lib/clsxm. All of the pre-built components are using clsxm to ease the use of the reusable components.

Here is a thread that I made about tailwind-merge:

Absolute Import & Path Alias

import Header from '../../../components/Header';
// simplified to
import Header from '@/components/Header';

Reduce the complexity of importing components by using absolute import, and a nice path alias to differentiate your code and external libraries.

Prettier with Tailwind CSS Class Sorter

In this repository, I set it up so it will automatically sort class based on the custom config file. It even works with clsx or classnames! You don't need to ask your colleague to download another VS Code extension. All of it is bound to the repository.


This repository is prepared with ESLint to reduce human errors during development. Don't worry there won't be any annoying styling lint because all of it is taken care of with Prettier. Some cool features such as:

Auto Import Sort & Unused Import Removal

Don't you hate it when you have to revise your code because your reviewer told you to reorder imports? If they haven't automated it, do yourself a favor by recommending this starter.

Husky & Lint Staged

There are 3 Husky hooks that will help you with the automation of:

  1. pre-commit, run eslint check with 0 tolerance to warnings and errors and format the code using prettier
  2. commit-msg, run commitlint to ensure the use of the Conventional Commit for commit messages
  3. post-merge, running yarn every git pull or after merging to ensure all new packages are installed and ready to go

Oh right, you also don't have to wait that long because husky only the code that you stage (using lint-staged).

What about the type check, or if the staged code made the other fail? Don't burden your efficiency, just chuck it into Github Actions to run in the background.

Github Actions

I love automation and I put some useful workflows that you can use.

Type Check, Whole ESLint & Prettier

For the sake of efficiency, we don't run whole project checks on your local machine. That takes too long just to commit simple changes. We will run it on Github Actions instead, then you can continue working while waiting for it to complete.

Here are the complete lists that will be checked:

  1. ESLint - will fail if there are any warnings and errors
  2. Type Check - will fail on tsc error
  3. Prettier Check - will fail if there are any formatting errors
  4. Test - will fail if there are any test failures

Github also provides useful inline warnings in the Files Changed tab on the PR.

Auto Create Branch

We can automatically create a branch from the latest main branch after you assign an issue.

This will create a consistent branch name with the issue number in front of them, and some issue context.

p.s. You have to install the app for your organization/account/repository from the GitHub Marketplace for this to work

We automated the branch creation, the lint & the test process on the PR, what's next? Yep, linking PR to issue. That is super annoying and I always forgot to do it. We'll automate it using our consistent branch name.

It also provides a nice description of related issues, so your reviewer can check the issue first before reviewing.

Open Graph Generator

I also provided an open graph application that you can fork and deploy to vercel for free. It is automatically used with the SEO component and will generate a dynamic open graph based on the page title and description.

It defaults to my deployment, but please fork it and self-host. Because I might change the API without notice and could break your app's opengraph.


You can even customize it with your own brand based on the repo!


Snippets are crucial if you want to make a consistent convention across the application. I prepared some snippets that can help you code faster and more effectively.


See more detail on this file


You might notice the #region with green highlight comments. This is something that can be used with reg snippets. You can easily separate your logic into named regions, then fold them if they are insignificant.


The lesser noise the better. You can also use ⌘ K + ⌘ 8 to fold all regions.

Snippets Wrap

This is something that I recently added because it is annoying to wrap a component with React Fragment or refactoring className with clsx. So I created a snippet pattern called Snippets Wrap that can help you with that.

Expansion Pack

I have to keep this starter minimal, but there are some libraries that I often use in every project. So I created a bash script to install, config, and add additional components to this starter.

Currently, there are some packs in the expansion-pack repository

Here is a demo for the React Hook Form one

Hit the terminal then grab some coffee. You're back with complete components also a sandbox page to see how to implement the library.

For more demo, check out the repository readme

Star the repository

Liking the features? This repository basically grows with me, so the features will go through changes and improvement. If you got anything in mind, leave a comment below, or open a discussion.

Finally, I would be thrilled if you give a star to the repository.

Tweet this article

Enjoying this post?

Don't miss out 😉. Get an email whenever I post, no spam.

Subscribe Now