skip to content

Build Output Anatomy

The pieces a build leaves behind: hashed assets, prerendered documents, a server bundle and route manifests. Asked because the output tells you whether the app still needs a running server.

on this pageshow

questions

5

What kinds of files does a meta-framework's production build leave in its output directory, and what is each for?

level: juniorimportance: must knowfreq 68%

answer

  1. four kinds, not one blob
  2. names that change with contents
  3. finished documents versus a program
  4. the index that ties them together

basics

~10 s

A production build emits content-hashed client assets, prerendered documents for routes resolved at build time, a server bundle for routes that were not, and manifests mapping routes and assets to those files.

solid answer

~40 s

Most meta-frameworks emit four categories. **Client assets** - JavaScript chunks, CSS and copied static files - get content-hashed filenames, so the name changes whenever the bytes do. **Prerendered documents** are complete HTML files produced once at build time for routes whose output was already determined then. A **server bundle** holds everything left to request time: routes rendered per request, data and form endpoints, middleware, and the rendering runtime they need. **Manifests** are machine-readable indexes tying the rest together - which URL pattern is answered by which document or handler, and which hashed files a given route needs. Reading those four tells you the thing that matters most: whether anything still has to execute after the build, and which URLs already exist as finished files.

go deeper

for a junior

Be able to name the four kinds and say which of them a browser downloads. The one distinction to hold on to is finished HTML versus code that still has to run.

for a middle

Explain why asset names carry a content hash, why prerendered documents embed their data, and what the manifest exists to solve when no file name can be written by hand.

for a senior

Show that you read an output to make a hosting decision: find the entry points, check which routes have documents, and say out loud what still has to execute per request.

for a principal

Frame the output as the contract between building and running. Argue for treating its shape as something the team depends on deliberately, since assumptions about it leak into deploy scripts and hosting choices.

A production build is not a compiler handing back "the app" as one file. It leaves a directory of artefacts with different producers, different consumers and different lifetimes. Most meta-frameworks emit the same four kinds, whatever their authoring model, and being able to name them is what lets you answer "what does this deployment actually need?" without guessing. ## The four kinds **Content-hashed client assets.** The JavaScript the browser executes, the CSS it applies, and files copied verbatim from the project's public folder. Generated ones are named with a hash of their own contents, so a logical `app.js` is emitted as something like `app.9f2c1a4b.js`. The consequence that matters here is that the *name identifies the bytes*: nothing is ever overwritten, and a file whose contents did not change keeps its name from build to build. How long each category may be cached is a caching-policy question in its own right. **Prerendered documents.** For every route whose HTML could be determined at build time, the build writes a finished document to disk, usually at a path mirroring the URL. These are ordinary HTML files: no server is needed to produce them, only to hand them over. They normally embed the serialised data the page was rendered with, so the client can take over the existing markup without re-fetching what the build already had. **A server bundle.** Everything not resolved at build time is compiled into a bundle with a request-handling entry point: per-request routes, data and form endpoints, middleware, and the rendering runtime. Its packaging depends on what the build was told to target - a long-running process, a per-request function, an edge runtime - but its role is constant. It is the code that must execute after deployment. **Manifests.** Machine-readable indexes that glue the other three together: which URL pattern maps to which prerendered document or server handler, and which asset files a route needs. Because assets carry content hashes, nothing can hard-code their names; the manifest is how generated HTML and the client runtime discover them. ## How they differ | Artefact | Produced | Consumed by | Needs code at request time | |---|---|---|---| | Hashed client assets | Once, at build | The browser | No | | Prerendered documents | Once, at build | The browser, served as-is | No | | Server bundle | Once, then executed per request | The hosting target | Yes | | Manifests | Once, at build | The server bundle and client router | No, but read by code that does | The line that matters runs through the middle of that table. The first two rows are **results**; the third is a **program**. An output with no server entry point describes an application that is finished. An output with one describes an application that is only half finished until something runs it. ## Reading an output directory 1. Find the directory of hash-named files. That is the client graph - what browsers download. 2. Find the `.html` files laid out like the site's URLs. Those routes already exist as documents. 3. Find a bundle with a server or handler entry point. If there is one, part of the app still has to run somewhere. 4. Open the route manifest. It is the authoritative statement of which URLs are answered from disk and which are answered by code - more reliable than inferring it from the file tree. ## A common misreading The most frequent mistake is to call the whole output "static" because it is all sitting on disk. Files on disk and a static deployment are not the same claim: the server bundle is a file on disk too, and so is an on-demand transformer that reshapes assets when they are requested. "Static" is a statement about whether anything must execute to answer a request, and the honest way to settle it is to find the entry points, not to look at file extensions. ## What the output does not tell you Meta-frameworks differ in how visible they make all this: some publish the output layout as a documented contract you may read and build on, while others treat it as internal and expect you to go through a translation layer for whichever hosting shape you chose. The artefact *categories* are stable across them, which is why the vocabulary transfers even when the directory names do not. Two things a directory listing genuinely will not tell you. First, freshness policy: whether a prerendered document is meant to survive until the next build or to be replaced while the app runs is a property of how the route was configured, not of the file. Second, cost: a server bundle's existence says code must run, not how much of it runs per request or how heavy that is.

  • Why are the files dropped in a project's public folder usually copied without a content hash?
    Because they are referenced by URLs that people and other systems write by hand - a favicon, a site verification file, an image pasted into content. A hashed name would change under those references on every edit, so builds copy them verbatim and leave their freshness policy to be set conservatively.
  • Where does the data a prerendered document was rendered with normally end up?
    Serialised into the document itself, usually as an inline payload the client reads on startup so it can adopt the already-rendered markup without re-fetching what the build already had. It counts towards the document's size, and it is visible to anyone who views source - so build-time rendering is not a place to put data the viewer should not see.

A build output is closer to a shipping crate than to a program: some of it is finished goods (documents and assets), one item is a machine that still has to be plugged in (the server bundle), and one is the packing list that says what is where.

saying these in an interview costs you the question

  • Calls the whole output static because it is all files on disk
  • Thinks the server bundle is only used while the build runs
  • Believes a hashed asset keeps its name after its contents change
  • Treats manifests as debug output that can safely be deleted
  • Assumes documents and hashed assets may be cached identically
open as a page

Why does a meta-framework build emit a separate module graph for the browser and for the server?

level: middleimportance: must knowfreq 58%

basics

~20 s

Because the two sides have different entry points, targets and permitted dependencies. The browser graph must stay small and carry no secrets or server-only code, while the server graph may use anything, so each is traversed from its own roots.

open as a page

In a meta-framework's build output, what does a route manifest contain, and what depends on it at runtime?

level: middleimportance: should knowfreq 52%

basics

~20 s

A route manifest maps each URL pattern to how that URL is answered - a prerendered document or a server handler - and to the assets that route needs. Server dispatch and client-side prefetching both read it.

open as a page

How do a build's base path and asset origin appear in its output, and what breaks when either is wrong?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Both are baked in at build time, prefixing asset URLs in generated HTML, in manifests, in emitted CSS and in the client runtime that composes chunk URLs later. Get either wrong and documents render while their assets fail to load.

open as a page

Given only a build's output, how do you tell which artefacts were produced once and which need a process at request time?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Look for entry points, not file types. Finished documents and hashed assets are results, while a request-handling entry, an on-demand asset transformer or a writable runtime cache directory all mean code still has to execute per request.

open as a page