Senior craft

Senior craft

What changes when the thing you build is used by other teams rather than by end users - API design you cannot easily take back, release discipline, security, and review.

A product feature can be rewritten next sprint. A shared layer or module cannot: twenty apps have imported its component names, read its app.config keys and set its options in their own configs. Everything in this section follows from that asymmetry. The interview signal is whether you think in terms of consumers — their upgrade cost, their debugging experience, their production risk — rather than in terms of your own repository.

Know

  • The public surface is the product. For a layer it is component and composable names, app.config keys, runtimeConfig keys, routes and layouts, and the modules in the preset. For a module it is the options object, the injected runtime APIs, the hooks it exposes and the types it augments. Everything else is internal, and saying so explicitly is what allows you to change it.
  • Design for the escape hatch. Consumers will need something you did not anticipate. Build hooks, runtime hooks, an alias to your runtime directory and an overrides option cost you little and prevent forks.
  • Deprecate, do not delete. One major with the old name working and a warning that names the replacement, a codemod when a rename touches many files, a migration note written from the consumer's point of view.
  • Security is part of the job for internal tooling. Everything a layer ships runs in production in every app: server routes, middleware, plugins, dependencies. Nuxt shipped security releases during 2026, so tracking advisories and upgrading on a cadence is a habit an interviewer will probe.
  • Support is a process, not a favour. Reproduction-first intake (a fixture per bug, which then becomes a regression test), triage labels, a known-pitfalls document consumers can self-serve from.
  • Measure adoption. You cannot deprecate what you cannot see. Version tracking across consuming apps turns "should we remove this?" from an argument into a query.
Be able to say· What changes when you build for other developers instead of end users?

"The cost of a mistake moves from your repository into theirs. So I design a small public surface and say out loud which parts are internal, I give consumers escape hatches — hooks, an alias, an overrides option — so they do not fork when I did not anticipate their case, and I treat any change to that surface as a breaking change that needs a deprecation window, a migration note and adoption data before removal. I also carry their production risk: every server route or plugin I ship runs in every app, so security advisories and upgrade cadence are part of my job rather than theirs."

Exercise

Exercise
  • Write down the public surface of a package you have built: every name a consumer can depend on. Then mark the ones you would be happy to change next month. The gap between the two lists is your design debt.