npm package: @kodevy/nx-next
Description: Nx generators for scaffolding Next.js monorepos with Clean Architecture, shared UI, API clients, auth, and utilities.
Latest version: 1.0.6

# Kodevy Next.js Monorepo Template

Nx preset and generators for scaffolding production-ready Next.js monorepos with shared UI, API clients, authentication, and utilities.

---

## What Problem This Solves

Starting a new Next.js monorepo means setting up the same foundation every time: project structure, shared component library, API client infrastructure, authentication, theming, linting, Docker, and CI/CD.

This template gives you a complete, opinionated monorepo with all of that wired up — so you can start building features immediately.

---

## What You Get

Each generated monorepo includes:

- **Nx workspace** — monorepo with apps and shared libraries
- **Next.js app** — App Router, standalone output, Tailwind CSS
- **UI library** — 50+ shadcn/ui components, theme system (light/dark), Sonner toasts
- **API library** — typed HTTP clients for both server and client components, with auth token handling
- **Auth library** — NextAuth.js integration with JWT, token refresh, credentials provider
- **Utils library** — common helpers (date, string, object, async, env, URL)
- **Docker** — multi-stage build with standalone output
- **Azure Pipelines** — generic CI/CD template (customizable)
- **Tailwind CSS** — shared preset, CSS tokens, design system foundation

---

## Prerequisites

- [Node.js 20+](https://nodejs.org/)

---

## Quick Start

### Create a New Monorepo (one command)

```bash
npx create-nx-workspace my-project --preset=@kodevy/nx-next
```

Nx will prompt you for:
- **npm scope** — e.g. `@mycompany` (used for shared library imports)
- **app name** — e.g. `dashboard` (name of the first Next.js app)

Or pass them directly:

```bash
npx create-nx-workspace my-project \
  --preset=@kodevy/nx-next \
  --scope=@mycompany \
  --appName=dashboard
```

This generates:

```
my-project/
├── apps/
│   └── dashboard/              # Next.js starter app
│       ├── app/
│       │   ├── layout.tsx
│       │   ├── page.tsx
│       │   └── api/auth/[...nextauth]/route.ts
│       ├── components/
│       ├── network/
│       ├── project.json
│       ├── next.config.js
│       └── tailwind.config.js
├── libs/
│   ├── ui/                     # 50+ shadcn/ui components + theme
│   ├── api/                    # Server & client API clients
│   ├── auth/                   # NextAuth.js with JWT
│   └── utils/                  # Common helpers
├── nx.json
├── tsconfig.base.json
├── package.json
├── Dockerfile
└── azure-pipelines.yml
```

### Run It

```bash
cd my-project
nx serve dashboard
```

### Add Another App

```bash
nx g @kodevy/nx-next:app \
  --scope @mycompany \
  --appName admin \
  --port 4100
```

### Existing Monorepos vs New Monorepos

- **If your monorepo was created before `@kodevy/nx-next` v`1.0.5`**: install the plugin once:

```bash
npm install -D @kodevy/nx-next
```

- **If your monorepo is created with `@kodevy/nx-next` v`1.0.5` or newer**: the plugin is added automatically, so `nx g @kodevy/nx-next:app` works without manual install.

---

## Available Generators

| Generator | Command | Description |
|-----------|---------|-------------|
| Preset | `npx create-nx-workspace --preset=@kodevy/nx-next` | Creates a full monorepo (recommended) |
| Init | `nx g @kodevy/nx-next:init` | Same as preset, for use inside an existing workspace |
| App | `nx g @kodevy/nx-next:app` | Adds a new Next.js app to an existing monorepo |

---

## Generator Parameters

### Preset / Init

| Parameter | Description | Default |
|-----------|-------------|---------|
| `--scope` | NPM scope for shared libraries (e.g. `@mycompany`) | *(prompted)* |
| `--appName` | Name of the first app (e.g. `dashboard`) | *(prompted)* |
| `--port` | Dev server port | `4000` |

### App

| Parameter | Description | Default |
|-----------|-------------|---------|
| `--scope` | NPM scope (must match existing monorepo) | *(required)* |
| `--appName` | Name of the new app (e.g. `admin`) | *(required)* |
| `--port` | Dev server port | `4100` |

---

## Architecture

### Shared Libraries

All shared code lives in `libs/` and is imported via path aliases:

| Library | Import | Description |
|---------|--------|-------------|
| UI | `@mycompany/ui` | Components, theme, hooks |
| API (client) | `@mycompany/api/client` | Browser-side API client with toast error handling |
| API (server) | `@mycompany/api/server` | Server-side API client with auth headers |
| API (core) | `@mycompany/api/core` | Shared types, ApiClient base, ApiError |
| Auth | `@mycompany/auth` | NextAuth options, authenticated user model |
| Utils | `@mycompany/utils` | Pure utility functions |

### Each App Includes

- `app/` — Next.js App Router pages
- `components/` — App-specific components
- `network/` — Pre-configured API client instances (server + client)
- `project.json` — Nx targets (serve, build, build-standalone, typecheck)
- Tailwind CSS configured with the shared UI preset

---

## Theming and Typography Model

This preset uses a two-layer design system:

1. **Shared defaults in `libs/ui`** (safe, neutral, complete)
2. **Optional app branding in each app** (override only what you need)

### 1) Shared defaults (`libs/ui`)

The UI library provides:

- `libs/ui/src/styles/tailwind.css` — Tailwind directives
- `libs/ui/src/styles/tokens.css` — full semantic token defaults (light + dark)
- `libs/ui/src/styles/base.css` — base styles wired to CSS variables
- `libs/ui/tailwind.preset.js` — Tailwind mapping to semantic tokens

Because `tokens.css` is complete, a brand-new app has a fully working theme even with zero app-specific overrides.

### 2) App-level overrides

Generated apps import styles in this order:

```css
@import '../../../libs/ui/src/styles/tailwind.css';
@import '../../../libs/ui/src/styles/tokens.css';
@import '../../../libs/ui/src/styles/base.css';
@import './theme.css';
```

`theme.css` is app-owned and optional. Since it is imported last, any token or typography variable set there overrides shared defaults.

### Typography and interaction variables

Shared base styles are variable-driven to keep defaults reusable while allowing app branding:

- Typography:
  - `--body-font-family`
  - `--heading-font-family`
  - `--heading-font-weight`
- Links:
  - `--link-color`
  - `--link-decoration`
  - `--link-hover-decoration`
  - `--link-underline-offset`
- Focus ring:
  - `--focus-outline`
  - `--focus-ring-width`
  - `--focus-ring-offset-width`
  - `--focus-ring-color`
  - `--focus-ring-offset-color`

### Font loading

Apps load fonts in `app/layout.tsx` via `next/font/google` and expose:

- `--font-sans`
- `--font-mono`

The shared Tailwind preset also supports legacy aliases:

- `--font-inter`
- `--font-jetbrains-mono`

This keeps new and older app styles compatible.

---

## Docker

Build any app as a standalone Docker image:

```bash
docker build \
  --build-arg APP=dashboard \
  --build-arg NEXT_PUBLIC_API_BASE_URL=https://api.example.com \
  -t my-app .
```

Run:

```bash
docker run -p 3000:3000 my-app
```

---

## License

MIT