Mmohebifar

nextjs-pages-to-app-router-mining

Detect patterns for migrating nextjs apps from pages to app router

nextjsapp-routerpages-routermigrationmetricsanalysis
Public
0 executions

Run locally

npx codemod nextjs-pages-to-app-router-mining

nextjs-pages-to-app-router-mining

A read-only mining codemod that scans a Next.js codebase and produces a
semantic inventory of everything relevant to a Pages Router → App Router
migration. It never edits your code — it emits codemod:metrics
you can use to scope, prioritize, and track the migration route-by-route.

See CASES.md for the full design rationale behind each probe.

What it collects

Each metric is grouped by cardinality dimensions so you can slice the results
(e.g. all router.query usages, or every file bucketed as manual).

MetricDimensionsCaptures
nextjs-file-kindkindpage / api-route / app-entry / document (from path)
nextjs-data-fetchingfn, wrappedgetServerSideProps / getStaticProps / getStaticPaths / getInitialProps; wrapped=true for wrapper calls, reexport for export { x as getServerSideProps }
nextjs-data-contextfn, propcontext props read (params, query, req, res, preview, locale, …)
nextjs-data-returnfn, shapereturn shapes (props, redirect, notFound, revalidate, fallback, paths)
nextjs-router-importnamedefault (Router) / useRouter / withRouter / NextRouter from next/router
nextjs-router-usagemembermember accessed on a resolved router instance (push, query, pathname, asPath, …)
nextjs-router-riskpatternhigher-risk usage: push-object, shallow-routing, events, beforePopState
nextjs-client-reasoncategory, namewhy a file needs "use client": hook / global / jsx-handler / context / class
nextjs-headkindnext/head contents: import / static-title / static-meta / dynamic / script / other
nextjs-pages-typenamePages-specific type imports (NextPage, GetServerSideProps, AppProps, …)
nextjs-api-typenameNextApiRequest / NextApiResponse / NextApiHandler
nextjs-api-methodmethodHTTP method dispatch (GET, POST, …) from req.method checks / switch
nextjs-api-reqmemberrequest members used (query, body, cookies, headers, socket)
nextjs-api-resmemberresponse members used (status, json, send, end, redirect, write, …)
nextjs-layoutpatterngetLayout / layout / Layout per-page layouts; app-component (<Component {...pageProps} />)
nextjs-test-mocktargetjest.mock / vi.mock of next/router, next/head, next/navigation
nextjs-migration-bucketfile, bucketper-file difficulty: deterministic / ast-assisted / manual

The nextjs-migration-bucket metric is the headline: it classifies each
Next-related file into a migration difficulty bucket. manual is set when a
file uses getInitialProps, a wrapped data function, risky router APIs
(events / beforePopState / object push / shallow routing), streaming API
responses (res.write / res.revalidate), or <script> inside <Head>.

Targets

tsx grammar over **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}, excluding
node_modules, dist, and build.

Usage

bash

Because the codemod returns null for every file, no source files are
modified — it is safe to run on any branch.

Precision notes

  • Router usage is binding-aware. It resolves the local name of useRouter
    (including aliases) and const router = useRouter(), plus the default
    Router import, and only counts members read from those bindings.
  • API req/res mining is gated. req/res members are only counted on files
    that are genuine API routes (under pages/api, or importing a NextApi*
    type), so a page's getServerSideProps reading req.cookies is not
    misattributed as an API route (it is captured by nextjs-data-context).
  • Path-based signals (nextjs-file-kind, the pages/api gate) rely on the
    file path relative to the run target; content-based signals do not.
  • Browser-global detection keys on member access (window.x, localStorage.y)
    and matchMedia(...); bare typeof window guards are intentionally ignored to
    avoid noise.

Development

bash

Each test fixture under tests/ contains input.tsx, an identical
expected.tsx (this codemod never edits code), and a metrics.json snapshot of
the metrics that fixture should produce.

License

MIT

Ready to contribute?

Build your own codemod and share it with the community.