> [!IMPORTANT] > Our engineering team is currently focused on the [next generation of ZITADEL](https://github.com/zitadel/nextgen), so our capacity to review community pull requests is limited. We cannot guarantee that your pull request will be reviewed or merged. For larger changes, please open an issue or discussion before you begin. Thank you for contributing and for your understanding. # Which Problems Are Solved - Several npm dependencies in the workspace were behind their latest releases, and some transitive dependencies were locked to older versions even though their parents already allowed newer ones. - The `overrides` list in `pnpm-workspace.yaml` had drifted. Four entries were no longer needed, and none of them said which package pinned the old version, so it was hard to tell when an entry could be removed. - `apps/docs` declared `@scalar/api-reference`, which isn't used anywhere and pulled in a large dependency tree. # How the Problems Are Solved **Direct dependency bumps** | Package | From | To | Where | Type | |---|---|---|---|---| | `next` (+ `@next/eslint-plugin-next`) | 16.2.11 | 16.3.6 | login, docs | minor | | `@faker-js/faker` | ^9.9.0 | ^10.6.0 | login (dev) | **major** | | `testcontainers` | ^11.14.0 | ^12.1.0 | login (dev) | **major** | | `vitest` | ^4.1.6 | ^4.1.11 | login, client (dev) | patch | | `@angular/*` (framework, build, cli) | ^21.2.19 | ^21.2.24 | console | patch | | `nx` | 22.7.7 | 22.7.12 | root (dev) | patch | | `@changesets/cli` | ^2.31.0 | ^2.31.1 | root (dev) | patch | | `wait-on` | ^9.0.10 | ^9.1.0 | root (dev) | minor | | `js-yaml` | ^4.3.1 | ^4.3.2 | docs | patch | | `tsx` | 4.21.0 | 4.23.15 | docs (dev) | minor | | `@scalar/api-reference` | ^1.55.3 | removed | docs | unused | **Transitive dependencies refreshed within their existing ranges** (lockfile only): `qs`, `body-parser`, `hono`, `fast-uri`, `joi`, `js-yaml@3`, `@vitest/mocker`, `sharp`. **Overrides** - Removed, because their parents now depend on fixed versions: `axios` (nx), `postcss` and `sharp` (next 16.3), `uuid` (testcontainers 12 no longer uses it). - Kept or added, each with a comment naming the parent that pins the old version: - `brace-expansion`, `smol-toml`: `nx` pins exact versions, even in its latest 22.x and 23.x releases. - `esbuild`: `tsup` (latest 8.5.1) still allows only `^0.27`. - `@opentelemetry/core`, `@opentelemetry/propagator-jaeger`: kept on purpose, see Additional Context. # Additional Changes - **Login build config:** Next.js 16.3 type-checks every file matched by `tsconfig.json` during `next build`. That now includes unit tests, which vitest runs without type-checking. `next.config.mjs` now points `typescript.tsconfigPath` to a new `tsconfig.build.json` that extends `tsconfig.json` and excludes `*.test.ts(x)`. Editors and vitest keep using `tsconfig.json`. - **`.nvmrc`:** `lts/iron` (Node 20) → `lts/jod` (Node 22), to match `CONTRIBUTING.md`, CI and the devcontainer. - **Login `esbuild` range:** `^0.28.0` → `^0.28.1`, so the manifest matches the specifier pnpm records after applying the `esbuild` override. - **Skill:** a new tool-neutral runbook, `skills/npm-dependency-audit.md`, with a small helper script (`skills/npm-dependency-audit-summary.mjs`). It's listed in `skills/README.md` and linked from `AGENTS.md`, and describes this workflow for contributors and coding agents: fixing findings at the package that introduces them, pruning overrides and documenting the ones that remain. ## Breaking or behavior-changing updates and what to check ### `next` 16.2 → 16.3 (login, docs) Upstream changes that are relevant here: - Proxy (middleware) matching and request URL normalization were reworked. - Turbopack changes, a deprecation warning for the Edge runtime, and `next/image` cache hardening. - A CSP nonce is now added to loading and template scripts. - Stricter TypeScript checking during the build (handled above). The login's `src/proxy.ts` matcher and `basePath` are the most sensitive parts. Manual checks: - **Login, standalone image:** `pnpm nx run @zitadel/login:pack`, or run the Docker Compose setup and go through the login at `/ui/v2/login`: - `/ui/v2/login/loginname` → `/password` → signed in - `/ui/v2/login/register` (with email verification at `/verify`) - MFA: `/otp/time-based`, `/otp/email`, `/otp/sms`, `/passkey`, `/u2f` - external IdP login through `/idp` and the `/idps/callback/*` route - `/logout` and the device flow at `/device` - **Login, proxy passthrough:** requests to `/.well-known/openid-configuration`, `/oidc/v1/*` (authorize, end session), `/saml/v2/*` and `/oauth/*` still get the forwarded headers. For example, an OIDC authorization-code flow started from a sample app completes. - **Login, server actions behind a reverse proxy** with `SERVER_ACTION_ALLOWED_ORIGINS` set: submitting a form, for example the password page, still works. - **Login, OTEL:** with `OTEL_SDK_DISABLED` unset, traces and metrics still reach the collector. The build now prints a Turbopack warning about `process.exit` in `src/instrumentation.ts` for the Edge runtime. It's harmless: `register()` returns early unless `NEXT_RUNTIME === "nodejs"`. - **Docs:** `/docs` home, search, a versioned page such as `/docs/v4.17/...`, an API reference page under `/docs/reference/api/...`, and an OG image under `/og/docs/...`. ### `@faker-js/faker` 9 → 10 (login acceptance tests only) v10 is ESM-only, requires Node ≥ 20.19 and removes deprecated modules (`faker.name`, `faker.address`, `internet.userName`). The acceptance tests only use `internet.email`, `person.firstName`, `person.lastName` and `phone.number`, which didn't change. Check: the login acceptance (Playwright) job is green. ### `testcontainers` 11 → 12 (login dockerized tests only) v12 requires Node ≥ 22.22. CI, `CONTRIBUTING.md` (v22.x) and the devcontainer already use Node 22. `.nvmrc` still pointed to Node 20 (`lts/iron`, end of life), so it now points to `lts/jod` (Node 22). If you use nvm, run `nvm install` again. Its default wait strategy is now the image's Docker healthcheck instead of the listening ports. Every container in `apps/login/dockerized/**` sets an explicit `withWaitStrategy(...)`, so they aren't affected. Check: `pnpm --filter @zitadel/login test-dockerized` (needs Docker). ### `@scalar/api-reference` removed (docs) It isn't imported anywhere in `apps/docs`, and `fumadocs-openapi` only has an optional peer on `@scalar/api-client-react`, which is unrelated. Check: the API reference pages in the docs render and the "try it" panel behaves as before. ### Tooling (`nx`, `@changesets/cli`, `wait-on`, `vitest`, `tsx`, Angular patch releases) These are patch or minor releases with no expected impact. `wait-on` is used by `apps/api` and `tests/functional-ui` to wait for `/debug/ready`. `tsx` runs the docs generation scripts (`generate-index-pages`, `generate-error-reference`, `check-links`). Check: the console smoke test. Sign in to the console and open the organization, users, projects and an application detail page. ## Verification done locally - `pnpm audit`: no findings. - `@zitadel/login`: `build`, `lint`, `test-unit` (62 files / 938 tests) pass. - `@zitadel/console`: `build`, `lint` pass. - `@zitadel/client`: `build`, `lint`, `test-unit` pass. - `@zitadel/docs`: `build` passed with Next 16.3.6 before `@scalar/api-reference` was removed. `check-types` passes after the removal. A second full build couldn't finish locally because the disk ran out of space (`ENOSPC`), so please rely on CI for it. `docs:lint` reports MDX `no-undef` errors, mostly in fetched versioned content. None of the lint tooling changed in this PR, so these don't come from it. - Not run locally: login acceptance (Playwright), login dockerized tests, functional UI (Cypress). # Additional Context - Follow-up: bump the login's OpenTelemetry packages (`@opentelemetry/sdk-node` 0.218 → 0.222, `auto-instrumentations-node` 0.76 → 0.80, stable packages 2.7 → 2.11) and then remove the last two overrides. It's a separate PR because `instrumentation-http` then only emits stable HTTP semantic conventions (`http.request.method`, `http.response.status_code`, `url.path` instead of `http.method`, `http.status_code`, `http.target`). That affects operators' dashboards and alerts, and the OTEL integration tests need updating. - Follow-up: remove the `nx` overrides once a stable nx release ships `smol-toml` ≥ 1.7.1 (already in `23.3.0-beta`), and the `esbuild` override once `tsup` allows esbuild 0.28. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>
Zitadel Management Console
The Management Console is Zitadel's management UI.
It is built using Angular and part of the Zitadel monorepo.
To get started follow the contributing quick start.
Building
To build for production:
pnpm nx run @zitadel/console:build
This will:
- Generate proto files (via
prebuildscript) - Build the Angular app with production optimizations
Linting
To run linting and formatting checks:
pnpm nx @zitadel/console:lint
To auto-fix formatting issues:
pnpm nx @zitadel/console:lint-fix
Project Structure
src/app/proto/generated/- Generated proto files (Angular-specific format)buf.gen.yaml- Local proto generation configurationproject.json- Nx orchestration and caching for builds and testsprebuild.development.js- Development environment settings script
Dependency Chain
The Management Console app has the following build dependencies managed by Nx:
@zitadel/proto:generate- Generates the protobuf stubs@zitadel/client:build- Builds the TypeScript gRPC client library@zitadel/console:generate- Generates Management Console-specific protobuf stubs@zitadel/console:build- Creates a production build from Management Console
This ensures that the Management Console always has access to the latest client library and protobuf definitions.
Proto Generation Details
@zitadel/protogeneration: Modern ES modules with@bufbuild/protobuffor v2 APIs- Local
buf.gen.yamlgeneration: Traditional protobuf JavaScript classes for v1 APIs
The Management Console app calls Zitadel v1 and v2 APIs. As long as the Management Console still calls v1 APIs, it needs to import client stubs from separate sources:
Legacy v1 API (Traditional Protobuf)
- Uses local
buf.gen.yamlconfiguration - Generates traditional Google protobuf JavaScript classes extending
jspb.Message - Uses plugins:
protocolbuffers/js,grpc/web,grpc-ecosystem/openapiv2 - Output:
src/app/proto/generated/ - Used for: Most existing Management Console functionality
Modern v2 API (ES Modules)
- Uses
@zitadel/protopackage generation - Generates modern ES modules with
@bufbuild/protobuf - Uses plugin:
@bufbuild/eswith ES modules and JSON types - Output:
login/packages/zitadel-proto/ - Used for: New user v2 API and services
Dependency Management
The Management Console's project.json ensures proper execution order:
@zitadel/proto:generateruns first (modern ES modules)- Management Console's local generation runs second (traditional protobuf)
- Build/lint/start tasks depend on both generations being complete
This approach allows the Management Console app to use both v1 and v2 APIs while maintaining proper build dependencies.
Legacy Information
This project was originally generated with Angular CLI version 8.3.20 and has been updated over time.