name: nx-import
description: Import, merge, or combine repositories into an Nx workspace using nx import. USE WHEN the user asks to adopt Nx across repos, move projects into a monorepo, or bring code/history from another repository.
Quick Start
- brings code from a source repository or folder into the current workspace, preserving commit history.
- After nx , responds with .ndjson outputs and follow-up questions. For earlier versions, always run with and specify all flags directly.
- Run for available options.
- Make sure the destination directory is empty before importing.
EXAMPLE: target has and ; source has and — you cannot import into directly. Import each source library individually.
Primary docs:
Read the nx docs if you have the tools for it.
Import Strategy
Subdirectory-at-a-time (
nx import <source> apps --source=apps
):
- Recommended for monorepo sources — files land at top level, no redundant config
- Caveats: multiple import commands (separate merge commits each); dest must not have conflicting directories; root configs (deps, plugins, targetDefaults) not imported
- Directory conflicts: Import into alternate-named dir (e.g. ), then rename
Whole repo (
nx import <source> imported --source=.
):
- Only for non-monorepo sources (single-project repos)
- For monorepos, creates messy nested config (,
imported/tsconfig.base.json
, etc.)
- If you must: keep imported (projects extend it), prefix workspace globs and executor paths
Directory Conventions
- Always prefer the destination's existing conventions. Source uses but dest uses ? Import into (
nx import <source> packages/foo --source=libs/foo
).
- If dest has no convention (empty workspace), ask the user.
Common Issues
pnpm Workspace Globs (Critical)
adds the imported directory itself (e.g.
) to
,
NOT glob patterns for packages within it. Cross-package imports will fail with
.
Fix: Replace with proper globs from the source config (e.g.
,
), then
.
Root Dependencies and Config Not Imported (Critical)
does
NOT merge from the source's root:
- / from
- from (e.g.
"@nx/esbuild:esbuild": { "dependsOn": ["^build"] }
— critical for build ordering)
- from (e.g. exclusion patterns for test files)
- Plugin configurations from
Fix: Diff source and dest
+
. Add missing deps, merge relevant
and
.
TypeScript Project References
After import, run
. If it reports nothing but typecheck still fails,
first, then
again.
Explicit Executor Path Fixups
Inferred targets (via Nx plugins) resolve config relative to project root — no changes needed. Explicit executor targets (e.g.
) have workspace-root-relative paths (
,
,
,
,
) that must be prefixed with the import destination directory.
Plugin Detection
- Whole-repo import: detects and offers to install plugins. Accept them.
- Subdirectory import: Plugins NOT auto-detected. Manually add with . Check / patterns — defaults won't match alternate directories (e.g. ).
- Run after any plugin config changes.
Redundant Root Files (Whole-Repo Only)
Whole-repo import brings ALL source root files into the dest subdirectory. Clean up:
- — stale; dest has its own lockfile
- — source workspace config; conflicts with dest
- — stale symlinks pointing to source filesystem
- — redundant with dest root
- — source Nx config; dest has its own
- — optional; keep or remove
Don't blindly delete — imported projects may extend it via relative paths.
Root ESLint Config Missing (Subdirectory Import)
Subdirectory import doesn't bring the source's root
, but project configs reference
.
Fix order:
- Install ESLint deps first:
pnpm add -wD eslint@^9 @nx/eslint-plugin typescript-eslint
(plus framework-specific plugins)
- Create root (copy from source or create with base rules)
- Then to register the plugin in
Install
explicitly — pnpm's strict hoisting won't auto-resolve this transitive dep of
.
ESLint Version Pinning (Critical)
Pin ESLint to v9 (
). ESLint 10 breaks
and many plugins with cryptic errors like
Cannot read properties of undefined (reading 'version')
.
may peer-depend on ESLint 8, causing the wrong version to resolve. If lint fails with
Cannot read properties of undefined (reading 'allow')
, add
:
json
{ "pnpm": { "overrides": { "eslint": "^9.0.0" } } }
Dependency Version Conflicts
After import, compare key deps (
,
, framework-specific). If dest uses newer versions, upgrade imported packages to match (usually safe). If source is newer, may need to upgrade dest first. Use
to enforce single-version policy if desired.
Module Boundaries
Imported projects may lack
. Add tags or update
@nx/enforce-module-boundaries
rules.
Project Name Collisions (Multi-Import)
Same
in
across source and dest causes
MultipleProjectsWithSameNameError
.
Fix: Rename conflicting names (e.g.
→
), update all dep references and import statements,
. The root
of each imported repo also becomes a project — rename those too.
Workspace Dep Import Ordering
fails during
if a
dependency hasn't been imported yet. File operations still succeed.
Fix: Import all projects first, then
pnpm install --no-frozen-lockfile
.
Blocking Subdirectory Import
The TS preset creates
. Remove it and commit before importing.
Frontend tsconfig Base Settings (Critical)
The TS preset defaults (
,
moduleResolution: "nodenext"
,
) are incompatible with frontend frameworks (React, Next.js, Vue, Vite). After importing frontend projects, verify the dest root
:
- : Must be (not )
- : Must be (not )
- : Must include and (frontend projects need these)
- : for React-only workspaces, per-project for mixed frameworks
For
subdirectory imports, the dest root tsconfig is authoritative — update it. For
whole-repo imports, imported projects may extend their own nested
, making this less critical.
If the dest also has backend projects needing
, use per-project overrides instead of changing the root.
Gotcha: TypeScript does NOT merge
arrays — a project-level override
replaces the base array entirely. Always include all needed entries (e.g.
,
,
) in any project-level
.
Typings for Libraries
React libraries generated with
reference
@nx/react/typings/cssmodule.d.ts
and
@nx/react/typings/image.d.ts
in their tsconfig
. These fail with
Cannot find type definition file
unless
is installed in the dest workspace.
Jest Preset Missing (Subdirectory Import)
Nx presets create
at the workspace root, and project jest configs reference it (e.g.
). Subdirectory import does NOT bring this file.
Fix:
- Run — registers in and updates
- Create at workspace root (see for content) — only creates this when a generator runs, not on bare
- Install test runner deps:
pnpm add -wD jest jest-environment-jsdom ts-jest @types/jest
- Install framework-specific test deps as needed (see )
For deeper Jest issues (tsconfig.spec.json, Babel transforms, CI atomization, Jest vs Vitest coexistence), see
.
Target Name Prefixing (Whole-Repo Import)
When importing a project with existing npm scripts (
,
,
,
), Nx plugins auto-prefix inferred target names to avoid conflicts: e.g.
,
,
.
Fix: Remove the Nx-rewritten npm scripts from the imported
, then either:
- Accept the prefixed names (e.g. )
- Rename plugin target names in to use unprefixed names
Non-Nx Source Issues
When the source is a plain pnpm/npm workspace without
.
npm Script Rewriting (Critical)
Nx rewrites
scripts during init, creating broken commands (e.g.
→
).
Fix: Remove all rewritten scripts — Nx plugins infer targets from config files.
→ + (Critical)
Plain TS projects use
, incompatible with Nx project references.
Symptoms: "typecheck target is disabled because one or more project references set 'noEmit: true'" or TS6310.
Fix in all imported tsconfigs:
- Remove . If inherited via extends chain, set explicitly.
- Add ,
"emitDeclarationOnly": true
,
- Add and
"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo"
- Add
"extends": "../../tsconfig.base.json"
if missing. Remove settings now inherited from base.
Stale node_modules and Lockfiles
may bring
(pnpm symlinks pointing to the source filesystem) and
from the source. Both are stale.
Fix:
rm -rf imported/node_modules imported/pnpm-lock.yaml imported/pnpm-workspace.yaml imported/.gitignore
, then
.
ESLint Config Handling
- Legacy (ESLint 8): Delete all , remove v8 deps, create flat .
- Flat config (): Self-contained configs can often be left as-is.
- No ESLint: Create both root and project-level configs from scratch.
TypeScript Aliases
Nx uses
+ pnpm workspace linking instead of tsconfig
. If packages have proper
, paths are redundant. Otherwise, update paths for the new directory structure.
Technology-specific Guidance
Identify technologies in the source repo, then read and apply the matching reference file(s).
Available references:
- — Jest testing: setup, jest.preset.js, testing deps by framework, tsconfig.spec.json, Jest vs Vitest coexistence, Babel transforms, CI atomization.
- — Next.js projects: targets, , Next.js TS config (, ), auto-installing deps via wrong PM, non-Nx imports, mixed Next.js+Vite coexistence.
- — Vite projects (React, Vue, or both): typecheck target, / fixes, framework deps, Vue-specific setup, mixed React+Vue coexistence.