Skip to content

Next.js

Zen Principles

5 principles across 4 categories, drawn from Next.js documentation.

Correctness · 1 principle Idioms · 1 principle Performance · 2 principles Security · 1 principle

Rule ID Principle Category Severity Dogma
nextjs-001 Internal navigation should use next/link instead of raw anchors Idioms 6 ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT
nextjs-002 Images should use next/image when optimization matters Performance 7 ZEN-PROPORTIONATE-COMPLEXITY
nextjs-003 App Router files should not rely on getServerSideProps Correctness 8 ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT
nextjs-004 Route handlers should not serialize raw error objects Security 9 ZEN-STRICT-FENCES, ZEN-FAIL-FAST
nextjs-005 Client-side fetching inside effects should be reviewed against server-first defaults Performance 6 ZEN-PROPORTIONATE-COMPLEXITY
nextjs-001 — Internal navigation should use next/link instead of raw anchors

next/link preserves client-side navigation behavior and framework optimizations.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT Common Violations:

  • Internal navigation should use next/link instead of raw anchors

Detectable Patterns:

  • re:<a\s+href=[\"\']\/

Recommended Fix

Replace raw internal anchors with the Link component from next/link.

nextjs-002 — Images should use next/image when optimization matters

next/image enables responsive delivery, lazy loading, and optimization defaults.

Universal Dogmas: ZEN-PROPORTIONATE-COMPLEXITY Common Violations:

  • Images should use next/image when optimization matters

Detectable Patterns:

  • re:<img\s+

Recommended Fix

Use the Image component from next/image for managed images.

nextjs-003 — App Router files should not rely on getServerSideProps

getServerSideProps belongs to the Pages Router and is not the idiomatic App Router data-loading model.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT Common Violations:

  • App Router files should not rely on getServerSideProps

Detectable Patterns:

  • re:\bgetServerSideProps\b

Recommended Fix

Move data loading into Server Components, route handlers, or fetch in the App Router model.

nextjs-004 — Route handlers should not serialize raw error objects

Returning raw error objects can leak implementation details to clients.

Universal Dogmas: ZEN-STRICT-FENCES, ZEN-FAIL-FAST Common Violations:

  • Route handlers should not serialize raw error objects

Detectable Patterns:

  • re:return\s+(?:NextResponse|Response)\.json\(\s*error\b

Recommended Fix

Return a sanitized error payload and log internal details separately.

nextjs-005 — Client-side fetching inside effects should be reviewed against server-first defaults

Fetching inside useEffect often ships extra client JavaScript when Server Components could do the work earlier.

Universal Dogmas: ZEN-PROPORTIONATE-COMPLEXITY Common Violations:

  • Client-side fetching inside effects should be reviewed against server-first defaults

Detectable Patterns:

  • re:useEffect\([\s\S]*?\bfetch\(

Recommended Fix

Prefer server-side data fetching and keep client effects for truly client-only work.

Detector Catalog

Correctness

Detector What It Catches Rule IDs
NextjsAppRouterDetector Concrete detector binding for NextjsAppRouterDetector nextjs-003

Idioms

Detector What It Catches Rule IDs
NextjsLinkDetector Concrete detector binding for NextjsLinkDetector nextjs-001

Performance

Detector What It Catches Rule IDs
NextjsImageOptimizationDetector Concrete detector binding for NextjsImageOptimizationDetector nextjs-002
NextjsServerDataDetector Concrete detector binding for NextjsServerDataDetector nextjs-005

Security

Detector What It Catches Rule IDs
NextjsErrorResponseDetector Concrete detector binding for NextjsErrorResponseDetector nextjs-004
Principle → Detector Wiring
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 40, "rankSpacing": 60}}}%%
graph TD
nextjs_001["nextjs-001<br/>Internal navigation shoul..."]
nextjs_002["nextjs-002<br/>Images should use next/im..."]
nextjs_003["nextjs-003<br/>App Router files should n..."]
nextjs_004["nextjs-004<br/>Route handlers should not..."]
nextjs_005["nextjs-005<br/>Client-side fetching insi..."]
det_NextjsAppRouterDetector["Nextjs App<br/>Router"]
nextjs_003 --> det_NextjsAppRouterDetector
det_NextjsErrorResponseDetector["Nextjs Error<br/>Response"]
nextjs_004 --> det_NextjsErrorResponseDetector
det_NextjsImageOptimizationDetector["Nextjs Image<br/>Optimization"]
nextjs_002 --> det_NextjsImageOptimizationDetector
det_NextjsLinkDetector["Nextjs Link"]
nextjs_001 --> det_NextjsLinkDetector
det_NextjsServerDataDetector["Nextjs Server<br/>Data"]
nextjs_005 --> det_NextjsServerDataDetector
Detector Class Hierarchy
%%{init: {"theme": "base"}}%%
classDiagram
    direction TB
    class ViolationDetector {
        <<abstract>>
        +detect(context, config)
    }
    class det_01["Nextjs App Router"]
    ViolationDetector <|-- det_01
    class det_02["Nextjs Error Response"]
    ViolationDetector <|-- det_02
    class det_03["Nextjs Image Optimization"]
    ViolationDetector <|-- det_03
    class det_04["Nextjs Link"]
    ViolationDetector <|-- det_04
    class det_05["Nextjs Server Data"]
    ViolationDetector <|-- det_05
Analysis Pipeline
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 50, "rankSpacing": 70}}}%%
flowchart TD
Source(["Source Code"]) --> Parse["Parse & Tokenize"]
Parse --> Metrics["Compute Metrics"]
Metrics --> Pipeline{"5 Detectors"}
Pipeline --> Collect["Aggregate Violations"]
Collect --> Result(["AnalysisResult<br/>5 principles"])
Analysis States
%%{init: {"theme": "base"}}%%
stateDiagram-v2
    [*] --> Ready
    Ready --> Parsing : analyze(code)
    Parsing --> Computing : AST ready
    Computing --> Detecting : metrics ready
    Detecting --> Reporting : 5 detectors run
    Reporting --> [*] : AnalysisResult
    Parsing --> Reporting : parse error (best-effort)

Configuration

languages:
  nextjs:
    enabled: true
    pipeline:

See Also