Monorepo

Introduction

I opted to use NX mono repo for this setup for the following reasons:

  • I haven't built a startup that doesn't have an admin dashboard and a customer app (obviously). Usually, both of these share the same component system, libraries, and other toolkits. So it is much more beneficial to include both of these apps in a single repository for you and your engineering team (if you have one) to be productive by sharing resources from different projects.

  • Adding multiple apps is easy. You can add multiple apps for example if you need a cron worker in the future written in Golang, it is simple enough to do so.

But it's also shit at the same time because:

  • Once you go from zero to hero, scaling the build system will be hard since your contiguous integration system might check for new changes throughout the codebase and run tests to ensure all is well.

  • Navigating a large codebase might be a nightmare for you or your team.

For me, the benefits outweigh the cons, so I still opt for a mono repo setup since usually for me, most startups have a sort of cron worker, admin dashboard, and a customer app. Bundling these three apps in a single codebase is the fastest-frictionless way to go from zero to product-market fit, and it doesn't matter if you're a single guy crunching up the code or with a small engineering team.

Shared Libraries

Currently, the only shared libraries are

  • libs/ts/auth

  • libs/ts/mailer

  • libs/ts/uikit

  • libs/ts/uikit-utils

There might be some shareable code between the admin and the customer app, but I'll leave it up to you to refactor if you see one. 😉

If you need to add another shared NextJS library using NX you can use this command

nx g @nx/next:lib my-new-lib

or honestly, you can just create a folder for the library and call it a day. It's just NX tags the library generated using the command for the linter to scan that app or library

As you can notice in the photo above, the libs/ts/auth and libs/ts/mailer were not included in the linting process, and that's because they are libraries that I made manually.

Contiguous Integration

Basic configuration has already been placed, tailor it to your preference. It runs using this command:

    "lint": "nx run-many --target=lint --all --parallel",
    "typecheck": "nx run-many --target=typecheck --all --parallel",
    "ci" : "pnpm run lint & pnpm run typecheck",

Path Aliases

Path aliases are beneficial for your codebase to have a clean look. I don't like them having ../.../.../../../lmao . Check the pattern here and implement it once you make a new app.

    "paths": {
      "@admin-web/*": ["apps/admin-web/src/*"],
      "@db": ["db"],
      "@db/*": ["db/*"],
      "@ts/auth": ["libs/ts/auth"],
      "@ts/mailer": ["libs/ts/mailer"],
      "@ts/uikit": ["libs/ts/uikit/src/index.ts"],
      "@ts/uikit-utils": ["libs/ts/uikit-utils/src/index.ts"],
      "@ts/uikit/icons": ["libs/ts/uikit/src/ui/icons/index.ts"],
      "@web-app/*": ["apps/web-app/src/*"]
    }

App Management

To add a new NextJS app, I placed a script called create:next-app. Once you run it, something like this should appear:

There are a lot of NX generators to generate an app, there's one for NodeJS https://nx.dev/nx-api/node/generators/application and Go https://github.com/nx-go/nx-go. Just search for a generator for what kind of tech your app needs.

To remove an app run this command

npm run remove:app <name_of_your_app>

To show all projects or apps that you have run this command

npm run show:projs

Project Structure for NextJS Apps

Last updated