8 ms·
I Hate NestJS
- Bexar 3y ago[flagged]
- sir_pepe 3y agoRE decorators in TypeScript: it is true that TS code does not have to live in classes... in general. But some APIs (eg those for custom elements) _do_ require classes, so one may end up writing a whole bunch of classes anyway. And in this case, decorators are in fact quite useful.
- mock-possum 3y agoLove me some decorators for defining web components in TS
- Timon3 3y agoRegarding TypeORM - recommending Prisma feels a bit like throwing out the baby with the bath water. If I'm reading their Github issues correctly, they are slowly starting to use JOIN statements in their generated SQL. It may be fine for an ORM to perform local joins during alpha, but anything after that really should use the features DBs provide for these kinds of basic things. I've heard good things about Drizzle.
- deleted 3y ago[deleted]
- dsego 3y agoDrizzle seems a bit low level. Reading the docs I see a thin DSL for schema definitions and a query builder, which seems to return plain objects.
- dsego 3y agoJust looked at it again some more and it infers data types when returning data.
- bro_rabbit 3y agohttps://mikro-orm.io/ https://mikro-orm.io/ is pretty nice.
- frodowtf 3y agoKysely looks like the thing most people would want. It's not a full ORM though - just a well-typed query builder. https://kysely.dev/ https://kysely.dev/
- bdcravens 3y agoBoth the original and this followup article both say: "Last Updated: 1 year ago" I would much rather see real dates, to get a feel for how long this change of opinion took. (if you inspect, you see the actual date is 8/28/22, but the original doesn't show the original date, only the last updated date of the same day)
- starbugs 3y agoI'll say it: NestJS is pure evil. It pushes OOP beyond its absolute limits. Not that I would consider OOP a good way to do things in general. Beyond misleading autocompletions that look helpful at first glance, it's usually somewhat counterproductive in any language and with any framework I have ever encountered. But NestJS manages to make it pure pain and sadness. It's like a framework that spins around its own "architecture" making it nearly impossible to get stuff actually done. Pro tip: If you find a paragraph celebrating "SOLID principles" at the beginning of the documentation of something, run.
- cosmosgenius 3y ago"Not that I would consider OOP a good way to do things in general" this statement doesn't make sense to me. My normal mental model for design in usually "Objects" with message passing. How is OOP bad in general?
- starbugs 3y agoPlease watch the video linked in the article. It explains it way better than I ever could in a comment: https://youtu.be/QM1iUe6IofM https://youtu.be/QM1iUe6IofM TLDR: The main culprit is encapsulation at a granular level. Explicitly associating functions with data types systematically. A side note: I personally think this applies to "OOP as done in the industry". There are exceptions. Erlang for example.
- jokethrowaway 3y agoSmalltalk OOP is good, I'd argue nowadays OOP in modern lingo is not objects and message passing anymore (call it actor model if you want to be understood) but C++ / Java classes. Namely I would say: - Inheritance: bad because adding layers makes it harder to understand what code is running - favor composition instead - Encapsulation: bad because it encourages mutable internal state and couple functions with data - favor immutable state Plenty of practices of doing good OOP are all about doing less OOP (eg. Avoid deep inheritance hierarchies).
- 3y ago
- ilrwbwrkhv 3y agoJavascript adopting the class keyword was really bad. What a bizarre language which added something as syntactic sugar in the language but it's a paradigm.
- pcthrowaway 3y agoI don't understand this perspective.. people were already using class semantics in JS before the class keyword; but there was so much inconsistency in the patterns they were using to (ab)use Javascript's prototypal inheritance to emulate classes. The class keyword brings together a 'best practice' set of pre-existing JS features to provide a uniform OOP experience. Yes, classes still work a little bit differently than they do in other languages, but the benefit of being able to expect the same type of class from modern JS libraries doesn't get appreciated enough. The only drawback I see to its addition is that it abstracts prototypal inheritance and some other key idiosyncrasies of Javascript from newcomers to the language. But the move away from doing things 'the old ways' has worked out much better for Typescript adoption anyway, as it's hard to type things properly when the interface of an object created by a custom 'class' function is just 'whatever the prototype currently has'
- starbugs 3y agoClasses are not the problem. Please watch the video linked in the article. It's gold: https://youtu.be/QM1iUe6IofM?t=93 https://youtu.be/QM1iUe6IofM?t=93
- thoweradf234 3y agoI believe the target demographic for NestJS are spring developers, not native JS/TS developers. If you come from Java / Spring you would feel right at home, anyone else would feel disgust.
- NoNameProvided 3y agoThe target audience also includes Angular developers. NestJS emulates several aspects, such as modules, that it doesn't necessarily need to mimic Angular's appearance. I cannot pass judgment on whether this is good or bad, but I can easily see how this familiarity can be beneficial for the average programmer.
- flashback2199 3y agoThis exactly, and Angular also. It is pointless for the author to argue about the best way to use TypeScript because the value proposition of NestJS is to use the same patterns as another framework you are already using. If you're building a React app, for example, then NestJS doesn't make as much sense, it's just going to feel like it's getting in the way, hence this article. This article really misses the mark and the author is just proving that they still don't understand what NestJS is for.
- stillbourne 3y agoAs a C# guy I liked NestJS as well. Like some of the things he describes as hating are the things I liked about it. I wrote a whole ass SAML server in NestJS, it was one of my favorite projects. NestJS is more than just GraphQL.
- tehlike 3y agoSame here, former C# developer, who worked with (as a contributor) Monorail, ASP.NET MVC, Windsor, NHibernate. I feel right home. TypeORM is terrible, however. Prisma is probably way to go.
- kldavis4 3y ago> That surface-level judgement is as naive and nubile as it gets. Just a minor editorial comment... you might want to check the definition of 'nubile'
- catlover76 3y agoMaybe he does know it ( ͡° ͜ʖ ͡°)
- appplication 3y agoIn my early 20s, I volunteered to be a figure drawing model. The class was run out of the domicile of an older fellow named Arthur, who lived off the coast of the Big Island in what would best be described as an art shack. It was more screens and windows than walls, but you can get away with that quite comfortably there. The class itself a group of maybe 10-15 drop ins from the local commune, a mix of mostly straight women in their 20s and gay men in their 50s. It wasn’t really a formal class, more just the sort of thing that comes together when you’re surrounded by whimsical folk. It was fun being the center of so much attention and so many playful quips. It was my first time, but the instructor Arthur said I was doing well and asked if I had any experience. Naked and near completely upside down, told him no, I was quite nubile. He asked if I meant a noobish. I doubled down and told him, no, I’m nubile, but excited to learn. He smiled at me, and gave me quite the flirtatious look. I had no idea until weeks later when I learned the distinction. Sadly, a few years later Arthur passed away quite suddenly. I’m always reminded of that experience every time I hear the word, and doubly so when it’s mistakenly used.
- kldavis4 3y agogreat story - thanks for sharing!
- jansommer 3y agoI like the part on tests. No need for dependency injection when you can just override/spyOn the functions. Most people in the .NET world uses DI, causing a lot of smaller classes where code is dubiously grouped. And my god, all the interfaces where every use of that could just as well be the class version. But we have to use DI, because (1) people look at you like you're insane if you tell them you don't like it. And (2), we also don't want to pay for commercial software like JustMock (not affiliated) or VS Enterprise (also not affiliated), that supports mocking static methods. I think that in lack of a free, maintained and widespread library for this, C# ends up with the mess the author describes. It's a shame, because there's nothing wrong with the language itself. Because of (1) it's a struggle to convince anyone to buy (2). And would be silly to expect someone to provide it for free.
- catlover76 3y agoI remember back when I was working at a startup that used C# and then moved to a different startup where I was responsible for choosing framework, so long as it was NodeJS. Back then, the back-end TypeScript ecosystem was very small. A couple of the frameworks used IoC and DI, which of course were a standard feature of the C# back-end I had worked on. But I never really understood what IoC and DI were for, so I didn't use one of the bigger TypeScript frameworks that used them. At the time, I thought I was dumb for not understanding the point of those things, but now, years on, I think those things really are just unnecessary. I do like C# btw and would be happy to work with it again.
- cjalmeida 3y agoDI, at least in Java is a way to avoid rolling your own custom code to add dinamicity to the language. As you point out, JS, TS and Python are dynamic enough to not need those.
- gemstones 3y agoI'm very curious to hear from someone who likes DI in a non-OOP language - why? What techniques do you use to make the level of indirection feel like a help, rather than a hindrance, in your codebase? Reading this article reminded me that DI has a lot of advocates, but I've never heard a compelling reason to use it in most codebases.
- starbugs 3y ago* Keeping a function easy to understand without having to think about the rest of the codebase * Minimizing non-local state * Keeping things testable * Keeping code reusable without having to find and copy a lot of other code from a codebase/refactor completely Note: I am not talking about DI frameworks here, because I don't like them.
- BlackFly 3y agoHow else are you going to manage dependent options of an algorithm but to inject the dependency inside of its configuration? Say in rust, you have some struct backing a trait. But your implementation of the trait can also have a variety of options which are parameterized by some other trait. You end up with a generic struct: that is all dependency injection is. Every generic struct in rust is an example of dependency injection. Instead, dependency injection frameworks help people instantiate large dependency graphs with some lifecycle management. Those I am a bit of the take it or leave it opinion.
- starbugs 3y agoIn an OOP codebase, what I usually find is an if or switch with some enum which then calls something along the lines of SomeManager.shared.whatever(). Sorry for being cynical. I can't help it.
- BlackFly 3y agoYou see that in OOP codebases where the authors don't know any compositional patterns. Then the only way to thread logic together is statically, so singletons and the enums like you mention.
- rafaelflores 3y agoIf you found this problems in nestjs then most of them should be in Angular as well. As it is explicitly told in the documentation that Nestjs is a copy of the frontend framework.
- NoNameProvided 3y ago> For a long time NestJS depended on class-validator ... and regularly suffers from security vulnerabilities that can take years to fix. As a maintainer of class-validator, I'd like to clarify that this is not accurate. Legitimate security issues, when reported, are promptly addressed. The multi-year security alert listed in NIST NVD is akin to the bogus report that the curl maintainer discussed a few months ago. In a nutshell, the report suggests that specific settings can potentially lead to validation bypass, which is indeed the case because these settings determine whether unknown objects should fail or pass the validation. This is analogous to my creating a CVE for Windows simply because anyone can access my computer when I haven't set a password. However, the other part about the scare support is sadly true though.
- crubier 3y agoFinally someone said the words! NestJs always seemed like pure architecture astronautics, managing to be at the same time completely over engineered, and a copy of concepts from 2005 Java systems, in the worst way. I have absolutely no idea why anyone would use NestJS, short of being used to writing dumb enterprise Java for the past 20 years or not wanting to move forward from it. What a relief, I’m not alone feeling this way
- zoover2020 3y agoHonestly, who cares? Corporate engineers using NestJS to move POJOs around is not hurting anyone. As always, pick the right tool for the right job - let's stop the cargo-culting.
- ajxs 3y agoRecently I did some work on a project that was originally built using the LoopBack Typescript framework [0], and it suffers from all of the same issues as NestJS. I wouldn't recommend anyone use either framework. There's really no need for dependency injection in NodeJS. The problems DI solves in other languages can be better solved in NodeJS by other means. 0: https://loopback.io/doc/index.html https://loopback.io/doc/index.html
- sakesun 3y agoI worked on a project using LoopBack 2.X in 2017. An awful experience for me.
- chaostheory 3y agoI feel that the only devs who feel at home with nestjs are angular devs since nestjs looks like angular retooled for server side work
- davedx 3y agoI saw a recruiter trying to hire a dev with 7 years of NestJS experience the other day. It takes all sorts
- deadlyllama 3y agoI've been using NestJS this year and (mostly) found it great for the use cases I've had. I'd rather describe the HTTP to method call mapping of my controller with decorators than a bunch of "add endpoint" calls. I like that the HTTP to code binding is located right beside the code itself. I like that I can separate my app up into modules and couple them as loosely or tightly as I need. You can architecture astronaut with NestJS, but you don't have to! I wrote a queue module (to interface with a legacy queue system), using decorators to specify the consumer. Docs on doing this are essentially nonexistent. The NestJS based library I cribbed from spread the "find the object & method to call" logic across multiple classes. I distilled it down to a screenful. As with all tools, you get some choice in how you use it. Want to go wild with dependency injecting a zillion classes with one method each? If you really want to, I guess you can. Want to be sensible, for your definition of sensible? You can do that too.
- bastawhiz 3y agoI don't use Nest or have strong feelings about it, but this bit stuck out: > TypeORM is not even typed. When you run a .findOne() method is just passes back a generic. This is patently false. I'm not sure what the author is even trying to say here, but the output of `Foo.findOne(...)` is `Promise<Foo | null>`. If it's not, there's a good chance you're coloring outside the lines. Maybe this is true in the context of NestJS, but it is not true for typeorm on its own.
- itslennysfault 3y agoI thought the same. It's not true with TypeORM in Nest either. If you're using DI it's basically impossible in Nest. constructor( // this is the only way to get a repository for the photo table/model private photoRepository: Repository<Photo>, ) { } getPhoto() { // this would be type Photo const photo = this.photoRepository.findOne(); }
- beart 3y agoYou can inject a TypeORM data source which is non typed and create a query builder, but as pointed out, it's opt in.
- ljm 3y agoSo... Decorators are higher order classes. Dependency injection (i.e. inversion of control) is not standard OOP. DI is not the only way to do composition in OOP. OOP gives you the choice of both inheritance and composition. Look at any Python, Rails, or Smalltalk codebase and you will see that things are both composed and inherited. This post is just a rant. NestJS doesn't work for you? Don't fucking use it, no reason to hate.
- starbugs 3y ago> This post is just a rant. NestJS doesn't work for you? Don't f*** use it, no reason to hate. No reason to swear either. The article has an emotional title. The title explicitly says that it's a rant. It's literally about the author's emotion towards NestJS. I don't get the point of your comment. You don't like the article? Don't read it!
- DrammBA 3y ago> No reason to swear either. This is the internet, it's okay to swear.
- rzzzt 3y agoIs there an RFC out for this one?
- zoover2020 3y agoMUST swear
- dylan604 3y agoit's been in the working group since the 90s, around the time <blink> was introduced. it just can't seem to be ratified into the official spec.
- ljm 3y agoThere was a whole post to comprehend that you dismissed because you didn’t like the naughty word.
- moogly 3y agoStorytime. When the company I work for hired a person who was super excited about NestJS, I looked at it with an open mind (or so I'd like to think). I was probably a bit sceptical because this person, who seemed really nice, couldn't think of a single thing he disliked about it (that's a question I tend to ask about any tech that someone is all-over-the-moon about, and my thinking is that if you can't list a single thing you dislike about something, you probably don't know it well enough), but let's take a look at it! As soon as I saw they had basically copy/pasted the Angular 2+ module system into Node.js, and went full-hog into IoC, I decided not to even try it out. The same Angular 2+ module system that basically was copy/pasted from AngularJS and that I had actually ripped out of our huge AngularJS app at our previous job because it caused more friction than it solved, and lo and behold, the tests became simpler when we didn't have to use ngMock. All those services were singletons anyway and were more suited to being actual JS/TS modules. But AngularJS had a valid reason for it because it was back in forever-ago and there were no JS modules, much less dynamic imports for code-splitting. Not that you need code splitting for a backend app. I have never felt I needed DI in a Node.js app. NestJS - not even once.
- yellowviking 3y agoJavaEE has been using similar pattern for decades, somehow nodejs developers it's world changing and every startup on the planet is onboard with its ecosystem.
- anaxag0ras 3y agoWhy would you shoehorn practices from Java on Nodejs? A lot of those patterns would be unnecessary on JS. At the end of the day, those patterns were created to keep things maintainable, not just use them for the sake of it.
- robinjhuang 3y agoDependency injection is still tremendously helpful in writing unit tests.
- moomoo11 3y agoAlso not a fan of NestJS, having used it on multiple projects in past job. I'll tell you what. If you must work with NodeJS, IMHO you are best off just keeping things light and simple. NestJS is not good. I've used it professionally a few years ago for several services, and it was overly complicated which would be fine if the performance was okay - but it was not good either. And don't get me started on TypeORM or Prisma (or ORMs in general). So much wasted time and effort hammering down performance issues. The NestJS docs were also not that great and required having to dive into GH issues or source code too much compared to other frameworks. I eventually rewrote the services to use express + kysely + zod + msgpack. There was clear separation of concerns with layers which made both unit and integration testing easy. IMO attempting OOP in JS comes with additional complexity/overhead and performance implications due to overly complex inheritance. When in doubt, KISS.
- beart 3y agoI've done a lot of work with NestJS. I agree with some, but not all, of the authors points. - TypeORM is pretty bad. Particularly when you start using it for more than simple crud operations. There was an epic battle in the GitHub issues and eventually some folks finally got through to the maintainer. Since then, development has picked up and some long-standing issues have been corrected. It's still pretty bad. However, I haven't found anything in the nodejs ecosystem that's substantially better, which is sad. - class-validator and class-transformer mostly work, but are barely maintained and have many issues going back years. The maintainers left a bad taste in my mouth. I asked years ago about why these libraries which are so core to NestJS are not forked. The issue was locked with a frustrating response. It sounds like they may have finally been pursuaded to fork them. - NestJS support is terrible. I understand they have a paid support service but if you don't subscribe to that, they lock, discard, ignore any issues raised, even if they are valid and significant. They push all support questions to Discord, and as far as I can tell, none of the actual maintainers look at it. Very frustrating. - NestJS breaks semver by releasing breaking changes in minor or patch updates. They don't seem to understand that if a core third party dependency has a breaking change, they need to bump their major version. - It's very difficult to understand what has actually changed between versions. And with the history of breaking semver, upgrading is just plain scary. The "release notes" are just the commit list, and to make matters worse, they don't use a monorepo so you have to search through a dozen repositories. Unlike the author, I do actually enjoy the modular design, the dependency injection system, and a few other design choices. The only difficulty I've encountered when testing is around the third party pieces, such as TypeORM.
- NikxDa 3y agoI wonder what the alternatives are. I've searched for a framework that is a middle ground between bare-bones Express and NestJS. Something that I can throw a Zod validator at and it handles the validation for me by default, yet lets me structure my code a bit more functional and less opinionated than NestJS.
- dsego 3y agoSounds like you want Fastify maybe? It still feels bare bones compared to NestJS. https://fastify.dev/docs/latest/Guides/Getting-Started#validate-your-data https://fastify.dev/docs/latest/Guides/Getting-Started#valid...
- pcthrowaway 3y agoAdonis would be an option that's compared a lot to Laravel. I haven't used it enough to have an opinion Redwood may be an interesting full-stack option if you're OK with your backend being serverless
- dsego 3y agoI don't know about Adonis, tried it the other day and followed their guide (maybe it was this one https://adonisjs.com/adonisjs-at-a-glance https://adonisjs.com/adonisjs-at-a-glance). And the second or third command I typed in to create a model didn't work. Turns out it's not installed by default? https://github.com/adonisjs/core/discussions/2642#discussioncomment-3983487 https://github.com/adonisjs/core/discussions/2642#discussion... Not sure, but at this point I don't care, I just trashed it because I don't have time in my life to fool around.
- deckard1 3y agoNestjs is my least favorite framework I've used in the past 10 years. Just a step below RxJS. It's an ORM which means performance you may as well forget it. It's such a memory hog. On top of GraphQL, which can easily cause performance issues on its very own without help thank you very much. It's like the N + 1 problem had a baby with a memory leak. Why devs keep doing this to themselves I'll never understand. You don't need this level of pain for even a massive API codebase.
- BLanen 3y agoYea I refuse to use libraries which use(d) the old typescript decorators.
- teapot7 3y ago> That surface-level judgement is as naive and nubile as it gets. Nubile? Auto-correct mistake? Or just a very strange worldview?
- pragmatic 3y agoPeople miss the point of OOP as practiced (vs what the revered ancients intended). Alan Kay wanted biology and we got it, just the taxonomy system instead of cell biology. OOP with classes is a way to classify and organize code. The problem with the functional paradigm is there’s less clear patterns for code organization. Check out the average typescript project (or just any successful long lived js project) and the code organization is all over the place. Not saying you can’t organize a function and module system, it seems like a bigger challenge.
- warmedcookie 3y agoTrue, good code organization creates patterns and patterns create efficiency because humans are good at following them. When code is scattered and/or inconsistent in its design, I feel less productive. NestJS and similar modular frameworks do a good job at keeping code organized while allowing for scalability.
- vbilopav 3y agoHe hates TypeORM but loves Prisma and Prisma can't even do joins, it's doing N+1 by default and always. What does TypeORM do then?
- madmax108 3y ago> NestJS is one of those things where people coming from other languages like Java don't know how to develop without the patterns that Java gave them. This is EXACTLY how I felt using NestJS. Except, IMO, it took the worst part of Java (Spring DI, esp. the over-verbose, make-changes-in-4-random-files-to-get-an-object style they did it circa early 2010s, instead of the much cleaner styles they have today) and shoved it into a language that is built on a completely different paradigms and constraints. Not had a single pleasant experience working with NestJS, especially once it hits a certain scale, and you are just bogged down running between modules, services, controllers and DI-hell