I grab a framework to also keep my skills relevant, especially if I'm not practicing them in my day job. If I didn't have that impulse, I'd keep it simple all the time. I'm really good at it, because I really dislike complexity as it requires me to remember more things and I don't really like that feeling.
I'll optimize if I absolutely have to.
Not that businesses ever cared about this attitude. I mean, I've seen it work. The work that I do with LLMs is quick and pragmatic. No need to put stuff into production when it's just a prototype. No need to use a framework if gluing an LLM with some Python code and a well crafted prompt produces the result we need. It allows me to ship in days, not weeks. Obviously, if one then wants it productionized, additional work needs to be put into it and possibly the code needs to be refactored. But, in my opinion, that's the time and place where that type of stuff should happen.
Yes; a lot of people don't code because they need to make something work, they code for the joy of it. When the software they need to write is boring or solved - like another CRUD app, front- or back-end - instead of picking the boring and easy to build and comprehend languages and frameworks, they will make it interesting for themselves. Learn a new language, framework, or design paradigm; follow whatever is trending at the moment, etc.
A lot of new software is over-engineered from the start. A lot of that is cargo cult as well, e.g. big companies use microservices in their custom k8s cluster, therefore we should use microservices in our custom k8s cluster too.
> they will make it interesting for themselves.
Engineers love to solve problems. If there are no problems readily at hand, they will create some.Things like Wordpress sound super simple - you don’t even need to code!
But you do need to worry about managing an entire Apache server, managing a crappy database, hardcoding bullshit in PHP, cronjobs, cloud deployment and the fact that almost all “features” of it like plugins and themes etc are massive security vulnerabilities
I think the pitfall to avoid ITT is that there’s a single source of maintenance effort - there are likely many!
I was mainly providing an alternate example to “over-engineering is the only source of complexity” train of thought this thread largely has
If you can "make a website" by using a third-party provider but instead you opt into running wordpress on your own, you are still over-engineering.
As a rationalization, sure, but never as the reason.
They do offer more than coding standards.
I have no problem with sql but an ORM makes what I know about sql very ugly.
This means I treat every project like a letter to my future self that needs to be 100% self explainatory and work even if the environment around the project changed. And this means as few moving parts as possible.
For example, you work with ORMs and then you see all the problems with them as you maintain the project, so on your next app you create an app that is raw SQL. Then after maintaining that for awhile you start to see all the pitfalls of that approach and why people created ORMs in the first place. Then someone mentions the latest and greatest ORM that promises to be better this time and you use it, saving you from raw SQL you'd jumped to last time....ad infinitum.
Finally we have our web 3.0!
...
not every problem has a technical solution.
most of the time the real trade off is financial.
especially now with AI generated boilerplate and npm commands that shit out 10,000 lines of code at a keystroke.
Broad heuristics can be very effective
We make decisions on many more datapoints than can be put into what sometimes amounts to a “for and against” list
The more code, the more assumptions.
Until eventually a fixed and very fragile outcome is reached. The so-called first release. Everything is well balanced and based on assumptions I have made based on the information I have been given along the way.
Turns out though my first assumption was wrong.
Now the engineering comes in. Make it look like my first assumption wasn’t wrong, but it was falsely communicated to me. Blame others for my own failings. It called human engineering and it’s great fun.
What about your simple Go server or FastAPI server. Probably yes.
You can:
Use Next.js (frequently changing lots of transitive deps, suffers from Node ecosystem churn too)
Roll your own framework
OR (FANFARE....)
Use simpler arguably more professional tools. That 10 year old .NET MVC site. Guess what. Still works. Still secure.
I suppose that's one way to look at it.
Patient: Doctor, it hurts when I do this.
Doctor: Don't do this than.
The big frontend frameworks have great backward compatibility and usually provide codemods that automatically update your project.
If you install UI components and other libraries that might get abandoned or have breaking changes in major version updates you might have to put in more effort, that's not different in Go or Python.
Compare that to something like jQuery where all the edge cases have already been accounted for 10 years ago.
People who don't "over engineer" also don't track errors. So you might be losing a bunch of users because your website is broken on their devices, and you'll never know. You can't repro it because your locale doesn't match theirs.
It's not like you are always writing better code than the open source projects are. Unless you are one of the best developers in the world, then sure, then that might work, but for the rest of us, we are probably not guaranteed to ever write code that is 100% bug free for five years.
Security vulnerabilities grow in unattended code then?
Or they were there from the second the code was written but with some luck someone noticed them and fixed them?
Old code isn't necessarily insecure just because it's old...
You want me to believe that in the npm "ecosystem" they have LTS branches that only get security updates? For anything besides maybe a few large libraries with companies behind them?
Same, except I skipped Python and went with bash (https://gist.github.com/lelanthran/2634fc2508c93a437ba5ca511... if you're curious).
If I had to do it again, I'd go with Python, but because it started off as a small 5 line shell script I thought "Why bother with Python?".
most of it from my observation is people justifying their own roles, where the real value they bring is arguable imo
Then came linters and everyone hates me. But you know the codebase is slightly less buggy/shitty thanks to them.
The funniest thing to me is people thinking they don't need tests, linters, type checkers, because they're so good at it.
I have my personal website running on svelte. When I decided to have a blog, I quickly came up with a solution to use markdown to html converter and just added a couple of routes to existing setup and voila, the blog is up and running. I don't care that it depends on several packages. Publishing a post takes just a push to my repo.
They said at the start they were going on personal experience. I relate deeply to what they're saying: it's most definitely not a rant/beef against another project/client, it's most definitely the learnings of someone who's been producing personal websites for decades, has kicked themselves a few times in the process and can sarcastically poke fun at their journey in front of others.
my latest attempt was to see if one of the LLMs could do it. nope.
I’ve thought about starting from scratch but don’t have the time
Migrations randomly fail, schema changes are a nightmare, and your team forgets how SQL works.
ORMs promise to abstract the database but end up being just another layer you have to fight when things go wrong.
(when it is not lower, then it is because there are sec framework and other fields that might not be mapped directly do the prisma schema)
You can see the related issue with more info:
And schema changes and migrations? With ORMs those are a breeze, what are you're on about. It's like 80% of the reason why we want to use ORMs. A data type change or a typo would be immediately caught during compilation making refactoring super easy. It's like a free test of all queries in the entire system. I assume that we're talking about decent ORMs where schema is also managed in code and a statically typed language, otherwise what's the point.
We're on .NET 8+ and using EF Core.
First thing I noticed was that I couldn't roll an SQL statement by hand even though I had a distinct memory of being able to do so in the past.
I went with an ORM and eventually regretted it because it caused insurmountable performance issues.
And that, to me, is the definition of a senior engineer: someone who realised that they've already forgotten some things and that their pool of knowledge is limited.
What they are not for is crafting high performance query code.
It literally cannot result in insurmountable performance issues if you use it for CRUD. It's impossible because the resulting SQL is virtually identical to what you'd write natively.
If you try to create complex queries with ORMs then yes, you're in for a world of hurt and only have yourself to blame.
I don't really understand people who still write basic INSERT statements. To me, it's a complete waste of time and money. And why would you write such basic, fiddly, code yourself? It's a nightmare to maintain that sort of code too whenever you add more properties.
At my day job everyone gave up on attempting to use the awkward ORM dsl to do migrations and just writes the sql. It’s easier, and faster, and about a dozen times clearer.
> I don't really understand people who still write basic INSERT statements
Because it’s literally 1 minute, and it’s refreshingly simple. It’s like a little treat! An after dinner mint!
I jest, I’m not out here hand rolling all my stuff. I do often have semi-involved table designs that uphold quite a few constraints and “plain inserts” aren’t super common. Doing it in sql is only marginally more complex than the plain-inserts, but doing them with the ORM was nightmarish.
You completely changed my perspective on simple SQL housekeeping. https://m.youtube.com/watch?v=qYPW3O6VhXo&t=48s
Moreover, the market promotes specialization. The other day I had a conversation with a friend who is rather a generalist and we contrasted his career opportunities with those of a person I know who started out as a civil engineer, but went into IT and over the course of about four years specialized so heavily in Angular, and only that, that now makes more than the two of us combined.
He can't write an SQL statement - I'm not sure he was ever introduced to the concept. How does that feel?
.extra()
?Here's the thing. In five of six companies I have worked at, this story is the exact same. Python, Ruby, Elixir. Passing around ORM objects and getting boundaries mixed leading to more interdependencies and slower velocities and poor performance until a huge push is required to fix it all.
Querysets within a domain seems fine, but when you grow, domains get redefined. Defining good boundaries is important. And requires effort to maintain.
For greenfield projects, you have a chance of splitting the codebase into packages with each one having its own model, migrations and repository, and if you want to cross these boundaries, make it an API, not a Django model. For existing projects this is hard to do most of the time though.
The other thing that's interesting about Django is that you can subclass queryset to do things like .dehydrate() and .rehyrdrate() which can do the translations between json-like data and orm representations.
Then replace the model manager (in Django at least) with that queryset using queryset.as_manager().
If you're trying to decompose the monolith, this is a good way to start -- since it allows you an easier time to decompose and recompose the orm data.
The simplest can just be:
def dehydrate(self) -> List[int]:
return list(self.values_list("id", flat=True))
def rehydrate(self, *pks) -> Self:
return self.filter(id__in=pks)At that scale any tool will break down without good architecture, ORM or not.
people forget how sql works??? people literally try to forget on how to program
more and more programmer use markdown to "write" code
My personal opinion is that ORMs are absolutely fine for read provided you periodically check query performance, which you need to do anyway. For write it's a lot murkier.
It helps that EF+LINQ works so very well for me. You can even write something very close to SQL directly in C#, but I prefer the function syntax.
But as someone who writes both raw SQL and uses ORMs regularly, I treat a business project that doesn’t use an ORM as a bit of a red flag.
Here’s what I often see in those setups (sometimes just one or two, but usually at least one):
- SQL queries strung together with user-controllable variables — wide open to SQL injection. (Not even surprised anymore when form fields go straight into the query.)
- No clear separation of concerns — data access logic scattered everywhere like confetti.
- Some homegrown “SQL helper” that saves you from writing SELECT *, but now makes it a puzzle to reconstruct a basic query in a database
- Bonus points if the half-baked data access layer is buried under layers of “magic” and is next to impossible to find.
In short: I’m not anti-SQL, but I am vary of people who think they need hand-write everything in every application including small ones with a 5 - 50 simultaneous users.
Personally, from the database-ops side, I know how to read quite a few ORMs by now and what queries they result in. I'd rather point out a missing annotation in some Spring Data Repository or suggest a better access pattern (because I've seen a lot of those, and how those are fixed) than dig through what you describe.
On the other hand, I agree that mapping SQL results to instances of shared models is not always desirable. Why do you need to load a whole user object when you want to display someone's initials and/or profile picture? And if you're not loading the whole thing, then why should this limited data be an instance of a class with methods that let you send a password reset email or request a GDPR deletion?
I know exactly what's going on, while getting some level of idiocy protection (talking about wrong column names, etc).
It is not that JPA is inherently bad, it's just that such projects lack strong technical leadership.
>- Bonus points if the half-baked data access layer is buried under layers of “magic” and is next to impossible to find.
It’s really funny because you’re describing an ORM perfectly.
My ORM does extremely much more than those "SQL helper" classes and it logs SQL nicely to the console or wherever I ask it to to log.
And it is easy to find it, just search for @Entity.
I poorly implemented SOLID design principles, creating a complete mess of a SQL Factory, which made it impossible to reason about the query unless I had a debugger running and called the API directly.
Complex queries I write myself anyway, so Claude fills the 'ORM' gap for me, leaving an easily understood project.
But seriously, yeah, every time I see a complaint about ORMs, I have to wonder if they ever wrote code on an "average team" that had some poor developers on it that didn't use ORMs. The problems, as you describe them, inevitably are worse.
For example, I'm working on a project right now where I have to do a database migration. The project uses c# entity framework, I made a migration to create a table, realized I forgot a column, deleted the table and tried to start from scratch. For whatever reason, entity framework refuses to let go of the memory of the original table and will create migrations to restore the original table. I hate this so much.
There's also the reality that no two ORMs may be built to the same way and performance standard.
If a dev thinks that all SQL can be written by hand then they probably haven’t worked with a complex application that relies on complex data.
A good question to ask them is: what problems do ORMs solve? Good answers are:
Schema Changes + migration
Security
Code Traceability (I have a DB field, where is it used)
Code Readability
Standardisation - easy hiring.
Separation of data layer logic and application layer logic.
Code organisation, most ORMs make you put methods that act on a table in a sensible place.
I’ve used Django, SQLalchemy and Hibernate. All three have good migration stories.
I've worked with devs who hated on ORMs for performance issues and opted for custom queries that in time became just as much a maintenance and performance burden as the ORM code they replaced. My suspicion is the issues, like with most tools, are a case of devs not taking the time to understand the limits and inner workings of what they're using.
More specifically a GraphQL-native columnar database such as Dgraph, which can leverage the query to optimize fetching and joining.
Or, you could simply use a CRUD model 1:1 with your database schema and optimize top-level resolvers yourself where actually needed.
Prisma can also work, but is more susceptible to N+1 if the db adapter layer does separate queries instead of joining.
It's hard to find similarly mature and complete solutions. In the JS/TS world, I like where Drizzle is going, but there is an unavoidable baseline complexity level from the runtime and the type system (not to criticize type systems, but TS was not initially built with this level of sophistication in mind, and it shows in complexity, even if it is capable).
Sql does not really needs fixing. And something like sqlc provides a good middle ground between orms and pure sql.
table=db.table("table1")
table.insert({"col1": val1, "col2": val2})
at the very least, if you are really writing lots of INSERTs by hand I bet you are either not quoting properly or you are writing queries with 15 placeholders and someday you'll put one in the wrong place.ORMs and related toolkits have come a long way since they were called the "Vietnam of Computer Science". I am a big fan of JooQ in Java
and SQLAlchemy in Python
Note both of these support both an object <-> SQL mapper (usually with generated objects) that covers the case of my code sample above, and a DSL for SQL inside the host language which is delightful if you want to do code generation to make query builders and stuff like that. I work on a very complex search interface which builds out joins, subqueries, recursive CTEs, you name it, and the code is pretty easy to maintain.
Inspect the actual SQL query generated, and if needed modify ORM code or write a SQL query from scratch.
Object-relational mapping (ORM) is a key concept in the field of Database Management Systems (DBMS), addressing the bridge between the object-oriented programming approach and relational databases. ORM is critical in data interaction simplification, code optimization, and smooth blending of applications and databases. The purpose of this article is to explain ORM, covering its basic principles, benefits, and importance in modern software development.
They had a reason, an I'm sure it had some merit, but we found this out while tracking down an OOM. On the bright side, my co worker and I got a good joke to bring up on occasion out of it.
If you want a maintainable system enforce that everything goes through the ORM. Migrations autogenerated from the ORM classes - have a check that the ORM representation and the deployed schema are in sync as part of your build. Block direct SQL access methods in your linter. Do that and maintainability is a breeze.
Let's you do what you want here and now and then pay dearly for it afterwards :-)
In the hand of a good team, ORMs and migrations are an unbeatable productivity boost.
Django is best in class.
It's like asking "I'm new to driving, what brand of nitros should I be using"
Nah dude, get your sea legs first
The first question I posed to the Erlang community was exactly that: what are the build tools, what are the unit testing frameworks and how is a project setup.
Not because I didn’t know what these tool/concepts did but because I wanted to know what is the state of the art in Erlang tooling.
I have my sea legs, including the wooden one, but just not yet in Erlang. Why Erlang? Because it’s completely different to everything else!
Frameworks solve these problems efficiently. Sure, some frameworks can be overly complex (I'm personally not a fan of Next.js), but that's a problem with the specific framework, not the idea of using a framework at all. But many frameworks make things much simpler and let you avoid reinventing the wheel. You could write your own scripts (in practice a mini-framework) but eventually you'll hit limitations, especially as your project grows or you start working with others. At that point, you'll probably end up switching to an established framework anyway.
If you're already using something like PHP with server-side rendering and templates, that's fine too—you've just chosen a different kind of framework (it is still some kind of framework. Just not a client-side one). I just don't buy into the idea that avoiding all build steps and frameworks is somehow more "pure." It feels a bit like a hipster take: "I'm going to write everything from scratch and avoid all tools just to show that I can."
And from the linked post on the same website.
> if you write vanilla HTML, CSS, and JS, all you have to do is put that code in a web browser and it runs.
Very (very, very) few large projects use plain JS (instead of TS) these days. Let's stop acting like all these people don't know what they're doing.
This post is probably applicable to selected tiny and small projects. And for some of those, it may be better if there was no JS at all.
There are much better arguments to use TypeScript than "five billion flies can't be wrong". Most other popular tech choices are in fact rather silly.
They certainly have their reasons and they definitely aren't stupid, but it would be more useful to know what those reasons are and in what scope they are applicable.
More recently, see how there's a strong push towards types in Python. AI/ML is to Python what the internet was for JS. And types are here.
While there is sometimes good reason to use TS, often you might be better served using JSDoc so you have type safety without the compilation step.
I currently see the direct comparison as my company has one project that uses old-school php backed rendering with a bit of vanilla js sprinkled it and one with modern React and TS. The React team is significantly less productive and the code is much harder to maintain, has more bugs, is less performant and harder ton onboard people to. But when I suggest that a new project does not not need to be a SPA, I always get booed.
JSDoc would be unequivocally the superior choice if the browsers themselves hadn’t begun to make just opening the html file problematic by requiring HTTP origins for various parts of the API.
1. be multiple developers on the same project.
2. for each developer, use your own tools and techniques, insist on only handling those parts of the site that you did with your tools, and insist on never fully understanding those remaining parts of the site the other devs did.
This will allow for all sorts of fun, including:
- A multiple inconsistent implementations of the same thing
- B even better, those multiple inconsistent implementations affecting and breaking each other!
One you have this going, there are some easy bonus pickings: Whenever B happens, "fix" it with weird extra incancations inside your own toolset, cleverly avoiding any attempt at (2) above.
If you succeed at this, several developers can, combining these techniques to sabotage and trigger a veritable pinball game of strange breaking effects.
Note: CSS is a great place to start this game!
Here's some more:
- People only visit your personal website knowing they can personally read, understand, audit and approve every single line of code that ever went into it. This means you don't really have a personal website unless you meticulously wrote every single line and every single change is clearly described and accessible on github (and sourcehut, and forgejo, and the rest. What sort of monster uses only Github nowadays?)
- Remember to explain every single self-doubting existential thought that went into producing (or not producing) your website: people aren't there for objective, intellectual, educational tech content, they're probably more interested in self-deprecating metacognition.
- Install a rolling release distro by hand
- Install stuff without using packages or configuration management by hand without documenting them
- Install stuff on bare metal without using containers or a hypervisor. Bonus points for unlabeled spaghetti patch cable rat's nest.
- Don't automate deployment or upgrades
- Don't have backups of anything
- Don't have a plan for patching, DDoS mitigation, or DR/BCP
Collect every metric possible and set up arbitrary blanket alerting thresholds and black-box anomaly detection and tune nothing ever. Now you can hire a whole team dedicated just to suffering from alert fatigue.
Standardize on a single LTS OS release across all your infrastructure and wait until the absolute last possible second to start trying to switch to the new current LTS release, biting off about a decade of OS changes to everything everywhere all at once.
I have a hard time believing that writing vanilla JS is superior to using a compiled language in any but very simple cases. Seems like bad advice to me.
my_script.toString();
Boom, strongly typed code with no compile step that executes in both Node and the browser.Now, what if a dependency does break? Well, you can replace it with another dependency, or you can write one from scratch. Using dependencies allows you to save time earlier, and then only spend time writing your own libraries once you hit a roadblock.
2. Frameworks are similar to dependencies. They allow you to save time at the beginning of projects when you're not fully aware of your requirements, and then you're free to write from scratch when you have enough users and resources to do so.
3. Compilation is lightning fast these days because many tools are written in Rust. Projects built using Vite, for example, take a few seconds to build on a 10 year old laptop.
To summarize, these things don't result in websites that will require a lot of time and energy to maintain.
The problem is when looking at it 10 years later I want to rebuild it from scratch because the code and build system look so different than what we do now. I'm not sure yet if it will take a long time though, at least if I accept to keep jquery and avoid typescripting everything.
Rewriting things from scratch is something that everyone wants to do as time passes, regardless of the tech stack used initially.
For example, I'd rather install React Router for routing in a React app instead of writing my own routing library. I guess some people will reply "grrr React, just use static HTML bro". Okay cool.
How will you know if/when that happens?
Are you subscribed to the development channels of all your dependencies? Do you examine every one of their commits for security fixes?
For example modern compilation may very well be faster than in the past, but your application and experience could be still even faster without compilation.
Frameworks also come at a substantial cost. They are highly restrictive, super massive, and almost always unnecessary. I can understand why people use them, but again your application and experience could be dramatically faster without them. People tend to prefer frameworks when they lack the confidence to build without them, but for those of us that frequently measure things large frameworks are always a net negative.
I doubt it. Compilation actually improves developer experience and speeds up the process of releasing apps because you have a standardized way to release your app to production.
I seriously can't understand the hate against compilation because it's never been a roadblock for me, especially these days when most builds take a few seconds on slow CPUs. I guess it's cool to hate things for no reason.
> Frameworks also come at a substantial cost. They are highly restrictive, super massive, and almost always unnecessary.
This is highly subjective. Frameworks have been nothing but a huge productivity boost for me. For example, I can spin up feature-complete API using FastAPI in a few hours instead of spending weeks building my own framework to do the same thing.
> People tend to prefer frameworks when they lack the confidence to build without them
Doubt it. People mostly choose frameworks because they want to get work done instead of wasting their employer's money on non-profitable endeavours.
> for those of us that frequently measure things large frameworks are always a net negative
Could be that you're measuring the wrong thing. At the end of the day, engineers need to ship features so that the company can generate revenue. Frameworks are great at facilitating that process. I'm no Math expert but this seems like a net positive to me.
> This is highly subjective.
It is measurable.
At the end of the day actual engineers measure things. Junior developers deliver features.
Nobody is stopping you from gathering numbers. Again, that is the difference between an actual engineer and a junior developer.
Hand code everything, including the protocol encoders/decoders, dialogs etc.
Use a framework that is brand new and full of shiny new bugs you can spend months of enjoyable time fixing, until the framework is dropped by the developer(s) and you can recode everything to the next new and full of shiny new bugs framework. Repeat infinitely.
Also pick a shiny new programming language FooBar, to write both the server and client, that "really soon now!" will have all the libraries and bug fixes you need to use it in production. Spend time writing all the missing libraries and contributed it to the 5 other developers using the language. Spend hours complaining on HN that other developers are too stupid to realise the obvious benefits of rewriting everything in FooBar.
epolanski•6mo ago
Even admitting one wants to go with bare bone web components authoring and maintaining them is expensive, requires lit or something.
Thus, what's the solution? Some sort of templating? Again, you're bringing on dependencies.
DocTomoe•6mo ago
A classical example might be https://www.npmjs.com/package/is-odd
Phemist•6mo ago
Anyway, to include this package as a dependency is indeed overkill. I would most likely opt for vendoring this package into the project (including licenses and acknowledgement), as the code is unlikely to change and is MIT licensed.
johannes1234321•6mo ago
kome•6mo ago
honestly ctrl+c, ctrl+v of hand written html. and i'm cool as a cucumber.
epolanski•6mo ago
But wait, now you want to add an active state to your navigation links, and you're manually changing the `class="active"` in 12 different files...
I could go on, it doesn't scale beyond triviality, albeit LLMs do help speeding up.
johnisgood•6mo ago
nottorp•6mo ago
epolanski•6mo ago
And you went from a simple nginx extension to again full blown software.
johnisgood•6mo ago
porridgeraisin•6mo ago
ghusto•6mo ago
If your "dependency" is yourself because you wrote your own template for your specific needs, is that still a dependency?
I wrote a templating solution for my own repeated sections and I'm so glad. It does exactly what I need, it's simple for me to understand if ever it grows large and I need a refresher, and easily expandable.
aDyslecticCrow•6mo ago
A small amount of PHP as a templater for simple raw HTML and JS segments is pretty nice.
fragmede•6mo ago
lelanthran•6mo ago
I side-stepped that completely, even on actual production web apps for clients, with this: https://github.com/lelanthran/ZjsComponent
Now, you may argue that that is a dependency, but it doesn't have any of its own, you can make a copy of it, serve it from your primary domain, and you're done.