Patching dependencies is easier than forking
blog.cyrusroshan.com
blog.cyrusroshan.com
For example, one of the tools we use is MinIO. There was an issue for their Python client that complained it lacked administrative features and the maintainers marked it as not on the roadmap at that time. I wrote a library called bmc, as a wrapper to their CLI exposing admin functions to a Python programmer. I proposed a prototype and the MinIO people said it's the expected behavior and went on to write it. Other people reading the issue asked access to it and we put it on PyPI.
It's not a fork but a separate library. Now the MinIO folks have included _some_ functionality in their original Python client but it doesn't have the ones we need. We'll switch back to their client for admin as soon as they have feature match.
Another example is MLflow. There was an issue wher it could track models that expect higher dimensional data but when deployed, they could only receive a two dimensional dataframe. I think issue 3570. It didn't go far and we developed a plugin/companion library that did that instead of changing the code and playing catch-up. Same with other features like authentication, which also is a result of good design decisions of having authentication not tied to our product, but having our product as an authentication provider amongst many and it just happens that we used ours, which again, makes supporting other authentication schemes easier.
An example of issues are one with Grafana where we didn't like how bandwidth was represented (as Mbs) because it would break dimensional reasoning (if you integrate bandwidth with respect to time, you should have Mb, not Mbs^2). They were super fast and changed it.
To good folks at Jupyter also ,ere very helpful when we needed to use custom config files that were overwritten or something. They promptly replied to the issue by making it configurable.
These are some things we use to avoid forking. Issues, pull requests, plugins, libraries, etc.
So the only real difference is that one stores the changes to be rebased as part of the main repo vs the repo of a forked dependency. As a result of that one loses the existing tooling aimed at merge/rebase management (git rerere, git rebase -i)
Thus - if the part of the code base being patched is relatively unchanging, this is a nice shortcut. But if it is part of actively changed code, explicitly managing what is essentially a fork in disguise may be more convenient.
Would I recommend this method to everyone? No. Is it useful in certain cases? Definitely yes.
It feels differently to me as a developer which of the things that seem analogous I do in ruby. I don't have experience using this particular tool in JS.