We built Storylines around a simple rule: branch-per-client is an exception, not a default. Every deployment runs from the same source-of-truth branch. What varies between clients is configuration, not code — environment variables, feature flags, and build-time injection determine what a given instance looks like and does, not a fork that has to be manually kept in sync with everything upstream.
In practice, this means a `clients/` directory structure holding per-client configuration, a `CLIENT_ID` environment variable that gets set per deployment, and a pre-build step that injects the right config before the site ships. Each client gets its own Netlify site, but all of them build from the same repository. A bug fix or feature lands once, in one place, and every instance picks it up on its next deploy.
The discipline this requires is mostly editorial, not technical: resisting the request to hardcode something “just this once” for a single client. When a genuine one-off customization can’t be handled through config or a feature flag — something that really does require different code, not just different settings — that’s when a branch is justified. Everything else goes through the shared system, even when it’s slower up front.
The payoff shows up later, not immediately. Six months in, when the platform needs a security patch or a new capability rolled out everywhere at once, a multi-tenant, config-driven architecture makes that a normal deploy instead of a coordination project across a dozen divergent branches.
None of this is novel as a pattern — it’s standard SaaS architecture. What’s worth saying is that it applies just as much to a platform serving ten NGOs as it does to one serving ten thousand customers. The scale changes; the discipline required doesn’t.
Click here to add your own text

