This isn't what is normally understood in software engineering by those terms.
A library is something you call.
A framework is some kind of application scaffolding that normally calls you.
You can use more than one library. You normally only have one framework in-process.
I found the blog post a little hard to parse. Is it an argument against wrapping frameworks, or wrapping libraries?
I agree that wrapping frameworks is fraught with danger. I can't quite agree for wrapping libraries. Wrapping libraries makes a lot of sense if you're only using a tiny fraction of the library functionality, the breadth of the wrapper's API is much smaller than the library's API, wrapping it enables you to substitute it (whether for a smaller / faster / whatever dependency in the future, or for testing, etc.), and so on.
For me, the only purpose of an abstraction is to reduce complexity, but often times I'm seeing it being used to reduce repetitiveness, which often times replaces well understood more verbose code with less understood less verbose and less flexible alternative. For me, as a team lead, easy to read code is far more important than subjectively perceived elegant abstraction that everyone then has to learn how to use, and potentially fight with.
In many cases I have noticed people jumping into abstracting away a complexity right away, often times ending up with a leaky or inflexible abstraction. To those people I say, do that painful thing at least 10 times, then think about abstracting it away, since then you probably have some level of understanding about the pain you're trying to alleviate and all the nuances that comes with that domain.
This article reminded me of two classic pieces of writing.
The first is 20+ years old now: Joel Spolsky's law of leaky abstractions:
https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-a...
One of the reasons these mini-frameworks lead to problems is that they leak. They don't cover every case which means you inevitably have to fully understand what they are doing for you in order to debug them or work around their limitations. Your cognitive load goes up!
The second is Will Larson's "Migrations: the sole scalable fix to tech debt."
https://lethain.com/migrations/
The OP complains that they've never seen a technology migration at Google that finished. Will advocates for migrations to be driven by a team that both coaches other teams on the migration and then, crucially, finish the job themselves to make absolutely sure it gets done to 100% completion.
Most Spring (+Boot) projects have been far more painful to work with - numerous abstractions and deep and complex relationships between them just to support every technology and integration under the sun. Hard to work with, hard to debug (especially with proxies and how the DI works, alongside the nonsensical rules about how @Transactional works, e.g. how it doesn't if you call a transactional method from within the same component/service), sometimes performs like shit or leaks memory and migrations between major versions are a pain. We just spent multiple months migrating a project from an old Spring version to a more recent version of Spring Boot. It's a pain.
Compare that to Dropwizard: it is fairly stable and most updates are maintenance related. It uses a bunch of idiomatic packages from the ecosystem: Jetty, Jersey, Jackson, Logback, Hibernate/JDBI3, supports Liquibase or Flyway, there's also validation and views or whatever you want, but none of it is pushed down your throat. The docs are practical and more manageable just because it does LESS overall, the code is simpler and there are far fewer surprises. And because the logic is mostly just Java and there's no castle-in-the-sky bullshit with annotations, if you want to swap out HK2 for Dagger (if you still want DI), you can - which I think is good because Dagger also does a lot at compile time and avoids the whole Spring runtime injection can of worms altogether.
The size of a framework doesn't instantly make it good or bad, but oftentimes the bigger ones will be more difficult to reason about and sometimes the amount of abstractions gets out of hand.
Moral of the story, abstractions always fail the edge cases, especially at scale. But when the entire eng org adopts something, it works much better. Everyone has to be bought in. Which at Google scale is hard.
https://research.google/pubs/megastore-providing-scalable-hi...
The modern variant of this is "platform vs service". At my previous company, it seemed like the only path to promotion was "platform" something something. So every org was in the middle of some way over-budget rewrite of their services as some big bloated platform thing, incompatible with every other team's platform, with less functionality than their old services offered. I don't know why leadership sees all these failures and seems to think "ooh, that's exactly what I want for my team too!" But you can't get a promotion if you're not platformizing.
I was very guilty of this as a young go-getter engineer! Why try to convince another team that something should be fixed if I can just paper over it?
** mini-frameworks is a realization of the creator's mental model, but it's not everyone's mental model**
People being smart enough to make their own understanding work well - but not smart enough to see they are just pushing their way of doing things and not working on something “generally understood”.
And it is very easy to start feel like you know you have a great abstraction when you don't. And unfortunately it's easy and fun to make abstractions, kinda like making babies. And has kind of similar weight to it too.
I just have to say.. stay safe out there.
Those people have their own OKRs and promo desires.
Often times, sending patches to OSS orgs are easier.
So naturally, extension to the original framework happened.
I can be found here:
Distributed (multithreaded, concurrent, ...) systems are a counterexample that are highly vulnerable to snake oil. In normal software it makes sense to build up from a small set of intellectually coherent primitives. In those cases you inevitably end up with poor performance and usually reliability if you try that. Java started out with a snake oil approach to threading (synchronized!) and Doug Lea talked some sense into them and now we have java.util.concurrent which has a rich set of primitives which are pragmatic and meet the real requirements, not a vision of purity.
On the other hand, If it was a mini-framework to pound out numerous not-so-simple HTML form applications it could greatly enrich your life and your team's.
A framework calls you. You call a library.
A framework constrains the program. A library expands the program.
It’s easier to write a library that is future proofed because it just needs to satisfy its contract.
It’s harder to write a framework because it imposes a contract on everything that depends on it.
Just like it is hard to write tort law without a lot of jurisprudence to build out experience and test cases, it is hard to write a framework from only one use case.
No one likes lawyers because they block you from doing what you want. This is the problem with frameworks.
However the government likes laws because they block you from doing what you want. Same with whomever is directing engineering that wants all other programmers to work in a consistent way.
I wonder how much of the problem stated in the article is actually a result of this resume-driven development style? The author says how the mini-framework was pushed by their engineering manager, I know it's cynical but I assume the real goal of the project was for the manager and engineers building the framework to have something fancy to show for their next promotion packet.
A toolbelt of small utility-like composables are often easier to maintain and reason about. This results in added explicitness (i.e. less magic, fewer surprises).
Personal experience shows that the immediate efficiency gains of a framework often get diminished in the face of all the hacks people introduce later, just to work around the remaining 10% of cases that the framework did not anticipate or traded-off against.
Please note this is a comment based on personal experience and professional preference.
BOCTAOE.
That is also true for "macro" frameworks.
> Wraps around the company/org-shared tech stack or framework
That is often also true for "macro" frameworks.
> Creators claim that the framework "magically" solves many problems, and push more people to use it
That is often also true for "macro" frameworks.
---
It is not clear from the reader's perspective what actually characterizes a "micro" framework. It's also not clear why the size is the issue here, when all complaints seems to be about design or quality.
Is googletest a micro or macro framework? Is google/zx a micro or a macro framework? Give us some clarifying examples. Actual things people can look for, not internal unknowable projects. There must be some exceptions too (silver bullet rules don't exist), mention them.
Also, rethink the title. Maybe "makeshift frameworks" is better terminology, as it more accurately reflects the problem that is described in the content.
I think modern programmers nowadays understand that it is much better to take the path of libraries than frameworks as it provides them with the same functionality of a framework(which is just a bundle of libraries), but with the freedom of implementing their code however they want, unlike wit ha framework, which forces certain structure and style as frameworks had to made certain decisions for the programmer in order to be a functional and comprehensive tool. This lack of freedom will usually bite most programmes LATER, when it is too late to go back and refactor code or change style and whatnot.
And that inherently also makes small frameworks even less usable than the larger ones.
YMMV, but not really.
> Start fresh. Don't build a wrapper around the existing framework, build your own from scratch.
I don't know about this one. We have a mini-framework that's kinda GraphQL but not quite. REST-ish, but not quite. Weakly documented and constantly dealing with edge cases. Breaks all sorts of standard OpenAPI tooling because the schema returned is monstrous. Used to cause all sorts of issues with TypeScript and stack recursion. Requires a ton of code -- owned by one guy -- to make the OpenAPI doc generation to work correctly.I keep thinking "Just use GraphQL" because it's basically GQL at this point...except jankier.
Rather than trying to hide things to "ease adoption", the correct answer is to educate people. Devs hate learning things. But once they learn the new thing, the pain goes away, and the results are better. The more you try to avoid it, the more problems you create later.
The entirety of the problem was that the design was bad! Adding a layer of abstraction is a design choice.
I have the impression that he confuses "obscure" with "mini". Either framework or library..
These two aren’t really mutually exclusive. Your manager may be extremely friendly and accommodating to you personally (as it seems like the author’s manager was), but part of a manager’s job is growing and supporting their reports with their career goals. If you’ve spent years majorly underleveled like it seems this person did, your manager is failing you. No matter how much of a nice person they might be, they’re not doing their job well if you’re attempting to grow at the company and aren’t succeeding.
So yes, I do think that this person still left a manager. He left a manager who wasn’t meeting the needs he had to stay at the company.
The worst is when three lines of completely standard code (immediately understandable to anybody inline) get „helpfully” lifted out into a utility function.
At the end of the day. You end up cobbling together a bespoke, worse version of Django anyway.
I am glad they were up front about this. Saved me a read.