DEV Community

Cover image for What is ShaadKit? A Look at My Personal Foundation for Next.js Projects
seyed mojtaba shadab
seyed mojtaba shadab

Posted on

What is ShaadKit? A Look at My Personal Foundation for Next.js Projects

Where Does the Problem Start?

Imagine you've started a new Next.js project. You're about to build something new and exciting. But before you even write a single line of code for the actual product, you have to get through a mountain of repetitive tasks:

  • Setting up ESLint with the right config and strict rules
  • Setting up Stylelint for CSS and CSS Modules
  • Setting up Storybook for component-driven development
  • Adding testing with Vitest and Playwright
  • Setting up i18n for multilingual support from the start
  • Choosing a UI library and integrating it with Next.js
  • Setting up the project structure in a way that's ready to scale
  • Performance tooling like Bundle Analyzer
  • Various Next.js configurations for optimization
  • Project conventions from naming to file structure

And this cycle repeats with every new project:

create-next-app
      ↓
  configure
      ↓
fix conventions
      ↓
 add tooling
      ↓
 add testing
      ↓
add UI infrastructure
      ↓
finally start building
Enter fullscreen mode Exit fullscreen mode

Regardless of the fact that this is a repetitive process for every project, it's honestly extremely exhausting (I get really tired of it!)

One of the best solutions is to use ready-made templates or boilerplates. Given that my main focus is on Next.js, the following can be mentioned as examples:

Given the variety of repos, I could probably come up with 50 more examples! But I had a bigger problem.

I Don't Want a Template with Too Many Features

I love it when a project has many capabilities. For example, Next.js handles server components, optimizes images, creates routing, manages backend APIs, and so on. But this is not a good idea at all for ready-made templates!

The reason is obvious. Every technology or feature means making the learning curve steeper. And if a template has too many capabilities, its learning cost increases, while the whole point of using a template is to get started quickly! A developer might even be forced to learn something they've never worked with before or have no interest in using, but they're stuck with it.

I was looking for something where the capabilities would be plentiful enough, but I wouldn't be obligated to use them. I just wanted to use what I actually needed right now! I believe everything should be just enough — neither more nor less... That's why I created ShaadKit.

I'm Happy I Built ShaadKit

For a long time, I was looking for a project that was neither as simple as create-next-app nor like some boilerplates that pack in more than 50 technologies. I wanted to build an MVP very quickly, so I would use technologies that prioritized speed over quality (though quality is also very important to me).

Now, with ShaadKit, I can set up a scalable frontend foundation in just a few clicks!

ShaadKit uses the following technologies:

  • Bun as the Package Manager — ultra-fast installation and execution
  • 🧩 Mantine v9 — powerful and accessible components
  • 🌍 next-intl — ready for internationalization from the start
  • 📖 Storybook 10 — component-driven development with MCP and A11y
  • 🧪 Vitest + Playwright — fast and reliable tests
  • 🎨 Stylelint + ESLint (Antfu Config) — top-tier code quality
  • 🔍 Bundle Analyzer — bundle analysis and optimization
  • ⚛️ React 19 + React Compiler — the latest React with automatic optimization

But you might say this contradicts what I said a few paragraphs ago: "Every technology or feature means making the learning curve steeper. And if a template has too many capabilities..." However, my approach to this project is a bit different.

As I explained in the What is the philosophy of this stack? section, I didn't have complex technologies in mind for using ShaadKit, and there's no obligation to use the current technologies. You can even skip Mantine (which is the project's main foundation), but I have good reasons for choosing my technologies.

You don't necessarily have to use ShaadKit for large projects. Sometimes you need to create a simple table, or validate an idea very quickly. Mantine was chosen because it was perfectly suited for such an approach.

It Has a Simple Configuration That Is Just Creative and Powerful Enough

This is something I personally find very appealing. I wanted it so that if a developer doesn't like my coding style, they'd still admit that I chose a forward-thinking foundation for the project.

This is appealing to all businesses and employers.

ShaadKit doesn't have any complex configuration. Everything is simple and minimal, but based on the experience I'd gained, I tried to address some of the blind spots that existed.

Extending the configuration is very easy, and even beginner developers can do it!

I didn't add any library that I didn't find useful. As a result, ShaadKit's core is lightweight.

I Care a Lot About Code Quality

It's very important to me that the code I write always meets the necessary standards. Naturally, for this I had to use tools like ESLint or Oxlint.

I consider Oxlint a very appealing choice, but I chose ESLint because it has more capabilities.

I also added Storybook because developing a component in Storybook is faster than in Next.js! This is possible thanks to Vite. When I first got to know Storybook, it honestly became very hard for me to walk away from it.

I Chose the Best Package Manager (In My Opinion)

I've used both npm and pnpm! Aside from being the most stable, npm doesn't have any defensible feature, but pnpm is a milestone for the world of package managers.

However, on Windows (which has no shortage of developers), pnpm usually performs much slower than it claims, due to the nature of symlinks.

I decided to use Bun as the package manager so I could get both pnpm's speed and npm's stability. If you want to use the same symlink capability, you can enable it in Bun.

I Don't Use Next-intl Just for Internationalization!

Of course, the main reason Next-intl was created is to solve internationalization problems in Next.js, but I look at it from a different angle!

The thing is, maybe the site being developed is monolingual, and there are no plans to add more languages in the near future.

But there's another problem that Next-intl can solve: "managing static text." You've surely run into the issue where, to change a single word on the site, you have to go into several files across different parts of the project and edit them. With Next-intl, all the words are managed in one place with the utmost simplicity.

Integrating Next.js and Next-intl with Mantine

This is also mentioned in Mantine's own documentation. Mantine internally maintains two components, Image and Anchor (which is similar to Link in Next.js).

But the problem is that, under normal circumstances, using these two components means losing the power of Next.js!

In ShaadKit's configuration, from the very start, the Image component (from Next.js) has been merged with the Image component (from Mantine).

Also, for internationalization and Next.js optimization, the Anchor component has been merged with the Link component (exported from Next-intl, which itself extends Next.js).

Just Try It Once

As I said, you can set up ShaadKit very quickly:

Make sure you have Bun installed, and using Node.js version 24 is highly recommended

# Clone the project
git clone https://github.com/shaadcode/shaadkit.git
cd shaadkit

# Install dependencies with Bun
bun install

# Run the development server
bun dev
Enter fullscreen mode Exit fullscreen mode

Who Should Use ShaadKit?

ShaadKit is useful for most projects, but there are always some considerations:

  • Next.js developers
  • SaaS projects
  • MVPs that are likely to grow
  • Production projects
  • Multilingual projects
  • Projects where testing and component development matter

Contribute, Give Feedback, Support

Contributing to ShaadKit is easy. You can report a bug, offer your suggestion, or share your criticism:

If ShaadKit managed to solve a problem for you, I'd be very happy if you gave the repo a star (⭐).

Top comments (0)