Hacker News new | past | comments | ask | show | jobs | submit login
The Problem with Frameworks (plbrault.com)
82 points by drfreckles on Feb 8, 2022 | hide | past | favorite | 107 comments



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.


I'd like to add this:

- 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.

I'm not saying that's a good definition.


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.


Imo the autHor’s definition of a framework isn’t very good. React is clearly a framework and not a library.


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.


Ok, that's fair. Assembling your own architecture. But I feel the same risks and caveats apply.


I keep saying it again and again: Dependencies strangle dev teams to death. A massive framework tangle of interlocking dependencies is enough to default most teams to never-never-upgrade-land, even when struggling to compensate for a too-early release's flaws.

And I'll add that a lot of frameworks (I'm thinking of Spring here) devote most of their effort to creating "value add" wrappers around technologies that work more than well enough without, and that create even more problems for a dev who now has to understand both original and wrapper's attempt at enhancement. Enough wrapping! Create something real, just once.


> A massive framework tangle of interlocking dependencies is enough to default most teams to never-never-upgrade-land, even when struggling to compensate for a too-early release's flaws.

I definitely agree that the attitude of never upgrading dependencies doesn't work! But I've seen plenty of teams using dependencies successfully that took the opposite approach of updating them regularly (say, spending an hour updating versions every couple of weeks - perhaps a bit longer if there is a major release of an important dependency). This might not work if you require mission-critical stability, but it can work out to a huge time saving if you don't.


Agreed - I drive-by minor version updates at every opportunity that I can because I know if I don't, things will get pretty painful sooner or later.


I used to do this before I discovered renovate [1] - now we spend time working on major upgrades but minor are generally automatic (assuming they pass tests)

[1]: https://github.com/renovatebot/renovate


Oh nice - do you get many problems that slip through even though tests pass? I had a minor update to the Stripe SDK recently that broke something.


We do get very occasional issues in our React app, but not enough to outweigh the benefits of things staying up to date.


Well with spring boot you can use spring wrappers but there are always (atleast in my expirience) ways to override their way of doing things or just completely skip their wrapper and just use whatever is under the hood


> completely skip their wrapper

Why use Spring Boot at all then?


Because it provides commodity functionality that most developers with Spring experience can understand quicker, along with the Java philosophy of customization over convention.

I don’t like Java or Spring, but I understand their benefits and why people like them.


I don’t understand why people use Spring. Having worked in more than enough Spring projects, your frankly better off without any framework than using Spring.


What don’t you like, if you don’t me asking? I was thinking of delving deeply into Spring.


There is quite some boilerplate and for someone inexperienced it is quite a big leap.

Ive been developing with spring for past 3 years and so far I freaking love it.

Ive gotten quite quick with it so I can do an mvp with auth, logging, microservice patterns really fast.

And when project grows in complexity it is very maintainable.

But if you are not expirienced and don't care about maintainability and want something fast then node& express is a way to go imho


Thanks for your insight. I agree with your comment about the trade off between the time it takes to fully learn the framework vs the productivity that you will get. I think that’s true for all frameworks. There’s also Javelin if you need something smaller and quick to pick in Java that is similar to Express.js.


Imo if you’re doing Java, you need some inversion of control framework like Spring of Guava. You can’t avoid it especially for larger projects

what I really hate is that it focuses on configuration & customization over convention. At the same time, it is a strength for certain projects and teams.


> Imo if you’re doing Java, you need some inversion of control framework like Spring of Guava. You can’t avoid it especially for larger projects

I completely disagree. I’ve worked on more than my fair share of Spring projects, and as far as I’m concerned, dependency injection frameworks tend to make projects more complex than they need to be. In some ways I think Spring projects end up being much larger than they need to be because of Spring. Not to mention that it turns compile-time checks into incredibly hard-to-debug runtime checks.


