Design files and code versions must advance in lockstep
Aliases: paired release · design library version · lockstep versioning
What it is
Design sources (component files, variable sets, instances) and the code package must point at the same version identity. Lockstep is not “both sides ship now and then”. It is one contract change tagged with the same breakage digits on both ends, so an instance dragged from the design tool and the package installed in the repo are the same interface. If one side has already removed an old prop and the other is still drawing it, the handoff will be reinvented at implementation time.
The media differ: components and variables in a file, modules and types in a package. Identity still has to match — the same name, the same public props, the same major. When it does not, a frame that passed design review has no legal call in code.
Why it happens
If design and code keep separate release calendars, the faster end moves the contract first. Design moves first: engineers open a file whose props do not exist in the package yet, and build a local “temporary” that then becomes a permanent fork in the product. Code moves first: designers keep piling requirements onto old instances, and interactions that passed review have already been deleted in the new package. Both sides feel they are on “latest”; each latest cannot call the other.
Lockstep makes one contract change a single cross-media event: tag, changelog, and breakage digit appear on the design library and the code package together. Consumers upgrade as a pair, not “code first, design library next quarter”. The window where they disagree is a defect, not healthy collaboration buffer. The longer the buffer, the more both instances and call sites grow structures inside it that cannot substitute for each other.
Where it stops holding
Pure exploration sketches that will not be implemented need not lock versions; lockstep starts when “a developer will read this file”. A hotfix that only touches code internals, with public instance props unchanged, need not cut a new design major — but the patch number should still be findable in the design library’s release note, so “code 1.4.3, design stuck at 1.4.0 with nobody knowing 1.4.3 happened” does not arise. A system that exists on only one end (no design library, or no code package) has nothing to lock. If a third-party design tool cannot tag a library with the same digits as code, write that identity into the filename or the release record by hand; do not pretend the tool’s “latest” is the package’s “latest”.
Applying it
- One contract change produces a paired artefact: design-library file and code package share major.minor.patch, and the release note shares one breakage list.
- Write both “design library version” and “code package version” on the handoff checklist; a handoff where they differ is unfinished.
- Show the current library version next to instances in the design tool; mismatch with the repo lockfile is a defect in walkthrough, not a footnote.
- How to check: pick a feature in flight, read the design file’s library version and the repo lockfile. If they differ, list props that exist on only one side — each is an interface that will be reinvented in the window. Then ship only the code package, not the design library, and see whether the handoff checklist still passes: if it does, lockstep is not in the flow. Keep a reconciliation table of tags on both ends; after three releases that do not pair, stop adding contract and align identity first.
Related
- Same group: R1.13.1 Version numbers must express how breaking a change is · R1.13.2 Migration cost lands on consumers; pace is set by call-site count
- Adjacent: R1.05 Versioning and migration · R1.12 Usage guidelines and anti-example docs
- Search terms:
design-code version lockstep·design library version·paired release