diff --git a/packages/next/index.ts b/packages/next/index.ts
index 1e5bc580c9a338..c7077e633280ec 100644
--- a/packages/next/index.ts
+++ b/packages/next/index.ts
@@ -6,4 +6,4 @@ export { componentGenerator } from './src/generators/component/component';
 export { libraryGenerator } from './src/generators/library/library';
 export { pageGenerator } from './src/generators/page/page';
 export { withNx } from './plugins/with-nx';
-export { composePlugins } from './src/utils/config';
+export { composePlugins } from './src/utils/compose-plugins';
diff --git a/packages/next/plugins/with-nx.ts b/packages/next/plugins/with-nx.ts
index 101606427d16d3..5ab0a0f4a411d4 100644
--- a/packages/next/plugins/with-nx.ts
+++ b/packages/next/plugins/with-nx.ts
@@ -1,23 +1,14 @@
-import {
-  createProjectGraphAsync,
-  joinPathFragments,
-  offsetFromRoot,
-  parseTargetString,
-  ProjectGraph,
-  ProjectGraphProjectNode,
-  Target,
-  workspaceRoot,
-} from '@nx/devkit';
-import {
-  calculateProjectDependencies,
-  DependentBuildableProjectNode,
-} from '@nx/js/src/utils/buildable-libs-utils';
+/**
+ * WARNING: Do not add development dependencies to top-level imports.
+ * Instead, `require` them inline during the build phase.
+ */
+import * as path from 'path';
 import type { NextConfig } from 'next';
 import { PHASE_PRODUCTION_SERVER } from 'next/constants';
