---
title: "Codemod Transformations"
description: "Codemod transformations automate the upgrade process for Next.js applications by programmatically modifying source code, configuration files, and project structures across major version boundaries...."
last_updated: "2026-09-23T10:52:03.135025+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/ecosystem-packages/codemod-transformations"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/next-codemod/transforms/new-link.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/new-link.ts)
- [packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts)
- [packages/next-codemod/bin/transform.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts)
- [packages/next-codemod/transforms/url-to-withrouter.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/url-to-withrouter.ts)
- [packages/next-codemod/transforms/next-image-experimental.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-image-experimental.ts)
- [packages/next-codemod/bin/upgrade.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/upgrade.ts)
- [packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts)
- [packages/next-codemod/transforms/next-image-to-legacy-image.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-image-to-legacy-image.ts)
- [packages/next-codemod/transforms/remove-unstable-prefix.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/remove-unstable-prefix.ts)
- [packages/next-codemod/transforms/middleware-to-proxy.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/middleware-to-proxy.ts)
- [packages/next-codemod/transforms/next-lint-to-eslint-cli.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-lint-to-eslint-cli.ts)
- [packages/next-codemod/transforms/cra-to-next.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/cra-to-next.ts)
- [packages/next-codemod/transforms/metadata-to-viewport-export.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/metadata-to-viewport-export.ts)
- [packages/next-codemod/transforms/next-og-import.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-og-import.ts)
- [packages/next-codemod/lib/utils.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/utils.ts)
- [packages/next-codemod/transforms/built-in-next-font.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/built-in-next-font.ts)
- [packages/next-codemod/transforms/next-async-request-api.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-async-request-api.ts)
- [packages/next-codemod/lib/cra-to-next/index-to-component.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/cra-to-next/index-to-component.ts)
- [packages/next-codemod/transforms/name-default-component.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/name-default-component.ts)
- [packages/next-codemod/transforms/remove-experimental-ppr.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/remove-experimental-ppr.ts)
- [packages/next-codemod/transforms/lib/async-request-api/index.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/index.ts)
- [packages/next-codemod/transforms/__testfixtures__/next-request-geo-ip/skip-empty-ast.input.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/__testfixtures__/next-request-geo-ip/skip-empty-ast.input.ts)
- [packages/next-codemod/transforms/add-missing-react-import.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/add-missing-react-import.ts)
- [packages/next-codemod/bin/next-codemod.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/next-codemod.ts)
- [packages/next-codemod/transforms/app-dir-runtime-config-experimental-edge.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/app-dir-runtime-config-experimental-edge.ts)
- [packages/next-codemod/transforms/__testfixtures__/next-request-geo-ip/skip-empty-ast.output.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/__testfixtures__/next-request-geo-ip/skip-empty-ast.output.ts)
</details>

## Overview

Codemod transformations automate the upgrade process for Next.js applications by programmatically modifying source code, configuration files, and project structures across major version boundaries. These transformations address breaking changes, API deprecations, and architectural shifts—such as adopting asynchronous request APIs, migrating bundlers, and updating component conventions—thereby reducing manual refactoring overhead and ensuring compatibility with newer Next.js releases.

