Overview of @your-org/ui-lib
main@your-org/ui-lib package serves as a basic example of a design-system setup within this monorepo. It is designed to be used for building and documenting UI components using Storybook.repository·main·Indexed 23 days ago
https://github.com/belgattitude/nextjs-monorepo-exampleA Next.js oriented monorepo example demonstrating best practices for structure, shared packages, and tool integration using Turborepo and Yarn 4. It includes a Next.js application with REST and GraphQL APIs, I18N via next-i18next, and shared workspace packages such as @your-org/db-main-prisma for database management, @your-org/common-i18n for translations, and @your-org/eslint-config-bases for composable linting configurations. The project provides full Docker Compose support for deployment and local development.
@your-org/ui-lib package serves as a basic example of a design-system setup within this monorepo. It is designed to be used for building and documenting UI components using Storybook.The project follows a standard monorepo structure managed by Turborepo and Yarn 4, using TypeScript path aliases.
apps/: Contains deployable applications.nextjs-app: A Next.js application featuring SSR, i18n, API routes, and Vitest.vite-app: A basic Vite application.packages/: Contains shared libraries and configurations.core-lib: Publishable basic TypeScript libraries.db-main-prisma: Database layer using Prisma.eslint-config-bases: Shared ESLint configurations.ui-lib: A publishable React-based design system (using Emotion and Storybook).common-i18n: Shared locales and i18n logic.static/: Contains non-code assets like images, JSON, and locales.docker/: Contains Docker configurations, including a multi-stage Dockerfile for nextjs-app and docker-compose files for services like PostgreSQL.package.json (root): Defines the workspace configuration.tsconfig.base.json: The base TypeScript configuration used across the monorepo..yarnrc.yml: Yarn configuration.The application follows this organizational structure:
src/backend/*: Backend logic.src/components/*: Shared UI components.src/features/*: Feature-based modules (grouped by context).src/pages/api: Next.js API routes.public/locales/: I18n translation files.next-i18next.config.mjs: I18n configuration.tsconfig.json: Local path mappings for monorepo packages..
├── apps
│ └── nextjs-app
│ ├── public/
│ │ └── locales/
│ ├── src/
│ │ ├── backend/* (backend code)
│ │ ├── components/*
│ │ ├── features/* (regrouped by context)
│ │ └── pages/api (api routes)
│ ├── .env
│ ├── .env.development
│ ├── (.env.local)*
│ ├── next.config.mjs
│ ├── next-i18next.config.mjs
│ ├── tsconfig.json (local paths enabled)
│ └── tailwind.config.js
└── packages (monorepo's packages that this app is using)
├── core-lib
├── main-db-prisma
└── ui-libThis monorepo follows a specific dependency pinning strategy to balance stability and ease of updates:
dependencies and devDependencies are pinned to exact versions. This ensures reproducible builds and prevents unexpected breaking changes in application deployments.To maintain these dependencies, you can use the following scripts:
yarn deps:check: Checks for outdated dependencies.yarn deps:update: Updates dependencies.Alternatively, you can use Renovatebot for automated updates, as the project includes a renovate.json5 configuration.
Internationalization (I18N) is managed using next-i18next.
next-i18next.config.mjs.public/locales/../src/types.d/i18next.d.ts.Each application within the apps/ directory follows a standardized structure:
e2e/: (Optional) Contains end-to-end tests using frameworks like Cypress or Playwright.public/: Framework-conventional public assets folder.setup/: Configuration files for tooling, such as Vitest or React Testing Library (RTL).src/: The main application source code.package.json: Defines all dependencies required to run this specific app independently.next.config.mjs, tsconfig.json, eslintrc.cjs: Framework and tooling configuration files.🌳 (./apps)
└── 🍂 nextjs-app
├── 🏁 e2e
├── 👀 public
├── 🔩 setup
├── 💫 src
├─ eslintrc.cjs
├─ next.config.mjs
├─ package.json
├─ (tailwind.config.ts)
└─ tsconfig.jsonThere are two mutually exclusive ways to handle Prettier integration. Choose the one that fits your workflow:
@your-org/eslint-config-bases/prettier-plugin (Recommended for simplicity): ESLint will run Prettier automatically during the lint process. This is easiest to set up.@your-org/eslint-config-bases/prettier-config (Recommended for performance): ESLint only disables rules that conflict with Prettier. You must run Prettier as a separate command (e.g., prettier --write .).To customize your Prettier configuration while using the provided helpers, update your .prettierrc.js:
// .prettierrc.js
// @ts-check
const { getPrettierConfig } = require("@your-org/eslint-config-bases/helpers");
/**
* @type {import('prettier').Config}
*/
module.exports = {
...getPrettierConfig(),
overrides: [
// your custom overrides
],
};The src/ directory of applications follows a pattern inspired by bulletproof-react, adapted for Next.js features. Key directories include:
app/ or pages/: Next.js routing directories (App Router or Pages Router).features/: Domain-driven feature modules (the core of the application logic).components/: React components shared across the entire application.hooks/: React hooks specific to this application.layouts/: Layout components.providers/: React Context providers.server/: Server-side specific code.lib/: Third-party library configurations or wrappers.utils/: Utility functions (e.g., for tRPC).styles/: CSS, variables, and global styles.types.d: TypeScript declaration files.🌳 nextjs-app
└── 💫 src
├── app(*)
├── components
├── config
├── 🎼 features
├── hooks
├── layouts
├── lib
├── pages(*)
│ └── api(*)
├── providers
├── 🍂 server
├── styles
├── types.d
├── utils
└─ (middleware.ts(*))Storybook is used within the @your-org/ui-lib package to build UI components in isolation from the application's business logic, data, and context. This allows you to develop and test hard-to-reach UI states by saving them as stories.
To learn how specific components are implemented in Storybook, you can view their code in the stories directory within the package.
The project uses a multi-stage Dockerfile to minimize image size and optimize build times by leveraging buildx caching. The process is divided into three main stages:
deps: Installs the monorepo dependencies and makes node_modules available for subsequent stages. This stage can be skipped if the lock file hasn't changed.builder: Automatically runs the deps stage, copies the installed node_modules, performs the build, and removes devDependencies to keep the image slim.runner: The final production stage. It launches the production build and listens on http://localhost:3000 by default. You must provide a .env file with required runtime variables.Note: Ensure you have a .dockerignore file configured to prevent unnecessary files from being sent to the Docker daemon.
To initialize the database package, start the database container using Docker and then run the Prisma lifecycle commands. This sequence sets up the schema, seeds the data, and prepares migrations.
docker-compose up databasecd packages/db-main-prismayarn prisma-db-push (Create/Push schema)yarn prisma-db-seed (Seed data)yarn prisma-migrate dev (Run migrations)yarn prisma-migrate-reset (Reset database)cd packages/db-main-prisma
yarn prisma-db-push
yarn prisma-db-seed
yarn prisma-migrate dev
yarn prisma-migrate-resetTo use the Docker features in this project, ensure you have the following installed:
Optional tools:
lazydocker: A TUI for managing Docker.dive: For debugging layer sizes.If you are on Ubuntu, you may need to remove OS defaults before installing the official Docker engine:
sudo apt-get remove docker docker-engine docker.io containerd runc
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginsudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin