Photo by Tom Grünbauer on Unsplash
12 Features to Maximize Efficiency on Next.js & Tailwind CSS Projects
Increase your efficiency by using a pre-configured starter repository, with rich development features and automation.
Introduction
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.
Features
According to my list, these are all the features that I incorporate on ts-nextjs-tailwind-starter:
- ⚡️ Next.js 12
- ⚛️ React 17
- ✨ 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
- 🃏 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 and Tailwind CSS classes consistently
- 🐶 Husky & Lint Staged — Run scripts on your staged files before they are committed
- 🤖 Conventional Commit Lint — Make sure you & your teammates follow the conventional commit
- ⏰ Standard Version Changelog — Generate your changelog using
yarn release
- 👷 Github Actions — Lint your code on PR
- 🚘 Automatic Branch and Issue Autolink — Branch will be automatically created on issue assigned, and auto-linked on PR
- 🔥 Snippets — A collection of useful snippets
- 👀 Default Open Graph — Awesome open graph generated using og.thcl.dev, 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)
- clsx, a utility for constructing
className
strings conditionally. - react-icons, easily import popular icon packs in SVG format.
- 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.
ESLint
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:
- pre-commit, run eslint check with 0 tolerance to warnings and errors and format the code using prettier
- commit-msg, run commitlint to ensure the use of the Conventional Commit for commit messages
- post-merge, running
yarn
everygit 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:
- ESLint - will fail if there are any warnings and errors
- Type Check - will fail on
tsc
error - Prettier Check - will fail if there are any formatting errors
- 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
Auto Link PR to Issue
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 play around with the API on og.thcl.dev. You can even customize it with your own brand based on the repo!
Snippets
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
Regions
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
- React Hook Form + Form Input Components
- Storybook
- Cypress + workflow to run on Vercel preview on push
- Toast with React Query / SWR
- Dialog Manager with Zustand
- NProgress
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.
Originally posted on my personal site, find more blog posts and code snippets library I put up for easy access on my site 🚀
Like this post? Subscribe to my newsletter to get notified every time a new post is out!