Build, Buy, or Borrow — A Practical Decision Framework
- ShiftQuality Contributor
- Jan 8
- 7 min read
Every feature request is actually a decision in disguise. Not "how do we build this?" but "should we build this at all?"
The default instinct for most developers is to build. It is the most satisfying option. You control the code. You understand the implementation. Nobody else's bugs, nobody else's API rate limits, nobody else's pricing changes. And sometimes, building is the right call.
But building comes with a cost that developers chronically underestimate: maintenance. Every line of code you write is a line of code you own forever. It needs tests. It needs updates. It needs to be understood by whoever comes after you. When you build something, you are not just spending the time to create it. You are committing to the time it takes to keep it alive.
The alternative is buying — paying for a service or product that does the job. Or borrowing — using an open-source library or framework that someone else built and maintains. Each option has tradeoffs. This post gives you a framework for making the choice deliberately instead of defaulting to whatever feels easiest in the moment.
The Three Options
Build: You Write the Code
You build when the thing you need is core to your product, specific to your domain, or simply does not exist as a product or library.
When you build, you get total control. You can optimize for your exact use case. You can change direction without waiting for a vendor's roadmap. You can avoid paying ongoing licensing fees.
You also get total responsibility. Bugs are yours. Security patches are yours. The documentation that future team members need — also yours.
Buy: You Pay Someone Else
You buy when a mature product exists that solves your problem better than you could solve it yourself in a reasonable timeframe. Authentication services, payment processing, email delivery, analytics — these are solved problems with products that have been tested by millions of users and hardened by years of edge cases.
When you buy, you trade money for time and quality. A good SaaS product will be more reliable, more secure, and more feature-complete than what you could build in the same period. You offload maintenance to someone whose entire business depends on keeping that system running.
You also give up control. The vendor sets the pricing. The vendor decides the roadmap. If the vendor goes under or pivots, you have a migration project on your hands.
Borrow: You Use Open Source
You borrow when a well-maintained open-source project does what you need. Libraries, frameworks, tools — the open-source ecosystem covers an enormous range of problems, and the code is free to use.
When you borrow, you get the benefit of community development. Bug reports from thousands of users. Security patches from maintainers who care about the project. Documentation and tutorials from a community that has collectively spent more time on the problem than you ever could.
You also inherit risk. Open-source projects can be abandoned. They can introduce breaking changes. The maintainer who was doing the work may burn out and walk away. A library that is critical to your system may have exactly one person keeping it alive.
The Decision Framework
Here is a practical framework that works for teams of any size. For each feature or capability you are considering, ask these five questions in order.
1. Is This Your Core Differentiator?
If the thing you are building is the reason your product exists — the unique value that no one else provides — build it. Full stop.
A payment processing company builds its own payment engine. An analytics company builds its own data pipeline. A design tool builds its own rendering engine. These are the things that make the product valuable. Outsourcing your core differentiator means outsourcing your reason for existing.
Everything that is not your core differentiator is a candidate for buying or borrowing. And most of what you build is not your core differentiator. Authentication is not your differentiator. Email delivery is not your differentiator. User management, file storage, search indexing — unless your product is specifically about one of these things, someone else has already solved the problem better than you will.
Be honest about what your differentiator actually is. Many teams convince themselves that everything is core, because building is more interesting than integrating. That instinct leads to teams spending months building commodity features instead of the thing that makes their product worth using.
2. Does a Mature Product or Library Exist?
Search before you build. Spend an hour investigating what is available. Not a cursory Google search — a real investigation. Look at open-source options. Look at SaaS products. Read the documentation. Check the GitHub activity. Look at the issue tracker.
If a mature, actively maintained solution exists, the burden of proof is on building, not on buying or borrowing. You need a specific, concrete reason why the existing solution will not work for your case.
"We could build something better" is not a specific reason. It is a prediction, and it is almost always wrong. The existing solution has had years of users finding edge cases, filing bugs, and testing at scale. Your from-scratch implementation has had zero.
"The existing solution doesn't handle our specific requirement X" might be a valid reason — but check first whether the library is extensible or the product has an API that lets you add what you need. Often, building on top of an existing solution is a fraction of the work of building from scratch.
3. What Is the Total Cost of Ownership?
This is where most teams get the math wrong. They compare the upfront cost of building (developer hours) to the upfront cost of buying (subscription price) and conclude that building is cheaper.
It is not. The total cost includes:
Building costs:
Initial development time
Testing and quality assurance
Documentation
Ongoing bug fixes and maintenance
Security patching
Feature additions over time
Onboarding cost for new team members who need to learn the custom system
Buying costs:
Subscription or licensing fees over the expected lifetime
Integration development time
Time spent working around vendor limitations
Migration cost if you need to switch vendors later
Borrowing costs:
Integration development time
Time spent keeping the dependency updated
Risk of abandonment (and the cost of replacing it if that happens)
Time spent contributing fixes for bugs you encounter
When you do this math honestly, buying or borrowing almost always wins for non-core functionality. A $50/month SaaS product that saves one developer a week of work per year is paying for itself many times over — and that is before you account for the bugs you will never have to fix and the security patches you will never have to write.
4. What Happens If This Dependency Disappears?
Every buy or borrow decision introduces a dependency. The question is not whether the dependency is risky — all dependencies carry risk. The question is how bad it would be if the dependency vanished, and how hard it would be to replace.
For a logging library: low risk. If it disappears, you swap in another one. The interface is standard, and migration is straightforward.
For your authentication provider: medium risk. If it disappears, you have a real project, but the problem is well-understood and there are multiple alternatives.
For a niche library that provides the core algorithm your product depends on, and only one person maintains it: high risk. You should either contribute to maintaining it, fork it, or consider building an in-house alternative.
The mitigation strategy scales with the risk. Low risk: just use it. Medium risk: make sure the integration has a clean boundary so you can swap providers without rewriting your whole system. High risk: build it yourself or invest in ensuring the dependency stays alive.
5. How Clean Is the Integration Boundary?
This is the architectural question. Regardless of whether you build, buy, or borrow, the thing needs to connect to your system. How it connects determines how painful it will be to change later.
A clean integration boundary means your application talks to the dependency through a thin abstraction — an interface, a wrapper, a module that hides the implementation details. If the dependency changes or you need to swap it out, you change one module, not fifty files.
A dirty integration boundary means the dependency is woven throughout your code. ORM-specific query syntax in your business logic. Vendor-specific API calls scattered across controllers. Authentication provider callbacks embedded in your user model.
The cleaner the boundary, the lower the cost of changing your mind later. This is true whether you build, buy, or borrow — but it is especially important for buy and borrow decisions, because you control less of the evolution of the dependency.
Common Scenarios and What to Do
Authentication and authorization. Buy or borrow. Auth0, Firebase Auth, Clerk, Supabase Auth — pick one. Rolling your own authentication is one of the most common mistakes in software development. The security surface area is enormous, the edge cases are subtle, and the cost of getting it wrong is catastrophic. Unless you are building an authentication product, use someone else's.
Payment processing. Buy. Stripe, in most cases. The regulatory complexity alone makes this a nontrivial undertaking, and the liability of handling financial data incorrectly is not worth the savings.
Email delivery. Buy. SendGrid, Postmark, Amazon SES. Delivering email reliably is a full-time job involving sender reputation management, bounce handling, spam compliance, and deliverability monitoring. Your team has better things to do.
Database. Borrow (the engine itself) and build (your schema and queries). PostgreSQL, MySQL, or SQLite depending on your needs. The database engine is a solved problem. Your data model is not — that is the part unique to your application.
UI components. Borrow. A component library like shadcn/ui, Radix, or Material UI gives you accessible, tested components. Build your application-specific UI on top of them. Do not build your own date picker. Life is too short.
Core business logic. Build. This is the thing that makes your product different. The pricing algorithm. The matching system. The analysis engine. The workflow that no one else has. This is where your development time should go.
The Meta-Decision
If you take nothing else from this post, take this: the time you spend building commodity features is time you are not spending on the thing that makes your product valuable.
Every hour a developer spends implementing password reset flows is an hour they are not working on the feature that will get you your next ten customers. Every week spent building a custom email system is a week not spent on the core product.
The best architectural decisions are often decisions not to build. They free your team to focus on the work that only your team can do.
Key Takeaway
Build what makes you different. Buy what is mature and mission-critical. Borrow what is well-maintained and easily replaceable. For each decision, calculate the total cost of ownership — not just the upfront cost — and draw clean integration boundaries so you can change your mind later without rewriting your system.
The most productive teams are not the ones that build the most code. They are the ones that build the right code and leverage everything else.
Next in this learning path: Designing Systems That Survive Your First 1,000 Users — how to build something that does not fall over when real people start using it, without over-engineering for scale you do not have yet.



Comments