Ok, I'll take the counterpoint and offer a few challenges I've seen with libraries. In a sense, you are often assembling your own framework. No judgement there--just good to know what you are getting into.
- There's the potential for quite a bit of choice paralysis along the way as you assemble your stack
- It's harder to seek help: as you've likely assembled a unique collection of tools (and therefore encountered unique challenges)
- It's harder to onboard other developers
- There's often more bespoke glue code
- Smaller libraries often have a smaller community and a shorter lifespan
All of that said, I'd likely choose the library approach for certain unique applications and the framework approach for "common / solved problems" like publishing content.
- There's the possibility you will do something very wrong if you roll your own from libraries
For example, HTTP serving frameworks are popular because the HTTP protocol is complicated, not to mention best practices around security that have evolved over decades and are still evolving, and the (ideal framework) will handle a lot of high-level protocol logic (do you really want to parse mimetype ranges and do Accept matching? How about CORS? Cookie signing?) on your behalf, calling into your code only for the business logic.
Using the author's definition (necessary when comparing the two) of "I consider a piece of software development technology to be a framework if it dictates the way all or most aspects of an application built using it will be programmed and how the code will be organized, while a library covers only a specific aspect of the system and is usually less opinionated about architecture.", I'm not sure your criticism really holds; Rails is a framework, but Sinatra is a library - both serve HTTP.
Even then, a library or framework can choose to split up functionality and allow you to include it or not based on your needs; even if it doesn't, there's a high likelihood that problems that aren't unique to you already have a default solution (i.e., HTTP serving frameworks/libraries that make CORS, CSRF protections, and other browser only considerations a piece of middleware that is trivial to include if you want it. An example being Spring, where I believe the only place CSRF tokens are supported is in Spring Security).
Sinatra is a framework, it's very light in that it doesn't dictate where you put your files in directories (but neither does, say Phoenix, which is definitely a framework). In sinatra, the system calls into the functions you write and you have no choice but to organize your endpoints the way that sinatra wants you to, even if some things are light relative to rails.
Did...did you miss my callout to the author's definition? Per that, Sinatra is a library. The structure of endpoints is no different than function calls; where they go is not proscribed.
look, "all" is meaningless. What constitutes "most" is a matter of judgement. Sinatra does guide you in your code organization a hell of a lot more than something like, "a json parser library".
Sounds like you might be defining library vs framework as "library's are collections of functions with minimal if any state that needs carrying between calls to exposed functions" then. Which is a possible way to distinguish them! Just...not how the author did.
Of course, that makes things like Go's inbuilt HTTP a bit weird; it's part of the standard library, but it also necessitates setting up handlers, which would potentially make it framework.
I'm conforming to the authors definition, as you present it. Under these criteria, Sinatra is categorically closer to rails than a Jason library. What might an http server library look like? It would have a function that blocks on accepting a socket, a function that parses the socket contents into a data structure, and a function that lets you send a response. That's not what Sinatra looks like, at all. If you make a claim otherwise, you are on shaky ground. Let go.
Yes exactly. This list is pretty much verbatim my problems with working in javascript right now. Everyone has assembled their own framework within this complex web of influences and dependences so it all seems like the same thing but isn't quite.
It's kinda cool in a way too but it has those specific downsides you mentioned.
As I see it, very generalised, libraries are great, if I already know pretty well what I'm building, the problem I'm solving, so I can pick the right tools for the job. On the other hand, if I'm in a much more exploratory phase, changing the product a lot, then frameworks are great because of the amount of decisions I don't need to make at this stage and the defaults often being good enough.
So ideally, I would have a framework which allows me to swap out components as the application evolves and what is being solved becomes more well defined.
To counter some of your counters, or, actually, to give some advise that I've learned along the way:
> - There's the potential for quite a bit of choice paralysis along the way as you assemble your stack
Yes. Which is why it is crucial to know software patterns, be able to research architectures and have (someone close, with) experience in making those choices - and seeing them fail. Frameworks are not a real answer to this, as they don't take away the need to make such fundamental choices: they just pull them forwards: it's the first thing you'll have to choose. At a moment when you lack all information and insight to make that choice.
> - It's harder to seek help: as you've likely assembled a unique collection of tools (and therefore encountered unique challenges)
If you stick to well-known patterns, mostly, there's enough help. Apply patterns to encapsulate, decouple and isolate all pieces. This way you avoid having to go to SO and asking "my Wordpress in a Docker with both FooFormsUltra(plus edition), EcommerceBarEasy, the MegaThemePlus with BootBulma subtheme, gives an error when I click on a red button". Instead your problems are either about what patterns to apply (which is high-level, well-documented) or with code in isolation (which means you can ask the library devs).
> - It's harder to onboard other developers
Again, well-known patterns can help. Counter is that even a senior hardened Rails dev will have a tough time on that legacy Rails project. In fact, to keep your Rails (ReactBoilerplate, Django) app onboardable over time, strict application of design patterns are the best solution. You'll need to spend time on this regardless.
> - There's often more bespoke glue code
This one I agree. In fact, if you Do It Right, your app will be mostly glue code. Especially the "boring parts" (like database setup, connecting, http handling etc). This is stuff that matters not for your domain and is best kept out of the way anyway. You really don't want the CLI-opt-parsing to get in the way of what your CLI app is doing anyway.
> - Smaller libraries often have a smaller community and a shorter lifespan
Maybe I misunderstand. But why does "no framework" imply "smaller libraries"?
The key issue is “if you do it right”. That’s easy to type, but hard to execute.
You’re essentially creating a private framework without public scrutiny which catches a lot of mistakes. That’s one of the main values of using an open source framework.
Are there times when a new framework is better than a preexisting one? Sure, when there are no frameworks that can meet your specialized project, but if it’s a typically CRUD application? Imo you’re better off with an open source framework.
> The key issue is “if you do it right”. That’s easy to type, but hard to execute.
Indeed. In fact, everyone, including said seniors, will make the wrong decisions, will "do it wrong".
So make sure the "do it wrong" is cheap. And the "do it right" compounds.
Frameworks make "do it wrong" extremely expensive. If, after four years, you find that Symphony really was the wrong tool for your highly event-sourced bookkeeping, there's little you can do other that turning your Symphony into a personal version of it, or Rewrite It In Rust.
Frameworks dictate far more than just the language and where to put stuff. They dictate how you test, how you host, deploy, how your team works, how long sprints can be, if scrum fits and so on. They get their tendrils in the entire project.
Optimizing for "cheap failure" and "compounding interest on doing it right", IMHO does not go well together with many frameworks.
> So make sure the "do it wrong" is cheap. And the "do it right" compounds.
That’s still really simple to type and hard to do.
> Frameworks make "do it wrong" extremely expensive. If, after four years, you find that Symphony really was the wrong tool for your highly event-sourced bookkeeping
1. It’s pretty simple to determine a framework’s architecture and design decisions a few months in, if not a few weeks or less
2. A “book keeper” application is such a basic commodity CRUD app, that it was exactly what a commodity framework was built for. Virtually every web based CRUD application is a conventional commodity.
Using a framework is optimizing for “cheap failure”. Creating your own inverted private framework feels like the exact opposite. All of the expensive mistakes possible with an open source framework, equally applies to your homegrown framework. The difference is that it took a lot more work and time to get to the same starting point.
> In a sense, you are often assembling your own framework.
Exactly. I always phrase it this way: if you don't choose a framework, you will be writing one.
(for a certain class of problems, obviously)
So, just know that going in. If you're not prepared for that reality, maybe your best choice is in fact to choose a framework that's already written, tested, and well supported.
> There's the potential for quite a bit of choice paralysis along the way as you assemble your stack
True, but I feel (gut feel, no facts) that this is a matter of not fully understanding either the problem or the pros and cons of the options. If it's a choice you'll be stuck with for an extended period of time, it's worth writing up an Architecture Decision Record, or some other form of semi-formal design document; writing it proves to yourself and / or your team that you and/or your team understand the problem, have reviewed the options, and know the consequences of picking that particular solution.
And it gives you, your team, and future developers a handhold why library X was picked over library Y, and a basis to challenge the decision on. If they challenge it, they need to show they understand the cost of changing as well (working hours, retraining time, chance of new issues, etc).
> It's harder to seek help: as you've likely assembled a unique collection of tools (and therefore encountered unique challenges)
Each library on their own - thinking of mainly JS libraries here - will have their own website and community; I haven't found many instances where an issue was specifically about the combination of libraries X and Y, but your mileage may vary.
> It's harder to onboard other developers
I acknowledge this is a potential issue. You can probably find Django developers more easily than "developers with experience in x, y and z". It's a trade-off. That said, I do feel like every nontrivial application and development team will need to come to terms with the fact that training and education is an important aspect of onboarding new team members, and even if they may be familiar with e.g. a framework, they still need to learn the quirks of your particular application and domain.
> Smaller libraries often have a smaller community and a shorter lifespan
A library's community size and longevity is one of those factors to keep in mind in this architecture decision record I mentioned above. Sometimes it'll be better to pick the library with more known future proof than the sexiest one. Compromises all around. I picked React because I'm confident we'll be able to find developers in 5 years time, but I also went for a cleanly separated client-server application in case we need to rebuild the front-end (which for some reason ends up happening anyway every 5-10 years).
> In a sense, you are often assembling your own framework
No you aren't. This is a thought-terminating cliche. I think what people mean by this is you are assembling your own architecture. Frameworks often come bundled with an architecture, and that is a core value proposition for a lot of folks.
But you're not building a reusable tool to scaffold other apps with, you're building a bespoke architecture for a single app.
Mobile apps, for instance, have no "framework." iOS and Android require you to implement certain classes to participate in the app lifecycle, but it is not at all the same idea of "framework" as Rails, which really pushes you to use DHH's Favorite Things over everything else.