-
Notifications
You must be signed in to change notification settings - Fork 3
Description
What
Upgrade Next.js detection from "this project uses Next.js" to a rich architecture summary: which router, how many routes, how many server vs client components, middleware presence.
Why
The current scanner detects nextjs from package.json but says nothing about the architecture. Knowing "App Router with 23 routes and 6 client components" produces dramatically better skills than just "uses Next.js."
How
Edit src/lib/scanner.js. Add a probeNextjsArchitecture(repoPath) function that runs when nextjs is in the detected frameworks.
What to detect
Router type:
app/directory (orsrc/app/) withlayout.tsx/layout.js→ App Routerpages/directory (orsrc/pages/) → Pages Router- Both present → Both (migration in progress)
Route counting (App Router):
- Glob for
app/**/page.tsxandapp/**/page.js— each is a route - Glob for
app/**/route.tsandapp/**/route.js— each is an API endpoint - Count dynamic routes: directories matching
[param],[...param],[[...param]] - Count route groups: directories matching
(groupName)
Route counting (Pages Router):
- Every file directly under
pages/(except_app,_document,_error) is a route - Files under
pages/api/are API routes
Server vs Client components (App Router only):
- Read the first line of every
.tsx/.jsxfile underapp/ - Files starting with
'use client'or"use client"→ client component - Everything else → server component (default)
Middleware:
middleware.tsormiddleware.jsat project root → Edge Middleware present
Implementation
function probeNextjsArchitecture(repoPath) {
const result = { router: null, routes: 0, apiRoutes: 0, serverComponents: 0, clientComponents: 0, hasMiddleware: false };
// Check both root and src/ for app/ and pages/
const appDir = findDir(repoPath, ['app', 'src/app']);
const pagesDir = findDir(repoPath, ['pages', 'src/pages']);
if (appDir && existsSync(join(appDir, 'layout.tsx')) || existsSync(join(appDir, 'layout.js'))) {
result.router = pagesDir ? 'both' : 'app';
// Count routes: walk app/ for page.tsx/page.js files
// Count API routes: walk app/ for route.ts/route.js files
// Count server vs client: read first line of .tsx/.jsx files
} else if (pagesDir) {
result.router = 'pages';
// Count files in pages/ (excluding _app, _document, _error)
// Count files in pages/api/
}
// Middleware
result.hasMiddleware = existsSync(join(repoPath, 'middleware.ts')) || existsSync(join(repoPath, 'middleware.js'));
return result;
}
// Helper to find a directory from a list of candidates
function findDir(repoPath, candidates) {
for (const candidate of candidates) {
const full = join(repoPath, candidate);
if (existsSync(full) && isDir(full)) return full;
}
return null;
}Call from scanRepo() when nextjs is in frameworks:
if (result.frameworks.includes('nextjs')) {
result.nextjsArchitecture = probeNextjsArchitecture(repoPath);
}Display in src/commands/scan.js:
Next.js: App Router — 23 routes, 4 API endpoints, 47 server / 6 client components, middleware
Performance note
The 'use client' check reads the first line of each .tsx/.jsx file under app/. For a project with 200 components, that's 200 readFileSync calls reading ~100 bytes each. This is fast (<50ms).
Files to change
src/lib/scanner.js— addprobeNextjsArchitecture(), call fromscanRepo()src/commands/scan.js— display architecture detailstests/scanner.test.js— add tests for App Router, Pages Router, both, middleware
Acceptance criteria
-
npm testpasses - Detects App Router vs Pages Router correctly
- Counts routes and API endpoints
- Counts server vs client components
- Detects middleware presence
- Works with both
app/at root andsrc/app/