-
-import * as path from 'path';
-import { createWebpackConfig, NextConfigFn } from '../src/utils/config';
-import { NextBuildBuilderOptions } from '../src/utils/types';
+import type { NextConfigFn } from '../src/utils/config';
+import type { NextBuildBuilderOptions } from '../src/utils/types';
+import type { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils';
+import type { ProjectGraph, ProjectGraphProjectNode, Target } from '@nx/devkit';
 
 export interface WithNxOptions extends NextConfig {
   nx?: {
@@ -78,6 +69,7 @@ function getNxContext(
   targetName: string;
   configurationName?: string;
 } {
+  const { parseTargetString } = require('@nx/devkit');
   const targetConfig = getTargetConfig(graph, target);
 
   if (
@@ -119,7 +111,6 @@ function getNxContext(
     );
   }
 }
-
 /**
  * Try to read output dir from project, and default to '.next' if executing outside of Nx (e.g. dist is added to a docker image).
  */
@@ -130,22 +121,36 @@ async function determineDistDirForProdServer(
   const target = process.env.NX_TASK_TARGET_TARGET;
   const configuration = process.env.NX_TASK_TARGET_CONFIGURATION;
 
-  if (project && target) {
-    const originalTarget = { project, target, configuration };
-    const graph = await createProjectGraphAsync();
-
-    const { options, node: projectNode } = getNxContext(graph, originalTarget);
-    const outputDir = `${offsetFromRoot(projectNode.data.root)}${
-      options.outputPath
-    }`;
-    return nextConfig.distDir && nextConfig.distDir !== '.next'
-      ? joinPathFragments(outputDir, nextConfig.distDir)
-      : joinPathFragments(outputDir, '.next');
-  } else {
-    return '.next';
+  try {
+    if (project && target) {
+      // If NX env vars are set, then devkit must be available.
+      const {
+        createProjectGraphAsync,
+        joinPathFragments,
+        offsetFromRoot,
+      } = require('@nx/devkit');
+      const originalTarget = { project, target, configuration };
+      const graph = await createProjectGraphAsync();
+
+      const { options, node: projectNode } = getNxContext(
+        graph,
+        originalTarget
+      );
+      const outputDir = `${offsetFromRoot(projectNode.data.root)}${
+        options.outputPath
+      }`;
+      return nextConfig.distDir && nextConfig.distDir !== '.next'
+        ? joinPathFragments(outputDir, nextConfig.distDir)
+        : joinPathFragments(outputDir, '.next');
+    }
+  } catch {
+    // ignored -- fallback to Next.js default of '.next'
   }
+
+  return nextConfig.distDir || '.next';
 }
-export function withNx(
+
+function withNx(
   _nextConfig = {} as WithNxOptions,
   context: WithNxContext = getWithNxContext()
 ): NextConfigFn {
@@ -155,9 +160,16 @@ export function withNx(
       const { nx, ...validNextConfig } = _nextConfig;
       return {
         ...validNextConfig,
-        distDir: await determineDistDirForProdServer(validNextConfig),
+        distDir: await determineDistDirForProdServer(_nextConfig),
       };
     } else {
+      const {
+        createProjectGraphAsync,
+        joinPathFragments,
+        offsetFromRoot,
+        workspaceRoot,
+      } = require('@nx/devkit');
+
       // Otherwise, add in webpack and eslint configuration for build or test.
       let dependencies: DependentBuildableProjectNode[] = [];
 
@@ -179,6 +191,9 @@ export function withNx(
       const projectDirectory = projectNode.data.root;
 
       if (options.buildLibsFromSource === false && targetName) {
+        const {
+          calculateProjectDependencies,
+        } = require('@nx/js/src/utils/buildable-libs-utils');
         const result = calculateProjectDependencies(
           graph,
           workspaceRoot,
@@ -202,6 +217,7 @@ export function withNx(
 
       const userWebpackConfig = nextConfig.webpack;
 
+      const { createWebpackConfig } = require('../src/utils/config');
       nextConfig.webpack = (a, b) =>
         createWebpackConfig(
           workspaceRoot,
@@ -407,3 +423,5 @@ module.exports = withNx;
 // Support for newer generated code: `const { withNx } = require(...);`
 module.exports.withNx = withNx;
 module.exports.getNextConfig = getNextConfig;
+
+export { withNx };
diff --git a/packages/next/src/executors/build/lib/create-next-config-file.spec.ts b/packages/next/src/executors/build/lib/create-next-config-file.spec.ts
new file mode 100644
index 00000000000000..8863565c3c2c02
--- /dev/null
+++ b/packages/next/src/executors/build/lib/create-next-config-file.spec.ts
@@ -0,0 +1,59 @@
+import { getWithNxContent } from './create-next-config-file';
+import { stripIndents } from '@nx/devkit';
+
+describe('Next.js config: getWithNxContent', () => {
+  it('should swap distDir and getWithNxContext with static values', () => {
+    const result = getWithNxContent({
+      withNxFile: `with-nx.js`,
+      withNxContent: stripIndents`
+      // SHOULD BE LEFT INTACT
+      const constants = require("next/constants"); 
+      
+      // TO BE SWAPPED
+      function getWithNxContext() {
+        const { workspaceRoot, workspaceLayout } = require('@nx/devkit');
+        return {
+            workspaceRoot,
+            libsDir: workspaceLayout().libsDir,
+        };
+      }
+      
+      // SHOULD BE LEFT INTACT
+      function withNx(nextConfig = {}, context = getWithNxContext()) {
+        return (phase) => {
+          if (phase === constants.PHASE_PRODUCTION_SERVER) {
+            //...
+          } else {
+           // ...
+          }
+        };
+      }
+      
+      // SHOULD BE LEFT INTACT
+      module.exports.withNx = withNx;
+      `,
+    });
+
+    expect(result).toContain(`const constants = require("next/constants")`);
+    expect(result).toContain(stripIndents`
+      // SHOULD BE LEFT INTACT
+      function withNx(nextConfig = {}, context = getWithNxContext()) {
+        return (phase) => {
+          if (phase === constants.PHASE_PRODUCTION_SERVER) {
+            //...
+          } else {
+           // ...
+          }
+        };
+      }
+      
+      // SHOULD BE LEFT INTACT
+      module.exports.withNx = withNx;
+    `);
+    expect(result).not.toContain(
+      `const { workspaceRoot, workspaceLayout } = require('@nx/devkit');`
+    );
+    expect(result).toContain(`libsDir: ''`);
+    expect(result).not.toContain(`libsDir: workspaceLayout.libsDir()`);
+  });
+});
diff --git a/packages/next/src/executors/build/lib/create-next-config-file.ts b/packages/next/src/executors/build/lib/create-next-config-file.ts
index 6c9b693a068822..561126e3d9499f 100644
--- a/packages/next/src/executors/build/lib/create-next-config-file.ts
+++ b/packages/next/src/executors/build/lib/create-next-config-file.ts
@@ -1,9 +1,23 @@
-import { ExecutorContext } from '@nx/devkit';
-
-import { copyFileSync, existsSync } from 'fs';
+import type { ExecutorContext } from '@nx/devkit';
+import {
+  applyChangesToString,
+  ChangeType,
+  stripIndents,
+  workspaceLayout,
+  workspaceRoot,
+} from '@nx/devkit';
+import * as ts from 'typescript';
+import {
+  copyFileSync,
+  existsSync,
+  mkdirSync,
+  readFileSync,
+  writeFileSync,
+} from 'fs';
 import { join } from 'path';
 
 import type { NextBuildBuilderOptions } from '../../../utils/types';
+import { findNodes } from 'nx/src/utils/typescript';
 
 export function createNextConfigFile(
   options: NextBuildBuilderOptions,
@@ -13,7 +27,77 @@ export function createNextConfigFile(
     ? join(context.root, options.nextConfig)
     : join(context.root, options.root, 'next.config.js');
 
+  // Copy config file and our `.nx-helpers` folder to remove dependency on @nrwl/next for production build.
   if (existsSync(nextConfigPath)) {
-    copyFileSync(nextConfigPath, join(options.outputPath, 'next.config.js'));
+    const helpersPath = join(options.outputPath, '.nx-helpers');
+    mkdirSync(helpersPath, { recursive: true });
+    copyFileSync(
+      join(__dirname, '../../../utils/compose-plugins.js'),
+      join(helpersPath, 'compose-plugins.js')
+    );
+    writeFileSync(join(helpersPath, 'with-nx.js'), getWithNxContent());
+    writeFileSync(
+      join(helpersPath, 'compiled.js'),
+      `
+        const withNx = require('./with-nx');
+        module.exports = withNx;
+        module.exports.withNx = withNx;
+        module.exports.composePlugins = require('./compose-plugins').composePlugins;
+      `
+    );
+    writeFileSync(
+      join(options.outputPath, 'next.config.js'),
+      readFileSync(nextConfigPath)
+        .toString()
+        .replace(/["']@nx\/next["']/, `'./.nx-helpers/compiled.js'`)
+        // TODO(v17): Remove this once users have all migrated to new @nx scope and import from '@nx/next' not the deep import paths.
+        .replace('@nx/next/plugins/with-nx', './.nx-helpers/compiled.js')
+        .replace('@nrwl/next/plugins/with-nx', './.nx-helpers/compiled.js')
+    );
+  }
+}
+function readSource() {
+  const withNxFile = join(__dirname, '../../../../plugins/with-nx.js');
+  const withNxContent = readFileSync(withNxFile).toString();
+  return {
+    withNxFile,
+    withNxContent,
+  };
+}
+
+// Exported for testing
+export function getWithNxContent({ withNxFile, withNxContent } = readSource()) {
+  const withNxSource = ts.createSourceFile(
+    withNxFile,
+    withNxContent,
+    ts.ScriptTarget.Latest,
+    true
+  );
+  const getWithNxContextDeclaration = findNodes(
+    withNxSource,
+    ts.SyntaxKind.FunctionDeclaration
+  )?.find(
+    (node: ts.FunctionDeclaration) => node.name?.text === 'getWithNxContext'
+  );
+  if (getWithNxContextDeclaration) {
+    withNxContent = applyChangesToString(withNxContent, [
+      {
+        type: ChangeType.Delete,
+        start: getWithNxContextDeclaration.getStart(withNxSource),
+        length: getWithNxContextDeclaration.getWidth(withNxSource),
+      },
+      {
+        type: ChangeType.Insert,
+        index: getWithNxContextDeclaration.getStart(withNxSource),
+        text: stripIndents`function getWithNxContext() {
+          return {
+            workspaceRoot: '${workspaceRoot}',
+            libsDir: '${workspaceLayout().libsDir}'
+          }
+        }`,
+      },
+    ]);
   }
+
+  return withNxContent;
 }
diff --git a/packages/next/src/generators/application/files/common/next.config.js__tmpl__ b/packages/next/src/generators/application/files/common/next.config.js__tmpl__
index 82dd31149f8ed8..3b589f48df9785 100644
--- a/packages/next/src/generators/application/files/common/next.config.js__tmpl__
+++ b/packages/next/src/generators/application/files/common/next.config.js__tmpl__
@@ -30,7 +30,7 @@ const plugins = [
   withNx,
 ];
 
-module.exports = composePlugins(...plugins)(nextConfig));
+module.exports = composePlugins(...plugins)(nextConfig);
 <% } else if (style === 'styl') { %>
 const { withStylus } = require('@nx/next/plugins/with-stylus');
 
diff --git a/packages/next/src/utils/compose-plugins.spec.ts b/packages/next/src/utils/compose-plugins.spec.ts
new file mode 100644
index 00000000000000..67fdddc6e222a7
--- /dev/null
+++ b/packages/next/src/utils/compose-plugins.spec.ts
@@ -0,0 +1,58 @@
+import { NextConfig } from 'next';
+import { composePlugins, NextConfigFn } from './compose-plugins';
+
+describe('composePlugins', () => {
+  it('should combine multiple plugins', async () => {
+    const nextConfig: NextConfig = {
+      env: {
+        original: 'original',
+      },
+    };
+    const a = (config: NextConfig): NextConfig => {
+      config.env['a'] = 'a';
+      return config;
+    };
+    const b = (config: NextConfig): NextConfig => {
+      config.env['b'] = 'b';
+      return config;
+    };
+    const fn = await composePlugins(a, b);
+    const output = await fn(nextConfig)('test', {});
+
+    expect(output).toEqual({
+      env: {
+        original: 'original',
+        a: 'a',
+        b: 'b',
+      },
+    });
+  });
+
+  it('should compose plugins that return an async function', async () => {
+    const nextConfig: NextConfig = {
+      env: {
+        original: 'original',
+      },
+    };
+    const a = (config: NextConfig): NextConfig => {
+      config.env['a'] = 'a';
+      return config;
+    };
+    const b = (config: NextConfig): NextConfigFn => {
+      return (phase: string) => {
+        config.env['b'] = phase;
+        return config;
+      };
+    };
+    const fn = await composePlugins(a, b);
+    const output = await fn(nextConfig)('test', {});
+
+    expect(output).toEqual({
+      env: {
+        original: 'original',
+        a: 'a',
+        b: 'test',
+      },
+    });
+  });
+});
diff --git a/packages/next/src/utils/compose-plugins.ts b/packages/next/src/utils/compose-plugins.ts
new file mode 100644
index 00000000000000..6a7b91832641ea
--- /dev/null
+++ b/packages/next/src/utils/compose-plugins.ts
@@ -0,0 +1,30 @@
+import type { NextConfig } from 'next';
+import type {
+  NextConfigFn,
+  NextPlugin,
+  NextPluginThatReturnsConfigFn,
+} from './config';
+
+export function composePlugins(
+  ...plugins: (NextPlugin | NextPluginThatReturnsConfigFn)[]
+): (baseConfig: NextConfig) => NextConfigFn {
+  return function (baseConfig: NextConfig) {
+    return async function combined(
+      phase: string,
+      context: any
+    ): Promise<NextConfig> {
+      let config = baseConfig;
+      for (const plugin of plugins) {
+        const fn = await plugin;
+        const configOrFn = fn(config);
+        if (typeof configOrFn === 'function') {
+          config = await configOrFn(phase, context);
+        } else {
+          config = configOrFn;
+        }
+      }
+
+      return config;
+    };
+  };
+}
diff --git a/packages/next/src/utils/config.spec.ts b/packages/next/src/utils/config.spec.ts
index 350fb5972e6475..05bd152e39c8fd 100644
--- a/packages/next/src/utils/config.spec.ts
+++ b/packages/next/src/utils/config.spec.ts
@@ -1,7 +1,6 @@
-import type { NextConfig } from 'next';
 import 'nx/src/utils/testing/mock-fs';
-import { composePlugins, createWebpackConfig, NextConfigFn } from './config';
 import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
+import { createWebpackConfig } from './config';
 
 jest.mock('@nx/webpack', () => ({}));
 jest.mock('tsconfig-paths-webpack-plugin');
@@ -76,60 +75,4 @@ describe('Next.js webpack config builder', () => {
       expect(config.module.rules.length).toBe(2);
     });
   });
-
-  describe('composePlugins', () => {
-    it('should combine multiple plugins', async () => {
-      const nextConfig: NextConfig = {
-        env: {
-          original: 'original',
-        },
-      };
-      const a = (config: NextConfig): NextConfig => {
-        config.env['a'] = 'a';
-        return config;
-      };
-      const b = (config: NextConfig): NextConfig => {
-        config.env['b'] = 'b';
-        return config;
-      };
-      const fn = await composePlugins(a, b);
-      const output = await fn(nextConfig)('test', {});
-
-      expect(output).toEqual({
-        env: {
-          original: 'original',
-          a: 'a',
-          b: 'b',
-        },
-      });
-    });
-
-    it('should compose plugins that return an async function', async () => {
-      const nextConfig: NextConfig = {
-        env: {
-          original: 'original',
-        },
-      };
-      const a = (config: NextConfig): NextConfig => {
-        config.env['a'] = 'a';
-        return config;
-      };
-      const b = (config: NextConfig): NextConfigFn => {
-        return (phase: string) => {
-          config.env['b'] = phase;
-          return config;
-        };
-      };
-      const fn = await composePlugins(a, b);
-      const output = await fn(nextConfig)('test', {});
-
-      expect(output).toEqual({
-        env: {
-          original: 'original',
-          a: 'a',
-          b: 'test',
-        },
-      });
-    });
-  });
 });
diff --git a/packages/next/src/utils/config.ts b/packages/next/src/utils/config.ts
index 2d9f4fa7b2d3c9..b1be952f4d079b 100644
--- a/packages/next/src/utils/config.ts
+++ b/packages/next/src/utils/config.ts
@@ -8,7 +8,18 @@ import {
   createTmpTsConfig,
   DependentBuildableProjectNode,
 } from '@nx/js/src/utils/buildable-libs-utils';
-import { NxWebpackExecutionContext } from '@nx/webpack';
+
+export interface NextConfigFn {
+  (phase: string, context?: any): Promise<NextConfig> | NextConfig;
+}
+
+export interface NextPlugin {
+  (config: NextConfig): NextConfig;
+}
+
+export interface NextPluginThatReturnsConfigFn {
+  (config: NextConfig): NextConfigFn;
+}
 
 export function createWebpackConfig(
   workspaceRoot: string,
@@ -96,39 +107,3 @@ function isTsRule(r: RuleSetRule): boolean {
 
   return r.test.test('a.ts');
 }
-
-export interface NextConfigFn {
-  (phase: string, context?: any): Promise<NextConfig> | NextConfig;
-}
-
-export interface NextPlugin {
-  (config: NextConfig): NextConfig;
-}
-
-export interface NextPluginThatReturnsConfigFn {
-  (config: NextConfig): NextConfigFn;
-}
-
-export function composePlugins(
-  ...plugins: (NextPlugin | NextPluginThatReturnsConfigFn)[]
-): (baseConfig: NextConfig) => NextConfigFn {
-  return function (baseConfig: NextConfig) {
-    return async function combined(
-      phase: string,
-      context: any
-    ): Promise<NextConfig> {
-      let config = baseConfig;
-      for (const plugin of plugins) {
-        const fn = await plugin;
-        const configOrFn = fn(config);
-        if (typeof configOrFn === 'function') {
-          config = await configOrFn(phase, context);
-        } else {
-          config = configOrFn;
-        }
-      }
-
-      return config;
-    };
-  };
-}