Sources: [packages/next-codemod/bin/transform.ts:1-240](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts#L1-L240), [packages/next-codemod/bin/upgrade.ts:409-635](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/upgrade.ts#L409-L635)

## CLI Architecture and Upgrade Orchestration

### Overview

The `@next/codemod` command-line interface provides a unified execution environment for running individual AST transformations and orchestrating automated multi-step project upgrades. Built on top of Commander, the entry point dispatches commands to specialized modules, ensuring proper positional option parsing, interactive prompts via `prompts`, and git safety validation prior to file modification.

Sources: [packages/next-codemod/bin/next-codemod.ts:1-105](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/next-codemod.ts#L1-L105), [packages/next-codemod/bin/transform.ts:1-11](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts#L1-L11)

### CLI Execution Model and Git Hygiene

Before any transformation writes changes to disk, `checkGitStatus` inspects the working directory using `isGitClean.sync(process.cwd())`. If uncommitted changes exist, the execution halts and exits with code `1` unless the `--force` flag is supplied.

```
checkGitStatus(force) → isGitClean.sync(cwd) ──(clean)──► execute transform
                                            └──(dirty)─► exit(1) [or bypass if force]
```

Sources: [packages/next-codemod/bin/transform.ts:33-35](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts#L33-L35), [packages/next-codemod/lib/utils.ts:4-32](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/utils.ts#L4-L32)

> [!CAUTION]
> Running codemods without a clean git directory or without passing `--force` terminates execution immediately. If the execution environment is not recognized as a git repository, `checkGitStatus` catches the error and treats the workspace as clean.

Sources: [packages/next-codemod/lib/utils.ts:10-14](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/utils.ts#L10-L14)

### Interactive Upgrade Workflow and Options

When invoking `runTransform` or `suggestCodemods`, the CLI interacts with users through prompts to select transformation targets, define file paths, and filter applicable codemods based on version differentials.

| Option / Flag | Type / Default | Purpose |
| :--- | :--- | :--- |
| `-f, --force` | Boolean (`false`) | Bypass Git safety checks and forcibly run codemods |
| `-d, --dry` | Boolean (`false`) | Dry run mode where no changes are written to files |
| `-p, --print` | Boolean (`false`) | Print transformed files to stdout for debugging |
| `--verbose` | Boolean (`false`) | Show detailed information about the transformation process |
| `-j, --jscodeshift` | Array / String | Pass raw options directly down to the underlying `jscodeshift` runner |

Sources: [packages/next-codemod/bin/next-codemod.ts:36-46](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/next-codemod.ts#L36-L46), [packages/next-codemod/bin/transform.ts:123-148](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts#L123-L148)

### JSCodeshift Runner Dispatch

Once files are expanded via `globby` and validation succeeds, `runTransform` constructs argument arrays for `jscodeshift`. Special transforms such as `cra-to-next` and `next-lint-to-eslint-cli` bypass `jscodeshift` entirely and invoke their default export functions directly with the expanded file paths and options.

```typescript
  const transformerPath = join(transformerDirectory, `${transformer}.js`)

  if (transformer === 'cra-to-next') {
    return require(transformerPath).default(filesExpanded, options)
  }

  if (transformer === 'next-lint-to-eslint-cli') {
    return require(transformerPath).default(filesExpanded, options)
  }
```

Sources: [packages/next-codemod/bin/transform.ts:102-120](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts#L102-L120)

For standard AST transforms, arguments configure parser options, ignore patterns, extensions, and the target transformer path before dispatching via `execa`.

```typescript
  let args = []

  const { dry, print, runInBand, jscodeshift, verbose } = options

  if (dry) {
    args.push('--dry')
  }
  if (print) {
    args.push('--print')
  }
  if (runInBand) {
    args.push('--run-in-band')
  }
  if (verbose) {
    args.push('--verbose=2')
  }
  args.push('--parser=tsx')
  args.push('--ignore-pattern=**/node_modules/**')
  args.push('--ignore-pattern=**/.next/**')
  args.push('--extensions=tsx,ts,jsx,js')
  args = args.concat(['--transform', transformerPath])

  if (jscodeshift) {
    args = args.concat(jscodeshift)
  }

  args = args.concat(filesExpanded)
```

Sources: [packages/next-codemod/bin/transform.ts:121-151](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/transform.ts#L121-L151)

## Async Request APIs Migration

### Overview

The `next-async-request-api` codemod orchestrates transformations for updating synchronous dynamic properties and request access patterns to leverage `async/await` and React's `use` hook. The top-level transform orchestrator coordinates multiple specialized sub-transforms sequentially across target source files.

```typescript
export default function transform(file: FileInfo, api: API) {
  const transforms = [transformDynamicProps, transformDynamicAPI]

  return transforms.reduce<string>((source, transformFn) => {
    const result = transformFn(source, api, file.path)
    if (!result) {
      return source
    }
    return result
  }, file.source)
}
```

Sources: [packages/next-codemod/transforms/lib/async-request-api/index.ts:5-15](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/index.ts#L5-L15)

### Dynamic Property and React Use Transformation

The `transformDynamicProps` suite handles member access expressions on component props, checking whether accessed properties match target names and updating scopes accordingly. When transforming member access, `awaitMemberAccessOfProp` inspects functions for member expressions matching the prop name.

```typescript
function awaitMemberAccessOfProp(
  propIdName: string,
  path: ASTPath<FunctionScope>,
  j: API['jscodeshift']
) {
  const functionBody = findFunctionBody(path)
  const memberAccess = j(functionBody).find(j.MemberExpression, {
    object: {
      type: 'Identifier',
      name: propIdName,
    },
  })
  ...
```

Sources: [packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts:37-49](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts#L37-L49)

> [!WARNING]
> If a parent function scope is synchronous and distinct from the target function itself, the codemod cannot convert it to `async`. In this case, it inserts an error comment directly into the code at the member access site rather than failing silently.

Sources: [packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts:74-90](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts#L74-L90)

### Re-Export Verification and Type Modification

The codemod also inspects named exports and re-exports to flag components that need manual inspection when using `params` or `searchParams`.

| Helper Function | Target Check | Action |
| :--- | :--- | :--- |
| `commentOnMatchedReExports` | `ExportNamedDeclaration` with specifiers matching `TARGET_NAMED_EXPORTS` or `default` | Inserts a warning comment if re-exported locally or imported from another module |
| `modifyTypes` | `TSTypeLiteral` property signatures matching `TARGET_PROP_NAMES` | Adjusts TypeScript type annotations for asynchronous component signatures |

Sources: [packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts:177-224](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts#L177-L224), [packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts:228-246](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts#L228-L246)

## Core Component and Routing Transforms

### Overview

The core component and routing transforms modernize legacy Next.js patterns by converting deprecated APIs, wrapping routing components, auto-naming components, and injecting missing imports. The suite includes codemods for `next/link` syntax updates, `url` to `withRouter` migration, `next/image` layout adjustments, component display naming, and automatic `React` imports.

Sources: [packages/next-codemod/transforms/new-link.ts:1-123](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/new-link.ts#L1-L123), [packages/next-codemod/transforms/url-to-withrouter.ts:85-393](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/url-to-withrouter.ts#L85-L393), [packages/next-codemod/transforms/next-image-experimental.ts:258-328](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-image-experimental.ts#L258-L328), [packages/next-codemod/transforms/name-default-component.ts:23-104](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/name-default-component.ts#L23-L104), [packages/next-codemod/transforms/add-missing-react-import.ts:51-90](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/add-missing-react-import.ts#L51-L90)

### Link Modernization and Prop Lifting

The `new-link` transform targets imports from `'next/link'`, stripping deprecated `legacyBehavior` and `passHref` attributes. For child anchor elements (`<a>`), it extracts anchor properties, deduplicates them against existing `<Link>` attributes, pushes unique props to the `<Link>` element, and replaces the child anchor with its inner children.

```typescript
// Before:
// <Link href="/about" legacyBehavior passHref><a className="link">About</a></Link>
// After:
// <Link href="/about" className="link">About</Link>
```

Sources: [packages/next-codemod/transforms/new-link.ts:14-116](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/new-link.ts#L14-L116)

> [!WARNING]
> If a link uses `legacyBehavior` but contains a child that cannot be resolved as an anchor tag, the codemod bails out of lifting props and injects an error block comment into the element's children.

Sources: [packages/next-codemod/transforms/new-link.ts:71-86](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/new-link.ts#L71-L86)

### Routing and Image Transformations

The `url-to-withrouter` transform locates default exports and variable declarations referencing `url` via `this.props.url` or parameter props, renames identifiers to `router`, inserts `withRouter` wrapping via `wrapNodeInFunction()`, and adds the `withRouter` import.

```typescript
function wrapNodeInFunction(j, functionName, args) {
  const mappedArgs = args.map((node) => {
    if (node.type === 'ClassDeclaration') {
      node.type = 'ClassExpression'
    }
    return node
  })
  return j.callExpression(j.identifier(functionName), mappedArgs)
}
```

Sources: [packages/next-codemod/transforms/url-to-withrouter.ts:68-79](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/url-to-withrouter.ts#L68-L79)

Image codemods handle bidirectional imports between `'next/image'`, `'next/legacy/image'`, and `'next/future/image'`. The experimental image transform replaces legacy `layout`, `objectFit`, and `objectPosition` props with inline styles and generated `sizes` attributes based on layout mappings.

| Layout Type | Mapped Style | Mapped Sizes |
| :--- | :--- | :--- |
| `intrinsic` | `maxWidth: '100%', height: 'auto'` | `null` |
| `responsive` | `width: '100%', height: 'auto'` | `'100vw'` |
| `fill` | `null` | `'100vw'` |
| `fixed` | `null` | `null` |

Sources: [packages/next-codemod/transforms/next-image-experimental.ts:20-31](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-image-experimental.ts#L20-L31), [packages/next-codemod/transforms/next-image-to-legacy-image.ts:12-93](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-image-to-legacy-image.ts#L12-L93)

### Component Naming and React Import Resolution

The `name-default-component` transform infers component identifiers from the file's base name, converting it to PascalCase via `camelCase()` and verifying validity with `isValidIdentifier()`. If an identifier collision occurs, it appends `'Component'` to the name.

```typescript
const camelCase = (value: string): string => {
  const val = value.replace(/[-_\s.]+(.)?/g, (_match, chr) =>
    chr ? chr.toUpperCase() : ''
  )
  return val.slice(0, 1).toUpperCase() + val.slice(1)
}

const isValidIdentifier = (value: string): boolean =>
  /^[a-zA-ZÀ-ÿ][0-9a-zA-ZÀ-ÿ]+$/.test(value)
```

Sources: [packages/next-codemod/transforms/name-default-component.ts:13-21](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/name-default-component.ts#L13-L21)

The `add-missing-react-import` transform checks files for `React` member expression usages without a corresponding default import. If usage is detected, it either attaches a `React` default specifier to an existing `'react'` import declaration or unshifts a new `import React from 'react'` statement into the top-level program body.

Sources: [packages/next-codemod/transforms/add-missing-react-import.ts:10-49](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/add-missing-react-import.ts#L10-L49), [packages/next-codemod/transforms/add-missing-react-import.ts:59-88](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/add-missing-react-import.ts#L59-L88)

## Configuration and Flag Cleanup Transforms

### Overview

The configuration and flag cleanup transforms automate the evolution of Next.js projects by updating `next.config.js` settings, migrating experimental Turbopack options, converting middleware features to proxy equivalents, and stripping deprecated experimental features. These codemods inspect Abstract Syntax Trees (ASTs) via `jscodeshift` to modify static objects, configuration functions, arrow functions, and assignment expressions.

Sources: [packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts:1-25](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts#L1-L25), [packages/next-codemod/transforms/middleware-to-proxy.ts:1-35](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/middleware-to-proxy.ts#L1-L35)

### Turbopack Configuration Migration

The `next-experimental-turbo-to-turbopack` transform restructures legacy experimental Turbopack options inside Next.js configuration files. It locates `experimental.turbo` property blocks and migrates properties to a top-level `turbopack` object while routing performance and debugging flags to `experimental.turbopack*` namespaces. Unsupported options such as memory limits are removed entirely from both old and intermediate locations.

| Legacy Property | Transformed Location & Name | Action |
| :--- | :--- | :--- |
| `experimental.turbo.minify` | `experimental.turbopackMinify` | Renamed to experimental namespace |
| `experimental.turbo.treeShaking` | `experimental.turbopackTreeShaking` | Renamed to experimental namespace |
| `experimental.turbo.sourceMaps` | `experimental.turbopackSourceMaps` | Renamed to experimental namespace |
| `experimental.turbo.*` (regular) | `turbopack.*` | Moved to top-level object |
| `memoryLimit` / `turbopackMemoryLimit` | *Removed* | Dropped entirely |

Sources: [packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts:1-40](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts#L1-L40), [packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts:98-166](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts#L98-L166)

> [!WARNING]
> If an `experimental` configuration object becomes completely empty after extracting `turbo` properties and removing unsupported memory limits, the codemod deletes the entire `experimental` property from the configuration object.

Sources: [packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts:143-155](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-experimental-turbo-to-turbopack.ts#L143-L155)

### Middleware and Runtime Flag Transforms

The `middleware-to-proxy` transform updates configuration properties, type imports, and runtime segment configs when renaming middleware mechanisms to proxy equivalents. It maps `next/server` type imports (`NextMiddleware` to `NextProxy`, `MiddlewareConfig` to `ProxyConfig`) and rewrites config properties including `middlewarePrefetch`, `middlewareClientMaxBodySize`, `externalMiddlewareRewritesResolve`, and `skipMiddlewareUrlNormalize`.

| Original Property / Import | Transformed Property / Import | Scope |
| :--- | :--- | :--- |
| `NextMiddleware` | `NextProxy` | `next/server` type imports & type references |
| `MiddlewareConfig` | `ProxyConfig` | `next/server` type imports & type references |
| `middlewarePrefetch` | `proxyPrefetch` | `experimental` config |
| `middlewareClientMaxBodySize` | `proxyClientMaxBodySize` | `experimental` config |
| `externalMiddlewareRewritesResolve` | `externalProxyRewritesResolve` | `experimental` config |
| `skipMiddlewareUrlNormalize` | `skipProxyUrlNormalize` | Top-level config |

Sources: [packages/next-codemod/transforms/middleware-to-proxy.ts:19-32](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/middleware-to-proxy.ts#L19-L32), [packages/next-codemod/transforms/middleware-to-proxy.ts:108-163](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/middleware-to-proxy.ts#L108-L163)

Additional cleanups remove deprecated experimental flags. The `app-dir-runtime-config-experimental-edge` transform targets App Router page, layout, and route files, locating named `runtime` exports configured with `'experimental-edge'` and rewriting their string literal value to `'edge'`. Similarly, the `remove-experimental-ppr` transform strips `experimental_ppr` variable declarations, direct named exports, and specifiers from App Router files.

Sources: [packages/next-codemod/transforms/app-dir-runtime-config-experimental-edge.ts:4-41](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/app-dir-runtime-config-experimental-edge.ts#L4-L41), [packages/next-codemod/transforms/remove-experimental-ppr.ts:4-78](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/remove-experimental-ppr.ts#L4-L78)

> [!NOTE]
> The `app-dir-runtime-config-experimental-edge` transform requires an exact match of a single named export containing the string literal `'experimental-edge'`; if multiple runtime exports or different values are present, the file is bypassed without modification.

Sources: [packages/next-codemod/transforms/app-dir-runtime-config-experimental-edge.ts:26-36](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/app-dir-runtime-config-experimental-edge.ts#L26-L36)

## Metadata and Package Import Migrations

### Overview

Metadata and package import migrations handle structural refactoring for Next.js features, updating font package namespaces, Open Graph imports, viewport configurations, and ESLint flat configuration files. These transforms normalize third-party or legacy integration paths to modern conventions using AST manipulation tools.

Sources: [packages/next-codemod/transforms/next-lint-to-eslint-cli.ts:319-522](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-lint-to-eslint-cli.ts#L319-L522), [packages/next-codemod/transforms/metadata-to-viewport-export.ts:4-95](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/metadata-to-viewport-export.ts#L4-L95), [packages/next-codemod/transforms/next-og-import.ts:6-52](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-og-import.ts#L6-L52), [packages/next-codemod/transforms/built-in-next-font.ts:4-47](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/built-in-next-font.ts#L4-L47)

### Package Import and Font Migrations

The `built-in-next-font` transform locates import declarations referencing legacy `@next/font` source strings and updates them to the built-in `next/font` package scope. It targets root packages, google subpaths, and local font variants.

| Legacy Import Source | Modernized Import Source | Target Font Variant |
| :--- | :--- | :--- |
| `@next/font` | `next/font` | General font utilities |
| `@next/font/google` | `next/font/google` | Google Fonts integration |
| `@next/font/local` | `next/font/local` | Local font loading |

Sources: [packages/next-codemod/transforms/built-in-next-font.ts:13-44](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/built-in-next-font.ts#L13-L44)

Similarly, the `next-og-import` transform parses files for `next/server` import declarations containing `ImageResponse`. When found, it splits the specifiers, isolating `ImageResponse` into a dedicated import statement from `next/og` while preserving remaining specifiers under `next/server`.

Sources: [packages/next-codemod/transforms/next-og-import.ts:6-49](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-og-import.ts#L6-L49)

> [!NOTE]
> The `next-og-import` transform splits specifiers dynamically: `ImageResponse` elements map to `next/og`, while all other identifiers remain tied to `next/server`.

Sources: [packages/next-codemod/transforms/next-og-import.ts:17-47](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-og-import.ts#L17-L47)

### Metadata Viewport Extraction

The `metadata-to-viewport-export` transform extracts mobile viewport configurations from the legacy `metadata` named export object and promotes them into an independent `viewport` export. It searches the `metadata` object declaration for specific properties (`viewport`, `colorScheme`, `themeColor`), extracts them, filters them out of the metadata object, and constructs a new named `viewport` constant export when modifications occur.

Sources: [packages/next-codemod/transforms/metadata-to-viewport-export.ts:4-92](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/metadata-to-viewport-export.ts#L4-L92)

> [!WARNING]
> If a file lacks any matching `viewport`, `colorScheme`, or `themeColor` properties inside its `metadata` export, the transformer makes no modifications and returns the original source string unmodified.

Sources: [packages/next-codemod/transforms/metadata-to-viewport-export.ts:20-22](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/metadata-to-viewport-export.ts#L20-L22), [packages/next-codemod/transforms/metadata-to-viewport-export.ts:69-72](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/metadata-to-viewport-export.ts#L69-L72)

### ESLint Flat Configuration Transforms

The `next-lint-to-eslint-cli` transform updates ESLint flat configuration files (`eslint.config.js`) by replacing `FlatCompat` wrapper calls with direct config imports. It inspects `compat.extends(...)` and `compat.config({ extends: [...] })` constructs, mapping known string literals to direct identifier spreads.

| Config String Literal | Mapped Spread Identifier |
| :--- | :--- |
| `next` | `...next` |
| `next/core-web-vitals` | `...nextCoreWebVitals` |
| `next/typescript` | `...nextTypescript` |

Sources: [packages/next-codemod/transforms/next-lint-to-eslint-cli.ts:334-358](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-lint-to-eslint-cli.ts#L334-L358), [packages/next-codemod/transforms/next-lint-to-eslint-cli.ts:400-420](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-lint-to-eslint-cli.ts#L400-L420)

> [!CAUTION]
> Unrecognized non-Next.js string configurations encountered inside `compat.extends` arrays are preserved as wrapping `compat.extends()` or `compat.config()` calls rather than dropped.

Sources: [packages/next-codemod/transforms/next-lint-to-eslint-cli.ts:344-357](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-lint-to-eslint-cli.ts#L344-L357), [packages/next-codemod/transforms/next-lint-to-eslint-cli.ts:415-431](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/next-lint-to-eslint-cli.ts#L415-L431)

## Create React App Framework Migration

### Overview

The Create React App (CRA) framework migration codemod automates the end-to-end repository conversion of CRA and Vite projects into structured Next.js applications. Orchestrated by the `CraTransform` class and specialized jscodeshift transformers, the tool validates source directories, detects project frameworks, transforms custom DOM root rendering into Next.js compatible component wrappers, and scaffolds required routing and configuration files.

Sources: [packages/next-codemod/transforms/cra-to-next.ts:31-83](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/cra-to-next.ts#L31-L83), [packages/next-codemod/lib/cra-to-next/index-to-component.ts:4-102](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/cra-to-next/index-to-component.ts#L4-L102)

### Call-Chain Execution Walkthrough

The project transformation sequence executes through a precise chain of validation, AST rewriting, and scaffolding steps. Invoking `CraTransform.transform()` proceeds through the following named operations:

`CraTransform.transform()` → `runJscodeshift(indexTransformPath)` → `runJscodeshift(globalCssTransformPath)` → `fs.promises.mkdir()` → `this.updatePackageJson()` → `this.createNextConfig()` → `this.updateGitIgnore()` → `this.createPages()`

During `index-to-component` execution, the transformer checks for default React DOM imports and `render` call expressions, validating render boundaries before exporting `NextIndexWrapper`.

Sources: [packages/next-codemod/transforms/cra-to-next.ts:85-148](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/cra-to-next.ts#L85-L148), [packages/next-codemod/lib/cra-to-next/index-to-component.ts:21-84](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/cra-to-next/index-to-component.ts#L21-L84)

> [!WARNING]
> If multiple ReactDOM render roots or nested render calls are detected during the index transformation, `CraTransform` immediately halts execution via `fatalMessage()` to prevent invalid component structures.

Sources: [packages/next-codemod/transforms/cra-to-next.ts:102-113](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/cra-to-next.ts#L102-L113), [packages/next-codemod/lib/cra-to-next/index-to-component.ts:58-61](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/cra-to-next/index-to-component.ts#L58-L61)

### Configuration and State Flags

The `CraTransform` constructor inspects project dependencies, package managers, and configuration files to establish execution flags.

| Property Name | Type | Purpose |
| :--- | :--- | :--- |
| `isCra` | boolean | Detects whether `react-scripts` is present in dependencies |
| `isVite` | boolean | Detects whether Vite is present when CRA is absent |
| `shouldUseTypeScript` | boolean | Checks for `tsconfig.json` or `.ts`/`.tsx` source files |
| `installClient` | string | Resolves package manager (`yarn` or `npm`) via user agent or binary check |

Sources: [packages/next-codemod/transforms/cra-to-next.ts:31-83](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/cra-to-next.ts#L31-L83), [packages/next-codemod/lib/cra-to-next/index-to-component.ts:4-7](https://github.com/blade47/next.js/blob/main/packages/next-codemod/lib/cra-to-next/index-to-component.ts#L4-L7)

## Related

- [CLI Commands](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-and-config/cli-commands)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
