Fork vs Contribute Upstream: When to Maintain Your Own Fork

Contribute upstream by default: your changes get maintained by the project and you avoid merge debt. Maintain a fork only when upstream rejects changes you need, moves too slowly, changes licence or direction, or when the changes are proprietary. Keep any fork small and rebased often.
What is the difference between forking and contributing upstream?
Contributing upstream means sending your changes to the original project as pull requests, so they become part of the official code. Forking means keeping your own copy with changes the original does not have.
On GitHub every pull request starts from a fork, but that is a temporary working copy. The real question is whether you plan to run a long-lived divergent version, which is what this guide means by maintaining a fork.
The decision is mostly about who carries the maintenance. Upstream contributions share the load with the whole project, while a fork puts every future merge, fix and release on your own team.
- The change is a bug fix or improvement other users would want.
- Maintainers are active and review pull requests in reasonable time.
- Your product depends on the project long term and you want its fixes and security patches.
- The change is small enough to be accepted without redesigning the project.
- You want influence over the roadmap; regular contributors earn it.
When is maintaining your own fork justified?
- Upstream rejected the change or it conflicts with the project’s direction.
- The project is abandoned or releases too slowly for your needs.
- The licence changed to terms you cannot accept, and you want to stay on the last open version.
- The changes are proprietary features you do not want to publish, and the licence allows keeping them private.
- You need a stable, frozen version for a regulated or long-lived deployment.
How do the options compare?
- Describe the change you need and why the current project does not support it.
- Search issues and discussions to see whether it was proposed or rejected before.
- Ask maintainers whether they would accept it, and in which form.
- If yes, contribute upstream and use a temporary patch only until it ships.
- If no, check whether a plugin, hook or configuration option can achieve the same result.
- If not, estimate the yearly cost of a fork in merge and security hours.
- Compare that cost with the value of the change and with switching to an alternative project.
- Decide, document the reason and set a date to review it.
| Option | Upfront effort | Ongoing cost | Best for | Risk |
|---|---|---|---|---|
| Contribute upstream | Medium: review, tests, discussion | Low | General fixes and features | Changes may be rejected or slow to merge |
| Plugin or extension | Medium | Low to medium | Custom behavior on a stable API | Limited by the extension points available |
| Thin patch set on upstream | Low | Medium: rebase each release | A few private changes | Conflicts grow with each upstream release |
| Long-lived fork | Low at first | High: merges, security, CI | Diverged needs or abandoned upstream | Falling behind on security fixes |
| Community hard fork | High: governance and branding | Very high | Licence change or governance breakdown | Splitting users and contributors |
What does maintaining a fork really cost?
The hidden cost is merge debt. Every upstream release has to be merged or rebased into your fork, and conflicts grow as the two diverge. Teams often postpone this until they are several versions behind and a security fix forces a painful catch-up.
You also inherit responsibilities: running CI, tracking security advisories, publishing builds and documenting differences for your own team.
- Engineering hours per upstream release to merge and test.
- Security monitoring for upstream advisories and backporting fixes.
- CI and build infrastructure for your version.
- Knowledge risk if the person who understands the fork leaves.
What do well-known forks teach?
Licence changes have produced prominent community forks. When HashiCorp moved Terraform to the Business Source License, the OpenTofu fork was created under the Linux Foundation. When Redis changed its licensing, the Valkey fork appeared, also under the Linux Foundation.
These are community hard forks with foundations, many companies and full-time contributors behind them. A single company maintaining a private fork has none of that support, so the bar for going it alone should be high.
For a company, a fork is a product decision as much as an engineering one. It creates a component you now own, with its own roadmap, bugs and security exposure, and it should be visible to whoever plans headcount and risk.
Customers may care too. Enterprise buyers often ask which open-source components you run and how you patch them. A clear answer, such as tracking upstream releases within a set window, builds more trust than a vague reference to an internal version.
Estimate this cost before forking. Multiply the hours of the last few upstream merges by the expected number of releases per year, and add time for security backports. The result is often larger than the effort of getting the change accepted upstream.
How do you keep a fork healthy step by step?
The lesson for smaller teams is to fork only as a last resort and, if you must, to do it together with other affected users where possible.
- Record why the fork exists and what would let you drop it.
- Keep your changes as small, well-described commits on top of upstream.
- Move whatever you can into plugins, configuration or separate modules.
- Rebase or merge on every upstream release, not every year.
- Automate tests that cover both upstream behavior and your changes.
- Subscribe to upstream security advisories and release notes.
- Keep offering generic changes upstream, so your patch set shrinks over time.
Common mistakes with forks
- Forking to avoid a code review discussion, then paying for it for years.
- Mixing formatting or refactoring changes into the fork, which makes every merge harder.
- Ignoring the licence: copyleft licences may require publishing modifications you distribute or offer as a network service.
- Letting the fork fall many releases behind upstream.
- No single owner responsible for keeping the fork current.
How do you get changes accepted upstream?
Most rejected pull requests fail on process, not on the idea. Open an issue first describing the problem and your proposed approach, and ask maintainers whether they would accept it before writing much code.
Keep pull requests small and focused, follow the project’s style and include tests and documentation. A change that is easy to review gets merged faster and is less likely to be sent back.
Be patient and responsive. Maintainers are often volunteers; answering review comments quickly and politely builds the trust that makes future contributions easier.
- Discuss the design in an issue before coding.
- Split large features into reviewable steps.
- Add tests that prove the change and protect it from regressions.
- Offer a configuration option when the behavior is not wanted by everyone.
- Follow up on review comments within days, not weeks.
Which signals tell you it is time to drop a fork?
A fork should have an end condition. Revisit it whenever upstream ships a major release, because the reasons you forked may no longer apply.
Dropping a fork is usually cheaper than it looks once your patch set is small. Move remaining changes into plugins or configuration and switch back to official releases.
| Signal | What it means | Action |
|---|---|---|
| Upstream merged your key change | The main reason for the fork is gone | Plan the switch back |
| Upstream added an extension point | Your change can live outside the core | Rewrite as a plugin |
| Merge effort grows every release | Divergence is compounding | Reduce the patch set or re-evaluate |
| A community fork gained momentum | Shared maintenance is available | Consider joining it instead |
| Nobody on the team understands the fork | Knowledge risk is high | Document or retire it |
Frequently asked questions
- Is it legal to keep a private fork of an open-source project?
- Usually yes for internal use. Permissive licences allow private modifications. Copyleft licences such as GPL require sharing source when you distribute the software, and AGPL extends that to network services. Check the licence file before deciding what must stay public.
- How often should I sync my fork with upstream?
- Ideally on every upstream release, or at least every minor version. Small, frequent syncs keep conflicts manageable. Waiting a year turns syncing into a project of its own and leaves you exposed to security issues fixed upstream in the meantime.
- What if maintainers reject my pull request?
- Ask what would make the change acceptable, such as a configuration flag or an extension point. If they still decline, consider a plugin or a minimal patch set. Only maintain a full fork if the change is essential and cannot be done any other way.
- When should a company fork an open-source project publicly?
- When upstream is abandoned, governance breaks down or a licence change leaves many users without an acceptable option, and when you can commit to maintaining it long term. Public forks need contributors, releases and communication, so partner with others where possible.