How would you decide whether shipping a product as a files-only static export is the right call or a trap?
answer
- decide on the roadmap, not today
- does delivered HTML depend on the requester
- publishing becomes a build someone owns
- price the exit before taking the bet
- split surfaces rather than one target
basics
~20 sDecide on the roadmap, not today's feature list. Files-only fits when no delivered HTML has to depend on the requester and publishing can be a build. It becomes a trap when per-request behaviour is inevitable and the exit was never priced.
solid answer
~50 sI would ask four questions. **Does any delivered HTML have to depend on who is asking?** If yes, files-only is already the wrong target. **Can publishing be a build?** If content is edited constantly by non-engineers, the build becomes part of an editorial workflow someone has to own. **What is on the twelve-month roadmap?** Auth-gated areas, writes, personalisation and request-time media are the features that turn the choice into a trap - and they rarely arrive labelled as such. **What does the exit cost?** Keep data access behind one layer so it can move to a server, and avoid depending on host-specific rules you would have to reimplement. The upside is genuine - nothing to run, nothing to patch, an artifact that distributes trivially - so the honest framing is a bet with a stated exit price, not a default.
go deeper
Know the headline trade: no runtime to operate and very cheap hosting, in exchange for no work at all between the request and the response.
Be able to test a feature list against the target - which items need something before the response, and which are fine as a browser fetch after load.
Argue from the roadmap and from operations: name the features that end the fit, and say how you would keep the migration contained if they arrive.
Present it as a bet with a stated exit price and named tripwires, and consider splitting surfaces so the static decision never has to stretch to cover the application.
## Why this is a judgment call rather than a lookup Files-only hosting is the cheapest thing a web team can operate: no process to keep alive, no runtime to patch, no cold start, and an artifact that copies anywhere. It is also the target with the least room to grow: other shapes can behave more like it, but a files-only target cannot acquire a request-time capability of its own without becoming a different target. So the decision is not "is this good" but **"is this still right at the end of the roadmap I can see"**. ## The four questions worth asking 1. **Does any HTML we deliver have to depend on the requester?** Not "would it be nice" - *have to*. If the first paint must differ by identity, locale enforced at the edge, entitlement or experiment assignment, the target is already wrong, because the origin has no opportunity to decide anything. 2. **Can publishing be a build?** Files change only when a build replaces them. That is fine when engineers publish, and it becomes an editorial workflow problem when a dozen non-engineers publish daily and expect their edit to be live. Someone owns that pipeline, and that someone is usually not accounted for in the decision. 3. **What does the next year of the roadmap contain?** The trap signature is always the same: accounts, a write path, a gated area, personalised recommendations, request-time media. Each looks small; each needs something on the other side of the line. 4. **What does leaving cost?** This is the question that is almost never asked at the time, and it is the one that determines whether the decision was sound in hindsight. ## The trap signature | Warning sign | Why it ends the fit | |---|---| | "We'll add accounts later" | gated content cannot be prerendered, and client gates hide UI rather than withholding data | | "Just one form" | a write needs an origin that accepts it, with its own auth and CORS | | "Editors publish several times a day" | every publish becomes a build someone must own and monitor | | "We'll personalise the landing page" | the delivered HTML is identical for everyone by construction | | "The host has a rule for that" | capability now lives in host config that does not travel with the artifact | None of these is fatal on day one. The failure mode is that each is absorbed as a workaround, and eighteen months later the app is a client-rendered shell fetching everything after load, paying the cost of a static target and getting none of its benefit. ## Designing for a cheap exit If you take the bet, take it in a way you can unwind: - **Keep data access behind one layer.** If pages read data through a single module, moving that module from browser to server is a contained change. If every component fetches for itself, the move is a rewrite. - **Prefer framework-level features over host rules** for anything you would have to reimplement elsewhere. Redirects in host config are fine; business logic there is a migration you have not scheduled. - **Keep the URL shape and the canonical form stable**, so a later target change does not invalidate external links. - **Write down the tripwires.** "We revisit this when we need a gated area, a write path, or per-reader HTML." A decision with named exit conditions gets revisited; one without gets defended. ## The split that usually wins The strongest answer in an interview is frequently *not* one target for everything. Marketing, documentation and reference surfaces are genuinely static, benefit most from the operational profile, and rarely grow request-time needs. The application surface behind sign-in almost always does. Serving them from different targets under one domain costs a routing rule and buys each surface the shape it actually needs - and it removes the pressure that turns a good static decision into a bad one. ## How to present the decision State it as a bet with a price: what you gain now (no runtime to operate, trivial distribution, a deploy that is a file copy), what you give up (anything before the response), what the exit costs, and which observations would trigger it. That framing is what distinguishes a lead's answer from a preference. **Static is not a simpler version of dynamic - it is a different contract**, and the seniority signal is knowing which contract the product will still want later.
- What single observation would make you reverse the decision?A view whose delivered HTML must differ per reader - a gated area, an entitlement, an experiment decided before the response. At that point every remaining option is a workaround on the client, and the workarounds cost more than the target saves. Pre-agreeing that tripwire is what makes the reversal cheap.
- Is the decision reversible just by changing the build mode?Rarely. The mode flips easily, but a codebase that grew on a files-only target has usually pushed all data access into the browser and some behaviour into host configuration. The migration is those two things, not the flag.
- How do you answer a team that says static is simply faster?It removes origin work, which helps first-byte time - but if the content then arrives by a browser fetch after load, the reader waits longer than they would for server-rendered HTML. Speed depends on whether the content is in the delivered document, not on the target's name.
saying these in an interview costs you the question
- Treating static as a strictly cheaper, faster default
- Assuming a server can be added later at no cost
- Claiming browser-side fetching covers anything a server would have done
- Calling gated content safe because the UI hides it
- Judging the decision on today's features rather than the roadmap
- Ignoring who owns the build when editors publish daily