Public evidence: generated by OpenThunder’s keyless engine (no AI) from colinhacks/zod@912f0f5 on 2026-07-21. Reproduce it: openthunder lens generate --no-narrate && openthunder lens export. ← Evidence Gallery

zod: Architecture

zod · 912f0f51b0ce · generated 2026-07-21T00:12:17.364Z · static analysis

Architecture health: 62/100 (D)

Overview

zod is a JavaScript/TypeScript pnpm monorepo, built with React, Next.js, and Vite. It is a library of 7 packages. It stores data in Drizzle and calls OpenAI and Vercel AI SDK across an explicit AI provider boundary. The main structural risks to watch: 7 oversized "god" files. The file with the widest blast radius is packages/zod/src/v4/core/util.ts: 62 files depend on it at runtime; oversized and doing too much.

_This entire analysis runs on your machine with no AI required. Connect a model provider to also narrate the reasoning and recover decisions._

Where to start

  1. packages/bench/index.ts Start here: how the system boots and wires its subsystems together.
  2. packages/zod/src/v4/index.ts Core module: 91 other modules depend on it, so it shapes much of the system.
  3. packages/zod/src/v3/index.ts Core module: 67 other modules depend on it, so it shapes much of the system.
  4. packages/zod/src/v4/core/util.ts Core module: 65 other modules depend on it, so it shapes much of the system.
  5. packages/zod/src/v4/core/errors.ts Core module: 63 other modules depend on it, so it shapes much of the system.
  6. packages/docs/loaders/stars.ts Key flow: Authentication, a high-risk path that enters at invoke stars.ts (packages/docs/loaders/stars.ts).
  7. packages/docs/loaders/get-llm-text.ts Key flow: AI provider call, a high-risk path that enters at invoke get-llm-text.ts (packages/docs/loaders/get-llm-text.ts).
  8. scripts/write-stub-package-jsons.ts Key flow: File changes / writes, a high-risk path that enters at invoke write-stub-package-jsons.ts (scripts/write-stub-package-jsons.ts).
  9. packages/zod/src/v4/core/checks.ts Change with care: 3 files depend on it at runtime; types used by 53 modules; oversized and doing too much.

System map

flowchart TD
  subgraph sys_boundary["zod"]
    benchmarks["benchmarks"]
    docs["docs"]
    integration["integration"]
    resolution["resolution"]
    treeshaking["treeshaking"]
    tsc_perftest["tsc-perftest"]
    zod["zod"]
    store_drizzle[("Drizzle")]
  end
  subgraph ai_boundary["AI Provider Boundary"]
    ai_openai{{"OpenAI"}}
    ai_vercel_ai_sdk{{"Vercel AI SDK"}}
  end
  benchmarks -->|uses| zod
  integration -->|uses| zod
  resolution -->|uses| zod
  treeshaking -->|uses| zod
  tsc_perftest -->|uses| zod
  class benchmarks library
  class docs library
  class integration library
  class resolution library
  class treeshaking library
  class tsc_perftest library
  class zod library
  class store_drizzle store
  class ai_openai aiprovider
  class ai_vercel_ai_sdk aiprovider
  classDef frontend fill:#2563eb,stroke:#93c5fd,color:#fff,stroke-width:2px;
  classDef service fill:#059669,stroke:#6ee7b7,color:#fff,stroke-width:2px;
  classDef store fill:#d97706,stroke:#fcd34d,color:#fff,stroke-width:2px;
  classDef queue fill:#9333ea,stroke:#d8b4fe,color:#fff,stroke-width:2px;
  classDef job fill:#4f46e5,stroke:#a5b4fc,color:#fff,stroke-width:2px;
  classDef external fill:#475569,stroke:#cbd5e1,color:#fff,stroke-width:2px;
  classDef aiprovider fill:#e11d48,stroke:#fda4af,color:#fff,stroke-width:2px;
  classDef library fill:#0891b2,stroke:#67e8f9,color:#fff,stroke-width:2px;
  classDef cli fill:#0d9488,stroke:#5eead4,color:#fff,stroke-width:2px;
  classDef user fill:#64748b,stroke:#e2e8f0,color:#fff,stroke-width:2px;
  classDef muted fill:#334155,stroke:#64748b,color:#cbd5e1,stroke-width:1px;

