Nx Import
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.
- Skill ID
- nrwl/nx/nx-import
- Publisher
- nrwl
- Repository
- nx
- Installs
- 0
- Files
- 7
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
nrwl/nx/nx-importInstalls these files- SKILL.md
- references/ESLINT.md
- references/GRADLE.md
- references/JEST.md
- references/NEXT.md
- references/TURBOREPO.md
- references/VITE.md
What this skill tells the agent
Quick Start
nx importbrings code from a source repository or folder into the current workspace, preserving commit history.- After nx
22.6.0,nx importresponds with .ndjson outputs and follow-up questions. For earlier versions, always run with--no-interactiveand specify all flags directly. - Run
nx import --helpfor available options. - Make sure the destination directory is empty before importing. EXAMPLE: target has
libs/utilsandlibs/models; source haslibs/uiandlibs/data-access— you cannot importlibs/intolibs/directly. Import each source library individually.
Primary docs:
- https://nx.dev/docs/guides/adopting-nx/import-project
- https://nx.dev/docs/guides/adopting-nx/preserving-git-histories
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.
imported-apps/), then rename
Whole repo (nx import <source> imported --source=.):
- Only for non-monorepo sources (single-project repos)
- For monorepos, creates messy nested config (
imported/nx.json,imported/tsconfig.base.json, etc.) - If you must: keep imported
tsconfig.base.json(projects extend it), prefix workspace globs and executor paths
Directory Conventions
- Always prefer the destination's existing conventions. Source uses
libs/but dest usespackages/? Import intopackages/(nx import <source> packages/foo --source=libs/foo). - If dest has no convention (empty workspace), ask the user.
Application vs Library Detection
Before importing, identify whether the source is an application or a library:
- Applications: Deployable end products. Common indicators:
- _Frontend_:
next.config.*,vite.config.*with a build entry point, framework-specific app scaffolding (CRA, Angular CLI app, etc.) - _Backend (Node.js)_: Express/Fastify/NestJS server entrypoint, no
"exports"field inpackage.json - _JVM_: Maven
pom.xmlwith<packaging>jar</packaging>or<packaging>war</packaging>and amainclass; Gradleapplicationplugin ormainClasssetting - _.NET_:
.csproj/.fsprojwith<OutputType>Exe</OutputType>or<OutputType>WinExe</OutputType> - _General_: Dockerfile, a runnable entrypoint, no public API surface intended for import by other projects
- Libraries: Reusable packages consumed by other projects. Common indicators:
"main"/"exports"inpackage.json, Maven/Gradle packaging as a library jar, .NET<OutputType>Library</OutputType>, named exports intended for import by other packages.
Destination directory rules:
- Applications →
apps/<name>. Check workspace globs (e.g.pnpm-workspace.yaml,workspacesin rootpackage.json) for an existingapps/*entry. - If
apps/*is not present, add it before importing: update the workspace glob config and commit (or stage) the change. - Example:
nx import <source> apps/my-app --source=packages/my-app - Libraries → follow the dest's existing convention (
packages/,libs/, etc.).
Common Issues
pnpm Workspace Globs (Critical)
nx import adds the imported directory itself (e.g. apps) to pnpm-workspace.yaml, NOT glob patterns for packages within it. Cross-package imports will fail with Cannot find module.
Fix: Replace with proper globs from the source config (e.g. apps/*, libs/shared/*), then pnpm install.
Root Dependencies and Config Not Imported (Critical)
nx import does NOT merge from the source's root:
dependencies/devDependenciesfrompackage.jsontargetDefaultsfromnx.json(e.g."@nx/esbuild:esbuild": { "dependsOn": ["^build"] }— critical for build ordering)namedInputsfromnx.json(e.g.productionexclusion patterns for test files)- Plugin configurations from
nx.json
Fix: Diff source and dest package.json + nx.json. Add missing deps, merge relevant targetDefaults and namedInputs.
TypeScript Project References
After import, run nx sync --yes. If it reports nothing but typecheck still fails, nx reset first, then nx sync --yes again.
Explicit Executor Path Fixups
Inferred targets (via Nx plugins) resolve config relative to project root — no changes needed. Explicit executor targets (e.g. @nx/esbuild:esbuild) have workspace-root-relative paths (main, outputPath, tsConfig, assets, sourceRoot) that must be prefixed with the import destination directory.
Plugin Detection
- Whole-repo import:
nx importdetects and offers to install plugins. Accept them. - Subdirectory import: Plugins NOT auto-detected. Manually add with
npx nx add @nx/PLUGIN. Checkinclude/excludepatterns — defaults won't match alternate directories (e.g.apps-beta/). - Run
npx nx resetafter any plugin config changes.
Redundant Root Files (Whole-Repo Only)
Whole-repo import brings ALL source root files into the dest subdirectory. Clean up:
pnpm-lock.yaml— stale; dest has its own lockfilepnpm-workspace.yaml— source workspace config; conflicts with destnode_modules/— stale symlinks pointing to source filesystem.gitignore— redundant with dest root.gitignorenx.json— source Nx config; dest has its ownREADME.md— optional; keep or remove
Don't blindly delete tsconfig.base.json — imported projects may extend it via relative paths.
Root ESLint Config Missing (Subdirectory Import)
Subdirectory import doesn't bring the source's root eslint.config.mjs, but project configs reference ../../eslint.config.mjs.
Fix order:
- Install ESLint deps first:
pnpm add -wD eslint@^9 @nx/eslint-plugin typescript-eslint(plus framework-specific plugins) - Create root
eslint.config.mjs(copy from source or create with@nx/eslint-pluginbase rules) - Then
npx nx add @nx/eslintto register the plugin innx.json
Install typescript-eslint explicitly — pnpm's strict hoisting won't auto-resolve this transitive dep of @nx/eslint-plugin.
ESLint Version Pinning (Critical)
Pin ESLint to v9 (eslint@^9.0.0). ESLint 10 breaks @nx/eslint and many plugins with cryptic errors like Cannot read properties of undefined (reading 'version').
@nx/eslint may peer-depend on ESLint 8, causing the wrong version to resolve. If lint fails with Cannot read properties of undefined (reading 'allow'), add pnpm.overrides:
{ "pnpm": { "overrides": { "eslint": "^9.0.0" } } }Dependency Version Conflicts
After import, compare key deps (typescript, eslint, 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 pnpm.overrides to enforce single-version policy if desired.
Module Boundaries
Imported projects may lack tags. Add tags or update @nx/enforce-module-boundaries rules.
Project Name Collisions (Multi-Import)
Same name in package.json across source and dest causes MultipleProjectsWithSameNameError. Fix: Rename conflicting names (e.g. @org/api → @org/teama-api), update all dep references and import statements, pnpm install. The root package.json of each imported repo also becomes a project — rename those too.
Workspace Dep Import Ordering
pnpm install fails during nx import if a "workspace:*" dependency hasn't been imported yet. File operations still succeed. Fix: Import all projects first, then pnpm install --no-frozen-lockfile.
.gitkeep Blocking Subdirectory Import
The TS preset creates packages/.gitkeep. Remove it and commit before importing.
More from nrwl
Use this skill in a project
Open any RiverX project, search the Skills panel for nrwl/nx/nx-import, and install it in one click.
