This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Nx monorepo that publishes a family of Nx plugins (@nxext/*) for non-Angular frameworks: capacitor, ionic-angular, ionic-react, stencil, svelte, sveltekit, solid, preact, plus a shared common library. Plugin majors track the supported Nx major — e.g. 21.x of a plugin requires Nx 21.x.
Package manager: pnpm (pinned via packageManager in root package.json). Node version in .node-version. Always run pnpm format before pushing (enforced in CONTRIBUTING.md).
nx.json overrides the default Nx layout:
packages/*— the publishable plugin libraries (libsDir).e2e/*— the end-to-end test projects (appsDir), one per plugin. Each hasimplicitDependencies: [<plugin>].docs/— VitePress site (pnpm start:docs).tools/scripts/— playground, local-registry, version-bump, and documentation scripts.tsconfig.base.jsondefines@nxext/*path aliases that resolve to each package'ssrc/index.ts.
Each plugin package follows the standard Nx plugin shape: generators.json, executors.json (with a separate builders/executors split for legacy compat — the compat files are the builders entries), migrations.json, src/generators/, src/executors/, and src/index.ts re-exporting public generator factories. Shared generator/AST/path utilities live in packages/common and should be reused instead of duplicated.
Build / test / lint a single plugin (target runs against the Nx project name, which matches the dir name):
pnpm build stencil # nx build stencil
pnpm test stencil # nx test stencil
pnpm lint stencil
pnpm e2e stencil-e2e # runs the e2e project, not the plugin
Run a single unit test file / test name (forwarded to Jest):
pnpm nx test stencil --testFile=some.spec.ts
pnpm nx test stencil -t "generates application"
Affected-only variants (what CI uses):
pnpm affected --target build lint test --exclude="tag:e2e"
Formatting / release / misc:
pnpm format # nx format:write — REQUIRED before pushing
pnpm nx release # conventional-commits-driven, per-package (see nx.json "release")
pnpm documentation # regenerates schema docs from generators/executors
There are two ways to exercise plugin changes locally; pick based on what you're doing:
-
Playground (interactive, for generator/executor smoke testing):
pnpm create-playground # builds all publishable libs, scaffolds tmp/nx-playground/proj pnpm update-playground # re-copies built dists into the existing playgroundPublishable libs are detected via
getPublishableLibNamesintools/scripts/utils.ts(criterion:projectType === 'library'ANDbuild.executor === '@nx/js:tsc'). The playground'spackage.jsonpoints@nxext/*devDependencies atfile:paths intodist/packages/*. -
Verdaccio local registry (matches what CI e2e does): each e2e project's
jest.config.tswiresglobalSetuptotools/scripts/start-local-registry.ts, which runsreleaseVersion({ specifier: '0.0.1-e2e' }),nx run-many -t build, andreleasePublish({ tag: 'e2e' })against thenxext:local-registryVerdaccio target (port 4873, storage intmp/local-registry/storage). E2e projects thenpnpm install @nxext/<name>@e2einto a freshly-scaffoldedtmp/nx-e2e/projworkspace viacreateTestProject/installPluginine2e/utils/index.ts. When writing new e2e specs, use these helpers rather than rolling your own scaffolding.
- Module boundaries and dependency checks are enforced by ESLint (
eslint.config.js):@nx/enforce-module-boundarieson TS/JS and@nx/dependency-checkson everypackage.json/project.json. If you add a runtime import from anotherpackages/*or an npm dep, also add it to that package'spackage.jsondependencies— otherwise lint fails. - Generator conventions: use
@nx/devkithelpers (generateFiles,names,offsetFromRoot,formatFiles,runTasksInSerial) anddetermineProjectNameAndRootOptions/ensureRootProjectNamefrom@nx/devkit/internalfor project name + root resolution. CallassertNotUsingTsSolutionSetup(from@nx/js/internal) where applicable. Don't hand-roll these. Since Nx 23,@nx/*packages no longer expose a./src/*deep-import wildcard — internal-but-still-needed symbols live under each package's/internalsubpath instead. - Release model:
nx.jsonsetsrelease.projects: ["packages/*"]withprojectsRelationship: "independent"andversion.conventionalCommits: true. Every plugin has its ownCHANGELOG.mdand versions independently — commit messages matter (usepnpm commit/ commitizen for the prompt-driven flow). - CI (
.github/workflows/ci.yml) runs via Nx Cloud with 3 agents and includes e2e (nx affected --target build lint test e2e, no exclude flag). Don't assume it's fast, though — e2e is the slowest target, so it's worth running locally first if you changed generator output.