Eighteen months ago I was in a meeting room in Dongguan with the quality manager of a precision parts manufacturer. She had one form on the screen — the incoming inspection sheet for Line 1 — and she wanted a second one for a new production line. "It is almost the same," she said. "Can you just copy it?"
I said yes. The copy took about four seconds. The consequences took a year and a half.
This is the story of the most under-priced feature in every low-code platform I have worked on: reuse. We market it relentlessly. Industry templates. Component libraries. App packages you install with a single click. Platforms advertise "development and reuse of custom UI components" as a headline capability, right next to the form designer. And every time we ship a copy button, we quietly create a dependency graph that nobody ever draws.
The copy button is the most dangerous thing we ship
Copying is the cheapest thing a platform can offer and the most expensive thing a customer can do. At the moment of copying it is pure convenience: the fields are already there, the validation is already written, the layout is already approved. Six months later, the vendor introduces a new required compliance field. Now there are eleven copies of that form, and the person who made them no longer works at the company.
The platform's own reference material is honest about the intent — templates are described as a starting point you then customize. That word, customize, is doing an enormous amount of unacknowledged work. Customization is exactly the moment the copy stops being related to its parent. The template gave you a head start. It also gave you a fork.
There is a real distinction here and most platforms blur it. Referencing means many apps share one definition that is updated once. Copying means many apps hold their own frozen definition. Referencing is hard to build and hard to sell, because it has visible friction at t=0. Copying is trivial and demo-friendly. So we build the copy button, describe it in the same breath as a shared component library, and let the customer discover the difference in production.
We are almost always reusing the wrong unit
Ask what actually gets reused across enterprise systems and you get an awkward answer. It is rarely the screen. It is the rule — the validation that a batch number must match the receipt, the rule that only a certified inspector can sign off a line, the rule that a deviation above two percent routes to a manager. Those rules are policy, and policy is the thing every plant genuinely agrees on.
Where does policy live in a low-code platform? In a validation expression on a field, in a condition on a form, in a branch in a workflow, in a line of a script, in a configuration row on a dashboard. Five places, five editors, five mental models, one business rule. There is no unit called "the rule" that you can define once and reference from all five. So when we sell reuse, we sell it at the layer that is easiest to package — the visual layer — and the layer that actually needs reuse stays copied and scattered.
The result is a company that appears to have standardized, because every form looks the same, while the behavior underneath has drifted into eleven slightly different truths.
A component is not reusable. It is anchored.
When a platform finally builds proper custom components, there is a detail that almost nobody reads until it bites them. A component built against the platform's runtime library cannot run outside the platform base — it is tethered by design. The runtime gives it context, permissions, data binding, the whole host environment. That is a reasonable engineering decision. It is also a scoping clause hiding inside the word reusable.
Reusable turns out to mean reusable here, under these conditions, against this version of the base. Move it to a different environment, a different tenant, or an external page, and the anchor becomes a wall. In one integration I watched a team spend three weeks discovering that a component they called "shared" could not leave the sandbox it was born in, because it depended on the platform's own context APIs. It was shared. It just could not travel.
This is not a bug. It is the honest shape of reuse in a hosted platform, and it deserves to be said out loud before someone builds a strategy on top of it.
Reuse without versioning is just coupling with better marketing
Here is the part that low-code platforms have largely skipped, and it is the part every mature package ecosystem spent decades learning.
When you reference a shared component, you now have a dependency. A dependency needs a version, a changelog, a compatibility range, an owner, and a way to say "this is deprecated, migrate by March." Public package managers learned this the hard way. Low-code platforms mostly skipped it, because there was no way to express it: a component was a row in a table, and editing the row changed it for everyone, instantly, silently.
So the shared component in a low-code platform behaves like a dependency with no lockfile. Someone edits it to fix one team's problem. Every other consumer shifts underneath them without a release note, without a test, without a choice. The more successful your reuse program is, the more violent that drift becomes — the component with forty consumers is exactly the one nobody dares touch.
Reuse, it turns out, is not the opposite of duplication. Done badly it is a more efficient way to spread the same change everywhere at once.
Who owns the thing everyone copied?
The deepest problem is not technical. It is that a shared asset needs an owner, and the moment you create a component "for everyone," you have created something that belongs to no one. It was built for a project, by a person, against a deadline. That project shipped. The person moved on. The component now has forty dependents and zero parents.
Compare that with a library. A library is maintained because someone's job is to maintain it. Low-code organizations almost never staff that role, because the whole premise of reuse is that it removes work. It does remove work — the work of writing the same thing twice. It does not remove the work of owning it. It just moves it somewhere invisible, to a person who does not know they have it yet.
The uncomfortable conclusion
The feature that makes reuse effortless is the reason reuse fails.
Low-code platforms became popular by deleting the friction from software construction — no build step, no packaging, no dependency manifest, no release train. Reuse rode along on that deletion for free, which felt like a gift. But friction is not always waste. In a software ecosystem, packaging, versioning, ownership, and deprecation are not bureaucracy. They are the mechanisms that let one thing be safely shared by many. Delete them and sharing stops being safe, and unsafe sharing is just a slower kind of copying.
So the honest conclusion for anyone building or buying a low-code platform is uncomfortable: if you want real reuse, you have to make reuse harder. You have to require a reference instead of encouraging a copy. You have to make a shared asset carry an owner, a version, and an expiry. You have to accept a little friction at t=0 so that you do not inherit a decade of drift at t=n.
Back in Dongguan, we eventually consolidated eleven inspection forms down to one. It took longer than the original copy ever did. The quality manager said something I now repeat in every architecture review: "Copying was easy. Owning all the copies was the hard part."
She was right. The copy button is not free. It just sends the bill to a future team.
Top comments (0)