- MAJOR tells you when breaking changes happened.
- MINOR tells you when new features arrived without breaking old code.
- PATCH tells you when bugs were fixed.
A dependency resolver reads all your version ranges (^1.4.4, ~2.3.0, >=1.0.0,<2.0.0), walks through all transitive dependencies, and tries to pick one concrete version of each package that satisfies everyone. When this isn’t possible, a good resolver should not only fail, but explain why no valid combination exists.
Tools like uv do this using PubGrub, an algorithm specifically designed for dependency solving. PubGrub behaves like a tiny SAT solver: it explores possible combinations of versions, and when it finds an impossible set of constraints, it learns from that conflict and builds a human‑readable explanation like:
Because package A depends on B >= 2.0.0 and package C requires B < 2.0.0, there is no version of B that can satisfy both.
That’s a very smart, global approach, and it’s great for complex ecosystems.
The KnitPkg approach: pragmatic, explicit, and MQL‑first. With KnitPkg, which I author and maintain for the MetaTrader platform, I intentionally chose a more pragmatic approach to dependency resolution — one that fits the reality of MQL development and MetaTrader projects.
KnitPkg still respects semantic versioning and deterministic rules:
- Pick the latest stable version that fits the declared range.
- Only use pre‑releases when you explicitly ask for them.
- Ignore yanked versions unless you pin them directly.
But instead of relying on a heavy “global intelligence” solver, KnitPkg leans on a few simple, predictable principles that put you in control:
1. Order‑driven, deterministic resolution. The order of dependencies in your knitpkg.yaml (and in composite packages) actually matters. When multiple paths compete for the same package, resolution follows a clear, deterministic rule — so once you understand it, the behavior is easy to reason about and to reproduce.
2. Overrides as first‑class citizens. In real projects, you often need to say: “I don’t care which package wants what — for this project, libX must be version 1.2.3.” KnitPkg embraces that. You can force specific versions of indirect dependencies, or point to local dependencies, in a direct and explicit way. No fighting against a “too smart” solver that keeps picking something else.
3. Designed around MQL workflows and composite packages. KnitPkg is not a generic package manager forced onto MetaTrader. It’s built around how MQL is actually written and shipped:
- Composite packages and real #include behavior for development.
- Local development setups where MetaEditor’s IntelliSense and unit tests must work.
- A packaging model that understands what it means to ship EAs/indicators/scripts with shared libraries.
- Why a certain version was chosen.
- Where to intervene if you want something different.
- How to get a stable, reproducible build on your machine (and on your VPS/production environment).
I love building tools that make developers’ lives easier, and in the MetaTrader world that often means choosing clarity and control over “algorithmic magic”. KnitPkg’s dependency resolution is designed to be transparent, MQL‑friendly, and predictable — so you spend less time fighting the tool and more time shipping robust trading systems.
If you’re an MQL4/MQL5 developer and you’ve ever struggled with sharing code, reusing libraries, or keeping multiple projects in sync, the way KnitPkg resolves dependencies is a big part of what can make your workflow simpler and safer. It’s worth giving it a try in your next project.