> a lot of frameworks (I'm thinking of Spring here) devote most of their effort to creating "value add" wrappers

... that don't usually add any real value.


I've been struggling with this for years in the front-end / JS space, to the point where I just want out and live happily in my reasonable Go dependency management / aversion space.

It's a convoluted mess. A while ago I made the move to migrate to Yarn 2 / 3, because it uses less disk resources (dependencies are in .zip files). But because most tools still expect a node_modules folder, it required a lot of workarounds. And now I'm in some kind of dependency hell where one library needs version X of another lib while the other needs version Y, and they're not compatible or don't work well in my editor. It just keeps giving. Sigh.


FWIW my experience is that Yarn 2/3 work great, as long as you stick with the `node_modules` linker (which works the same way Yarn 1 and NPM always have, by extracting all packages to disk) instead of the "Plug 'n Play" option (which keeps all packages zipped up, and requires that Yarn own all filesystem access to decompress files on the fly).


But Spring also saves you the time of putting those wrapped technologies together.


I wonder if Spring has caused more wasted time, configuring its grandiosity, than it has saved people, and I say that because I don't know the answer.


Sometimes it is.

Trying to find solutions to random errors is a big task because of all the layers and layers of classes.

A simpler and renewed architecture that covers all those parts that Spring solves would be beneficial for the users.


What do you think people waste most of their time on?


Debugging and finding tiny mistakes in the new hot JS framework of the month. That and maybe trying to do something with CSS the wrong way, but not looking up how it should be done and reworking their DOM to make that happen.


I'm sorry, put the parent comment was talking a the Java framework Spring. My question was in regard to that framework.


Debugging is one. I’ve spent and enormous amount of time debugging problems that never would have occurred without Spring, and even more debugging things that would have been much easier to debug without Spring.

And even if I didn’t have to spend all that extra time debugging, I don’t think Spring actually added any real value.


Thanks for your comment. What best practices do you recommend so that people don't hit these debugging problems? Also, what other framework/library would you use instead of Spring?


I think it's language dependent - no team i've been on has been strangled by dependencies, they've largely amplified development; and the tradeoff to address breaking changes when they come is worth it.

But if you add dependencies, and don't make time to keep them up to date... you're going to have a bad time.


Most frameworks (web-frameworks at least) get you from 0 to 80% in very little time. Nice layout/css etc, but they require you to learn how they want to do everything; which can be both cumbersome and time consuming. Frameworks also gives management false expectations of how long it takes to make something.

"It looks like you're 80% done with the web-page already, and we've just started - great!" — Management


"But we'd like a quick chat to understand why the last 20% took so long" — Also Management


I love the phrase “quick chat” because it’s rarely ever actually quick. If it was actually quick, they’d just ask it.

Over time I’ve learned that the correct response is, approximately, “Sorry, I’m in the middle of [important work], please book 30 minutes for us and [stakeholders] to discuss it.” Gives me time to prepare so that I’m not caught off guard. And to bring backup if I think I need it.


And HR asking for a quick chat should set off greater alarm bells, especially with regards to documenting the discussion


Well, there's no "preparing" for that... except making sure your LinkedIn profile is up to date.


I actually had a quick chat with my teammate today. 5 minutes (well we chatted about dumb shit like changing oil on our cars for another 5). Also it wasn't bad, I was checking in to make sure his career objectives were being looked after (he just onboarded a few weeks ago).


I find this officespeak hilarious.


The good old "a quick chat"; that's when you know some blame is about to be handed out...


> (frameworks) require you to learn how they want to do everything; which can be both cumbersome and time consuming.

New teammates will have to learn how to do things anyway. But with frameworks there's a chance they already know.


I mean, yeah but that seems like a good investment? Like how many times you want to learn that remaining 20%? And how many times customisations are not reusable? Of course you either learn a framework and reuse it, or go something that is bespoke, and does it have the same unit test coverage? Same documentation? Same ability to hire people with common knowledge? Same ability to google issues? I am not sure, but I see only pros about frameworks (in terms of maintainability but I guess not in terms of resource usage :D) and cons in the context of people not understanding / knowing how to protect themselves from frameworks


Hi2u Telerik and Infragistics if that crap still exists.


Ask yourself: Are you building a Rails, Django, Spring app, or are you building a coffee-comparison-app, a facebook-for-dogs or a inventory-management-system (or anything, really).

This alone implies that what matters is your domain. Not the framework. This is also an important point that many seniors in the industry keep repeating. Eric Evans wrote a giant book about it (DDD), Robert Martin named his company after it (and keeps bringing it up on any conference). Dave Farley keeps repeating it in his youtube channel and his books. And so on.

My take is that development speed does not come from quick scaffolding like `rails generate CreditCard` but from having a clean, well-maintainable, loosely coupled, well-tested CreditCard Service or Aggregate, or DomainBoundary or whatever. Rapid time to market is not achieved with `curl fancyframe.work/in.sh | sudo bash` or `pip install django`. Rapid time to market is achieved with an architecture that allows easy rewrites, fast pivots and rapid swapping of dependencies.

Frameworks often hamper such loosely coupling. They get in the way, in the long run. Sure, chances are >50% that what you are building now fill be replaced or have failed within years. But for the off-chance of having something that you'll be maintaining over years, decades even, be sure you have something that does not get in the way. Edit: and on that timescale, the time-wins that the framework initially gave you, are often neglecatable anyway.

> So my strategy is to keep frameworks like Spring, Hibernate, and Rails at arm’s length; behind architectural boundaries. I get most of the benefit from them that way; and I can take ruthless advantage of them.

>

> But I don’t let those frameworks get too close. I surrender none of my autonomy to them. I don’t allow the tendrils of their code to intermingle with the high level policy of my systems. They can touch my peripheral subsystems; but I keep them away from the core business logic. The high level policies of my systems shall never be touched by frameworks. - Robert C Martin https://blog.cleancoder.com/uncle-bob/2014/05/11/FrameworkBo...


The discourse around how to build software is just terrible in general. This is sound advice and yet it's seen in many circles as tilting at windmills. Meanwhile, devs are happy to write off days/weeks with the makework of upgrading their apps to stay up-to-date with frameworks. Productivity is confused with a feeling of power.

I suspect some people value frameworks more highly because they perceive them as coming bundled with a community (e.g. support). This consideration outweighs the architectural damage done in their minds. I'm not disparaging this. But as devs mature and age, they gain confidence, and eventually realize that every project doesn't need to automatically start out with a framework.


I think a lot of the issues here (particularly around version management) are more advising against frameworks that aren't firmly established as popular.

If you're using something like Rails, a lot of the issues are minimized to a huge degree:

- Work required from updates to Rails itself, while sometimes painful, usually has a lot in the way of community support, and it hasn't been really bad since Rails 2/3/4.

- Libraries are highly, highly incentivized to keep up to date with the latest version of Rails, since so much of the ecosystem revolves around it. Not supporting the latest version of Rails basically signals you've abandoned the project.

Regarding switching libraries and frameworks, this depends on the scale I think. With React (an example he gave of a library, although I personally think it's in a bit of a grey zone) switching to something else basically means re-writing your front end - even your state management is likely written in something fairly coupled to React. If you're replacing a single-purpose library, sure the impact is smaller, but those sorts of libraries are ones you'd probably be using in a framework world anyway.

For me, the biggest value of frameworks is eliminating low-value decisions. With an opinionated framework, there doesn't need to be arguments about how to structure your project, how logging, or authentication, or database interaction, or one of a million other things with a lot of OK answers is going to work. This eliminates arguments when initially developing things, and massively reduces onboarding time. I can get a git repo of a Rails project and be more or less productive in a few days - with bigger Node apps I sometimes feel like it takes weeks or months to really get how things are structured sometimes.


> According to that definition, React is not a framework, but Gatsby is.

I dislike articles like this. The vast majority of people would consider React a framework, and if you need to redefine such a basic word in order to make your point valid, there's probably an issue with your argument, not the definition.


I think it's reasonable to say that React is a UI framework because you have to build your UI within it if you choose it. The author's argument that because it doesn't provide the kitchen sink it isn't a framework, misses the issue that you can have frameworks for subsets of a project. You get UI frameworks (React, Angular), CSS frameworks (Tailwind), backend/API frameworks (GraphQL), etc that only lock in one area.


It’s a bad argument. React is still a framework and not a “library”.


I get the argument the author is making. React is a Javascript framework, but Gatsby is a React framework. So you have a situation where you have a framework for a framework.

Having worked with both, React isn't just an "opinionated way of writing JS", it uses Javascript under the hood but there's a ton it does uniquely, that is there is no JS equivalent, this is a thing that only React has (hooks, context, etc).


According to https://www.reactjs.org react is "A JavaScript library for building user interfaces"


As someone wrote further down the thread, the official position of React is that it's not a framework, so it's not just this article making this point.

I agree with you that there's something slightly wrong about that framing on the part of the devs.

But this is just the old descriptivism/prescriptivism divide again.


React is a framework if you let it be a framework.


React marketing insisted on being a library for too long and Vue is distinguishing itself by saying they aren't a library, they're a framework.

https://www.youtube.com/watch?v=2KBHvaAWJOA


I like calling React a component framework and Gatsby/Next an application framework.


In game development, Unity 3D and Unreal Engine (and Godot) frameworks seem to have mostly taken over from custom game engines frameworks that use some libraries (for audio, physics, networking etc).


Because those abstract away the complicated build processes for the target, notably game consoles.


The problem with the frankenstack, where you levy a couple of hand-picked libraries, is that there’s no guarantee or roadmap that will make newer versions of your libraries (and their dependencies) play together nicely a year or two on. If the number of libraries can be kept to a minimum, then maybe it’ll be a viable strategy.


But at some point, isn't the hand-picked approach going to result in the same morass of version dependencies on any site of moderate complexity?


Ideally you would choose dependencies with minimal dependencies of their own (very few if any common dependencies), so you have a manageable number of versions and near complete freedom of choice of those versions.


And ideally, you'll wrap them too. In what is often called "Anti-Corruption-Layers". Often very simple Proxies or Adapters. Consequentially, this makes testing (in isolation) far easier too.

Which also means you'll choose libraries that are decoupled by design because the others are really hard to write such wrappers for.


Sometimes quite useful, yes, though I would strongly emphasize that the goal is not to wrap the entire API of the dependency -- that is pure busywork and doesn't stave off "corruption". Just the (consciously quite minimal) parts you actually need.


I'll usually even add another guard: only add them if the library uses non-domain language.

For example, so that you can say "chargeCard(payment)" in your domain and app, Instead of having to do things like "openAnonCustomer(payment.customerId) && pmt= addPayment(payment.amount, payment.currency) && bookPayment(pmt)" or whatever weird language, order, or transaction boundaries a library uses.


Yes, wrap a useful "flow" for your application, rather than functions. Often I find there is just one flow for a dependency.


Yes, but the whole point is that you don't have to update all your dependencies at once.

Even if you do find yourself needing to update your dependencies, you can do them 1 at a time. This way you aren't stuck with a not building, completely broken codebase for days while you refactor to adapt to new changes.


I think the issue here is with non-modular frameworks or opinionated frameworks and libraries. For example, Laravel is very much a framework, but at every level it allows you to opt-out of it's conventions and provided modules and do things your own way. And it doesn't end up with these problems.


I'll chime in on this for posterity's sake.

I spent about a month reviewing frameworks on "ToDoMVC.com". My goal was to evaluate those and choose one for an app I wanted to upgrade. When I'd finished the review process I struggled for about a month trying to decide on which of those I'd invest my time in because that's a huge investment.

I finally decided to no use one. I did exactly what the author did. I selected libraries of code. I used jQuery, Mustache.js, Accounting.js, PouchDB.js, Chart.js, and Bootstrap.

With the exception of the latest Bootstrap I've been able to update all of those without any issues at all and I've gotten pretty good and using those tools.

I don't regret this at all. In fact I think this choice would make it much easier for anyone to modify my code, and that's something I want to offer users.


The paradox of frameworks: if you couldn’t write it yourself, then using it is a big risk if you hit a bug. But if you could write it yourself, you may not want to, as you have a better idea of what you want.

Personally, I only like frameworks that don’t fight me tooth and nail to encapsulate them into adapter layers (hexagonal architecture) when the time comes. There aren’t many of them. Some of them feel almost narcissistic in how much they want to assert themselves within your code.

The domain model is the most important thing. The framework is a detail that is not important.

Edit: forgot to mention, there’s a whole other argument here about how frameworks are not architectures. I suspect this is a big draw for many teams. But a commoditized architecture won’t serve you well over the long term.


If you hit a bug with a popular, open-source framework, the odds are great that others have as well and it will get escalated and solved quickly. The same can't be said for closed-source, proprietary frameworks. Also, writing it entirely yourself always leads to re-inventing the wheel over and over again. Furthermore, I have yet to see any proprietary framework that wasn't in some shape or form a poor knockoff of something already existing in the open-source world.


But you don’t write your own framework, you write a program. Not trying to make something too generic can keep things much simpler.


I like the idea of a "curated" platform: putting together the best libraries in a somewhat opinionated way, but not writing a lot of additional code on top of it, and making sure that most of the curated glue code can be ditched if someone using the platform doesn't want or need something.

This would let people get going quickly and not have to make a thousand decisions or figure out all the integration points, but retains some of the benefits of the library-mindset (configurability, swappability, domain expertise, etc.)


In the clojure ecosystem, Luminus (https://luminusweb.com/) is pretty much a curated set of libraries for web development.

I still think that relationship still creates friction. The framework itself has swapped out libraries in the past, and you are basically dragged along if you upgrade.


As far as I understood from my experience, there’s no way to upgrade your Luminus after you had started your project, you only upgrade individual libraries — so any further changes in the Luminus framework itself don’t affect your old projects.


I'm not a Java person, but I think Dropwizard advertises with basically that idea.


interesting, thank you for the pointer!


15 years ago, there was "LAMP:" Linux, Apache, MySQL, PHP.


…and I still use this.


I generally agree with this article. (Great explanation of the tradeoffs, BTW.)

One edge case: Situations where the language itself has a major, breaking change between versions. IE, .Net Framework 4 -> .Net 5 (based on .Net Core,) or Python 2 -> Python 3.

A simple codebase might easily move from Python 2 to 3; or .Net Framework 4 to 5; but once there's a lot of libraries, there's a good chance that you'll need a newer library in order to move to the newer language... And that newer library might have breaking changes.


Also sometimes you have to go 'backwards' for whatever reason. You find the exact same issues.

Not as bad as it used to be but also just moving between platforms and staying on the same framework and things would act different. Because something in the OS layer was different. I ran into this quite a bit in python 2.x. Where windows and linux methods would be slightly different just because of underlying assumptions about how things like files were opened. That was when I learned your code is only as good as the std lib your platform provides. Take for example c++. The language itself is not terribly big. But that stdlib that goes with it (whew). Then you wonder would c++ be worth anything if that lib was not there?


From an overview it seems more likely solvable with proper coding and tools, I love the fact that for example symfony/php makes you use a framework but you have the proper tools in order to forget that you're using the framework, you can have controllers, entities, repositories (and services with right extensions of framework services?), not depends on symfony, but also like if you use a framework and you go all in in getting it into your way, you would always end up by not being able to change stuff easily, even if it was your code, so I always make sure that I don't depend on things I can't change and have a set of interfaces layer in between "Depend on things you can change and not on things you can't", unless you made it perfect the first time and never end up changing it, but I think most likely this post is just junior point of view, with all due respect, I don't know the person, so maybe he's one of the best developers around, but just only considering this blog post, it seems very bad

Also I think the issue is more relevant with Python and django and ruby as they lack abstract classes and interfaces? in the context of making things incrementally changeable they're quite useful, so maybe there is something that is like that?


Most software developers have the same problem. They ignore what they already know is going to happen: one day, their code will die, just like we all will one day die. This thought is so disturbing to us that we avoid dealing with it until it's too late. No one's code runs forever; yet we all pretend every line of our code will outlive us. And just like the health-nut marathon runner who drops dead of a heart attack, there are no guarantees in life or in code, framework or not.

Plan for your code's death. Keep an eye on the next versions, and keep a CI job pinned to them. Read the changelogs. Keep the import EOL dates on your calendar. EOL your own code. We don't get to choose whether our code will die, but we can choose how it goes out.


I think it really depends on your framework. Good ones have upgrade paths that work.

"Move fast and break things" frameworks are not good ones.

My first job, I was working on a Tapestry 5 web-app. Very nice framework, very opinionated though.

And the creator, Howard L Ship, was very opinionated about breaking things. So we could never upgrade past 5.x (where I think x was 4 or 6), because it just broke everything for us, and we put weeks of dev time into trying to overcome that.

In the end, we just ported the app to Wicket, it was faster to do so.


everytime i run npm install i feel i'm about to embark on a bunch of side missions


Hey one import and you can have 1000+ dependencies :)


If you don’t know better, use a popular framework. You’re less likely to be wrong.

As an added benefit, you’ll probably find it easier to get help from outsiders.


A framework presents a scope.

If your project falls within the scope, great. You may be sporting a bunch of YAGNI functionality, but could grow into it.

Now, should requirements venture outside the scope...

- You may eat some Level Of Effort to meet those requirements, assuming s decent plugin system, or

- As The Famius Article notes, you could eat the framework equivalent of DLL Hell trying to appease the Version Gods.


We’ve been arguing about this for years. Frameworks have their place. Bespoke hand-crafted apps have their place. It all depends on expected performance, human factors, and maintainability. I think that’s a benefit you get from hiring folks that have both worked inside and outside of frameworks and in a variety of tech stacks.


I don't really consider ExpressJs as framework, but if it is, then it's the most suitable one for me.

It's very simple to setup, easy to extend and letting you to setup the structure whatever you want.

If only it's updated to use async await, better error handling and have modules to perform ssr for react (and vue), it'll be much better.


Once you adhere to any API, moving away from it requires refactoring.

Good luck removing Lodash from your code, unless you're replacing it with an equivalent Underscore.


When you avoid frameworks for the sake of simplicity, maintainability, security (the attack surface is less), you still don't want to start with a fresh page. At least when dealing with React.

You need a slim boilerplate to create React script bundles, achieve performance and do a few other tasks. That is why I wrote Crisp React: https://github.com/winwiz1/crisp-react


If you're not using a framework, you're writing a framework.

Might be a good or bad thing depending on the project.


so, basically Clean Architecture reiterated.


I'll take a good library over any framework.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: