A modern monorepo setup powered by Bun runtime, featuring a Next.js application with shadcn/ui components. This architecture provides a scalable and maintainable structure for building enterprise-grade web applications.
# Clone into current directory
git clone https://github.com/AlexY-OS/bunjs-monorepo-next-shadcn-ui.git .
# Install dependencies
bun install
bun run dev
bun run build
bun run start
- Runtime & Package Manager: Bun
- Framework: Next.js 14+
- UI Components: shadcn/ui
- Styling: Tailwind CSS
- Type Safety: TypeScript
├── apps/
│ └── web/ # Next.js application
│ ├── src/ # Application source code
│ └── next.config.js # Next.js configuration
├── packages/
│ └── ui/ # Shared UI components library
│ ├── src/ # UI components source
│ ├── next.config.js # Required for shadcn/ui initialization
│ ├── components.json # shadcn/ui configuration
│ └── package.json # UI package configuration
├── package.json # Root package configuration
└── tsconfig.json # TypeScript configuration with path aliases
The project uses a workspace-based monorepo structure with centralized dependency management:
- All shared dependencies are installed in the root
node_modules
- No duplicate dependencies across packages
- Managed through workspace hoisting
// package.json
{
"workspaces": [
"apps/*",
"packages/*"
]
}
// apps/web/package.json
{
"dependencies": {
"@bun-monorepo/ui": "workspace:*"
}
}
- Create Base Structure
mkdir apps packages
mkdir apps/web packages/ui
- Configure Package Files
packages/ui/package.json
{
"name": "@bun-monorepo/ui",
"exports": {
".": { "import": "./src/index.ts" },
"./*": "./src/components/ui/*.tsx",
"./lib/utils": "./src/lib/utils.ts"
}
}
- Initialize shadcn/ui
# Initialize shadcn/ui
bun run ui:init
# Add components
bun run ui:add button
// Import UI components
import { Button } from "@bun-monorepo/ui/button";
import { cn } from "@bun-monorepo/ui/lib/utils";
// Import from web application
import { Component } from "@web/components";
{
"scripts": {
"dev": "bun run --cwd apps/web dev",
"build": "bun run build:packages && bun run build:apps",
"ui:init": "bun x shadcn@latest init --cwd packages/ui",
"ui:add": "bun x shadcn@latest add --cwd packages/ui"
}
}
- Use workspace dependencies with
workspace:*
- Keep shared dependencies in root package.json
- Use proper exports in packages/ui/package.json
- Maintain clear separation between app and UI package
- Only
.bin
directory is created in localnode_modules
- this is expected behavior - Dependencies are hoisted to root
node_modules
- Use
bunx
for running local binaries
- Bun 1.0+
- Node.js 18+
- TypeScript 5.3+
- Next.js 14+
MIT
The project uses a multi-level TypeScript configuration to handle both the UI library and Next.js application:
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@bun-monorepo/ui": ["packages/ui/src"],
"@bun-monorepo/ui/*": ["packages/ui/src/*"],
"@web": ["apps/web/src"],
"@web/*": ["apps/web/src/*"]
}
}
}
// packages/ui/tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "node",
"isolatedModules": true,
"paths": {
"@bun-monorepo/ui/*": ["./src/*"]
}
}
}
// apps/web/tsconfig.json
{
"compilerOptions": {
"jsx": "preserve", // Required for Next.js
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"],
"@bun-monorepo/ui": ["../../packages/ui/src"],
"@bun-monorepo/ui/*": ["../../packages/ui/src/*"]
}
}
}
- Root config provides base paths for monorepo
- UI package uses
react-jsx
for optimal component compilation - Next.js app uses
preserve
for SSR optimization - Path aliases are configured at each level for proper module resolution