Next.js Guide

Next.js architecture diagram: the system around the app, drawn from the repo

By the engineer who builds Datadef, from client work on data platforms · Reviewed August 21, 2026

Route visualizers draw the tree under app/. That is useful for a week, and then everyone knows the routes. The question that keeps coming back is different: what does this application actually talk to. Which database, through which client, with which schema. Which payment, mail, storage, and model providers. What builds it and where it lands. All of that is declared in the repository, in files a selector can find.

6 min readFor teams shipping a Next.js app with a real backend behind it

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

174/20003 credits left
Try:

No account needed · Editable canvas, not a picture

The files that describe a Next.js system

package.json is the densest architecture file in a JavaScript repository, and it is classified as a dependency manifest with a ceiling of 8, which is what lets a workspace repo contribute the root manifest and several package manifests to the same corpus. The dependency list names the database client, the ORM, the auth library, the payment provider, the mail sender, the queue, the analytics, and the model SDKs. Almost every external node in the finished diagram traces back to a line in that file.

The data layer comes from its own classes. A file named schema.prisma has a class to itself, 2 files. Migrations under a directory named migrations get 6 slots, sampled three from the earliest files and three from the latest, so the initial shape and the current direction both reach the generator. Plain .sql files elsewhere are classified separately, with 10 slots of their own.

The contract layer comes from the API class, and the matching rule is worth checking against your repo: a file is an API definition when its name starts with openapi. or swagger., or when its extension is .graphql, .gql, or .proto. A specification kept as docs/api-spec.yaml matches none of those and is read only if something else classifies it, so naming it openapi.yaml is the cheapest way to get the contract into the diagram.

The deployment path comes from the CI class: anything under .github/workflows, a root .gitlab-ci.yml, or an azure-pipelines file, plus any Dockerfile or compose file the repository carries.

What a Next.js repo contributes
  package.json              dependency manifest class (names the providers)
  prisma/schema.prisma      schema class
  prisma/migrations/*.sql   migration class (sampled from both ends)
  graphql/schema.graphql    API class
  Dockerfile                container class
  .github/workflows/*.yml   CI class

Never walked
  node_modules/  .next/  dist/  coverage/  and every lockfile

What is deliberately not read

TypeScript source is not part of the classified corpus, so the route handlers under app/api and the server actions in your components are not fetched. What the generator sees of them is the tree summary: app/api/ with its file count, and every other directory to three levels with theirs.

That sounds like a loss until you consider what a diagram made from route files would look like. Four hundred boxes, one per handler, is not architecture. The dependency manifest, the schema, and the pipeline describe the system at the altitude a diagram is actually read at, which is why they are the ones classified.

node_modules and .next are on the skip list and are never walked, and every lockfile is dropped by name, so a repository with a 4MB pnpm lock spends none of its 40-file budget on it.

Choosing what the diagram is about

On the first sync, Datadef counts what it classified and proposes a focus in one sentence built from those counts alone, with no model call. A typical application repo reads as: Mostly Dockerfiles and CI pipelines (9 files) with 5 data model and API files. Architecture is the usual pick, and it draws the running system: the app, its database, the providers, the jobs, and the pipeline that deploys them.

The content focus is the alternative, and it is the right choice when the interesting part of the repository is the data model rather than the deployment. It raises the ceilings on schemas, migrations, and API definitions and treats the containers and pipelines as context.

Either way the output lands on an editable canvas, so the two or three things only you know, a rate limit, a webhook path, an ownership boundary, can be added as annotations and survive on the diagram.

A monorepo of packages

When the Next.js app is one workspace among several, the dependency manifest ceiling lets several package.json files into the same corpus. See monorepo architecture diagram for how the budget is spent there.

Keeping it true across releases

The connection re-syncs daily against the branch or tag you chose, and skips commits that did not move the head. Adding a provider is usually a package.json change, which is exactly the kind of change that ought to redraw an architecture diagram and almost never does when the diagram lives in a design tool.

Embed the result in the repository README as a live image and the onboarding paragraph gets a picture that matches main. Export stays available as PNG or JPEG for a slide or a review document.

FAQ

Does it read my route handlers and server actions?

No. TypeScript and JavaScript source files are not part of the classified corpus, apart from migration files. The generator sees the route directories and their file counts through the repository tree summary, and builds the architecture from the dependency manifest, schemas, API definitions, containers, and CI pipelines.

How does it know which external services the app uses?

Mostly from package.json, which is classified as a dependency manifest. The dependency list names the database client, ORM, auth library, payment and mail providers, queue, and model SDKs, and those become the external nodes in the diagram, cross-checked against what the compose file and CI pipeline declare.

Is the database schema included?

Yes where the repository declares one. A file named schema.prisma has its own class, and files under a directory named migrations are read in the .sql, .ts, .js and .py extensions, sampled three from the earliest and three from the latest so both the original shape and the recent direction reach the generator. Other .sql files anywhere in the repository are classified separately.

Do node_modules or the build output slow this down?

They are never walked. node_modules, .next, dist, build, out, and coverage are skipped by directory name anywhere in the path, and package-lock.json, yarn.lock, pnpm-lock.yaml, and bun.lockb are dropped by file name, so none of them consume any part of the 40-file, 250KB budget. A repository with a four megabyte lockfile spends nothing on it.

Can I keep my own annotations on the generated diagram?

The canvas is fully editable, and hand-moved nodes keep their positions across syncs. Note that a sync regenerates the diagram from the code, so for a frozen annotated version, duplicate the project and keep the synced one as the living view.