Critical flows

Application startup medium risk

Entry: process start (packages/bench/index.ts)

calls an external service (external API)

Boot wires every subsystem together; a fault here stops the whole process from starting.

sequenceDiagram
  actor C0 as Process
  participant F0 as index.ts
  participant External as external API
  C0->>F0: process start
  F0->>External: calls an external service

Authentication high risk

Entry: invoke stars.ts (packages/docs/loaders/stars.ts)

calls an external service (external API); returns a response to the caller (client)

Authentication guards every protected resource; a regression here can expose data or grant unauthorized access.

sequenceDiagram
  actor C0 as Caller
  participant F0 as stars.ts
  participant External as external API
  C0->>F0: invoke stars.ts
  F0->>External: calls an external service
  F0-->>C0: returns a response to the caller

AI provider call high risk

Entry: invoke get-llm-text.ts (packages/docs/loaders/get-llm-text.ts)

Provider calls cost money and shape model output; mistakes leak prompts, burn budget, or route to the wrong model.

sequenceDiagram
  actor C0 as Caller
  participant F0 as get-llm-text.ts
  participant F1 as llms-full.txt/route.ts
  participant F2 as llms.txt/route.ts
  C0->>F0: invoke get-llm-text.ts

File changes / writes high risk

Entry: invoke write-stub-package-jsons.ts (scripts/write-stub-package-jsons.ts)

writes files to the working tree (disk)

Direct writes to the working tree are hard to reverse; an unguarded write can clobber user code.

sequenceDiagram
  actor C0 as Caller
  participant F0 as write-stub-package-jsons.ts
  participant Disk as disk
  C0->>F0: invoke write-stub-package-jsons.ts
  F0->>Disk: writes files to the working tree

Fragile zones

Architecture rules

blocking Route all AI provider calls through a single provider abstraction; do not scatter direct SDK calls (OpenAI, Vercel AI SDK) across feature modules.

A single provider boundary keeps the system model-agnostic, makes routing/failover/cost-tracking possible, and is the core differentiator of this product.

blocking Persist and read data through the data-access layer (packages/zod); do not issue raw Drizzle queries from request handlers or feature modules.

Centralizing persistence keeps schema knowledge in one place, preserves invariants/migrations, and contains the blast radius of storage changes.

blocking Change packages/zod/src/v4/core/util.ts with care: 62 files depend on it at runtime; oversized and doing too much. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 65, fan-out 4, risk score 129.3); a careless edit ripples through many dependents.

blocking Change packages/zod/src/v4/core/errors.ts with care: 5 files depend on it at runtime; types used by 58 modules. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 63, fan-out 5, risk score 68.5); a careless edit ripples through many dependents.

blocking Change packages/zod/src/v4/core/checks.ts with care: 3 files depend on it at runtime; types used by 53 modules; oversized and doing too much. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 56, fan-out 5, risk score 63.8); a careless edit ripples through many dependents.

blocking Change packages/bench/metabench.ts with care: 29 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 29, fan-out 1, risk score 58.3); a careless edit ripples through many dependents.

blocking Change packages/bench/benchUtil.ts with care: 18 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 18, fan-out 1, risk score 36.3); a careless edit ripples through many dependents.

blocking Change packages/zod/src/v4/index.ts with care: 14 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 91, fan-out 1, risk score 28.3); a careless edit ripples through many dependents.

advisory Do not add new responsibilities to oversized files (packages/zod/src/v3/types.ts, packages/zod/src/v4/core/schemas.ts, packages/zod/src/v4/classic/schemas.ts, packages/zod/src/v4/mini/schemas.ts, packages/zod/src/v4/core/api.ts); extract new logic into focused modules instead.

Large multi-purpose files are change magnets that accumulate coupling and resist testing; keeping them from growing limits the damage.

warning Respect package boundaries: import across packages via their published entry (e.g. the package name), not deep relative paths reaching into another package's internals.

Deep cross-package imports defeat the module boundary, make refactors brittle, and create hidden coupling the build graph cannot see.