Open the closed: why vendor lock-in is a design choice, not a given

← All posts

Every platform dependency is a bet. You're betting that this vendor will still be the right choice in two years — on price, on capability, on reliability. Most bets age poorly.

The standard advice is "choose wisely." Pick the vendor with the best track record, the largest ecosystem, the most stable API. Solid advice. Also: not sufficient.

The real problem is coupling, not choice

Lock-in doesn't happen because you picked the wrong vendor. It happens because your business logic learned the shape of that vendor's API. Your prompts know about OpenAI's message format. Your queries know about Pinecone's filter syntax. Your workflows know about Temporal's activity model.

When a better option appears — and it will — switching requires rewriting the business logic that referenced those shapes. That cost is almost always higher than the cost of staying. So you stay. Not because the vendor is best; because leaving is expensive.

Contracts as the fix

The structural fix is simple: your business logic should never reference a vendor's concrete types. It should reference a contract — an interface that describes what you need, not how it's implemented.

// Bad — business logic knows about OpenAI
import OpenAI from 'openai';
const res = await openai.chat.completions.create({ model: 'gpt-4o', ... });

// Good — business logic knows about a contract
import { ILLMAdapter } from '@kb-labs/contracts';
const res = await llm.chat({ messages, model: 'default' });

The adapter layer translates the contract into whatever the vendor requires. Swap the adapter, not the logic.

What "open the closed" means in practice

We apply this to every system boundary in KB Labs:

The test we apply to every new abstraction: can a developer swap this dependency without touching their business logic? If no, the abstraction is leaking.

The cost of this approach

There's a real cost. More interfaces to maintain. More adapter code to write. Occasionally, an abstraction that doesn't fit perfectly over a vendor's quirky API surface.

We think that cost is worth paying — and we think it compounds in your favour. The first swap is work. The second swap is routine. By the third, your team treats infrastructure as genuinely interchangeable, because it is.

That's the freedom we're building towards. Not freedom from vendors — freedom to choose them on their merits, any time.