Shared Libraries And Scaffolder · How to use it (conceptually)

2 min read
Mid-level10 min read
Rapid overview

How to use it (conceptually)

Adopting a shared package in an existing app

The thought process when you reach for a shared package:

ask: is there a NuGet package (backend) or @dloizides/* package (frontend) for this? Cross-cutting concerns — auth, tenancy, messaging, billing, email, storage, custom domains, push, theming, analytics, the UI kit — almost certainly already have one.

local-packages feed via package source mapping). Frontend: npm install @dloizides/<name>.

registered in the service's startup composition. Frontend packages plug into the app's providers (e.g. the useUi context, the theme provider).

thin local module so existing imports don't churn; migrate call sites gradually; delete any now-dead local file once it has no remaining purpose.

you need, prefer to extend the package's seam (an injection point) over forking it locally — but only if a second real consumer wants the same seam.

  1. Check whether the concern is already shared. Before writing plumbing,
  2. Add the dependency. Backend: reference the package (resolved from the
  3. Register / configure it at startup. Backend packages are typically
  4. Adopt via a shim, not a rewrite. Re-export the shared package through a
  5. Verify, then don't over-fit the package. If the package is almost what

And the inverse decision — when you have written something inline and wonder whether to extract it: wait for the second use. One product needing it is not a library; two products needing it is.

Scaffolding a brand-new product

When a genuinely new product is greenfield, you don't hand-assemble the plumbing — you generate it:

# generate a new product wired onto the shared stack
manage.sh create-app

The high-level flow:

product needs (billing / storage / custom-domains / email / GDPR). The scaffolder composes scaffold-backend, scaffold-web, the BFF generator, and mobile config into one product directory, injecting compiling skeletons for the toggles you picked.

login → dashboard before you write any product features. This is your confirmation that the wiring is correct.

REGISTRATION.md into the platform's manifests so the new service is part of the system.

the DNS records, the Keycloak realm, the Stripe account/keys, the S3 bucket, the email mailbox, and the analytics site. These require external accounts or secrets, so a generator can stub the seam but cannot perform the step for you.

foundation.

  1. Run manage.sh create-app and choose which optional feature toggles the
  2. Build and run the generated app. It should come up with a working
  3. Register the service. Paste the snippets from the emitted
  4. Complete the owner-gated setup. Walk the per-product RUNBOOK.md: create
  5. Now write product features on top of a known-good, fully-wired

The payoff: a new product starts from "everything cross-cutting already works" rather than "copy the plumbing from the last product and hope it still matches."


See also