That's definitely true, and I think that's a testament to Minecraft / Java's strong OO design—it dovetails very nicely with the Open/Close principle. However my view is that for a mod to be a mod, there's always going to be stuff that you can't/shouldn't implement just with datapacks—whether that's complex rendering features, new entity logic, or whatever. The Mixin processor makes it really easy to build these kinds of features in a very compatible way

These tools sound very powerful, could they find use for other Java codebases?

I don't know where you'd use it besides modding, but it is a general-purpose framework: https://github.com/SpongePowered/Mixin

Other codebases don't tend to need those tools, because they already use frameworks like Spring or Micronaut which have such features built-in. Usually without bytecode rewriting and with more concern given to API definition.

For example, in Micronaut (which is what I'm more familiar with) you can use @Replace or a BeanCreatedListener to swap out objects at injection time with compatible objects you provide. If a use-site injects Collection<SomeInterface> you can just implement that interface yourself, annotate your class with @Singleton or @Prototype and now your object will appear in those collections. You can use @Order to control the ordering of that collection too to ensure your code runs before the other implementations. And so on - there's lots of ways to write code that modifies the execution of other code, whilst still being understandable and debuggable.