---
From the OP:
Comparison to Node.js
- Deno does not use npm - It uses modules referenced as URLs or file paths
- Deno does not use package.json in its module resolution algorithm.
- All async actions in Deno return a promise. Thus Deno provides different APIs than Node.
- Deno requires explicit permissions for file, network, and environment access.
- Deno always dies on uncaught errors.
- Uses "ES Modules" and does not support require(). Third party modules are imported via URLs:
import * as log from "https://deno.land/std/log/mod.ts";
* No npm spaghetti, just requiring a URL is a win
* It'll build a lightweight static binary. Usually way smaller than the equivalent node Docker image
* The stdlib and every community lib were written at a time when async/await was the norm. So they're all very nice to use compared to wildly inconsistent node libs
Your comment inspired me to study Deno deeper and consider it for practical use. In addition to the pros you've listed, seamless integration of TypeScript sounds fantastic.
Would love to hear more about how Deno is used in your company!
IMO not really. We have many Java and JS projects where I work, I can't find a single Java project that has bigger dependencies than even our smallest JS project, or even an empty "create react app". One of our Java projects is 200k+ lines and still has smaller dependencies than create react app or a empty project created with angular cli.
In JS, it's normal to pull in 500+ libraries and this is only because the standard library is so lacking. Our Java projects, even massive ones, pull in less than 100.
In Java you also have Guava and Apache Commons. Those cover about 95% of data structure needs for a project not covered by the JVM. JS has nothing comparable.
People lament about how "big" the JVM is, but you trade complexity of the VM for complexity of your own app. In practice Java projects are smaller and use less space and memory because your dependencies aren't using 10 different libraries to pad whitespace.
This also makes it much easier to mentally transition between Java projects. If they were built in the last decade, they're probably using the standard library, Guava/Commons, hibernate, and some HTTP interface. I can move between Java projects at work no problem, but if it's Node or front-end 90% of the time I'm going to spend a few days learning a new framework to get anything done.
Small standard libraries are very harmful to the ecosystem. I hope to God they do it right with Deno, batteries included like Python and Java
My experience with Java projects is >1GB in RAM usage minimum (although it's been a couple years since I've written Java, so I don't know what improvements the JVM has made) whereas a Node app can run just fine on <100MB.
Again, conflating Node.js backend and JS front end apps is not a fair comparison to Java as a backend platform. Stick to apples and apples.
Node.js has quite a few standard libraries, although it's very common to use a framework like Express (and Express has been the top framework on Node.js since the earliest days of Node). The most difficult thing about going back to an older Node code base is that promises weren't officially supported, so there's often a 3rd party library for that or callbacks were used instead.
The main benefit of Node.js to me, remains the use of a single language across the front end and back end. You can often use the same libraries so you suffer very little context-switching penalty when bouncing back and forth.
Working between languages is easy as long as you use a cross-language object format like gRPC.IMO single language is overrated and context switching cost is basically zero. Is it hard to switch between two verbal or written languages you know? People do it mid sentence, I don't see how it's any different with programming languages.
Node packages tend to be smaller but there's far, far more of them in an average project. And unlike Java they're not stored as zip on disk and class files when built, so in both cases they're using a lot more space. Java bytecode was designed to be compact like WASM, it takes way less space than even minified source and it's zip compressed for deployment into a jar on top of that.
Node dependancies being more fragmented is generally a bad thing. I constantly have to replace libraries when our code scanners find vulnerable npm packages that are no longer maintained. Since Java is far less fragmented I hardly ever have to do this with our Java codebases.
Node's standard libraries are terrible compared to Java and Python but I can't make a case for that besides saying they clearly are.
I agree with you on front vs backend being a bad comparison, but even our regular express apps take up more space and memory.
Java using lots of ram is also a myth. It might have been true many years ago, but Java generally uses about 1/3 the memory storing the same structures because there's a lot less overhead per object and field. The only reason most Java apps use lots of ram is because people configure the garbage collector to use as much RAM as possible so it collects less often. Node doesn't use as much ram because nobody really changes the GC defaults.
It's not about "sharing code" between front end and back end. Although you can share code and I have in several projects, what I mentioned above was sharing libraries. That's very common, for example, Moment.js, Lodash, and i18n utils. I also use Chrome debugger tools on both front end and back end. I have even shared architectural patterns for state management.
I agree Java dependencies are less error prone because they're bundled up as Java byte code and I get the appeal there.
I agree Python has a fantastic standard library and Node is spartan by comparison. That was always a trade-off that Node consciously made from the beginning though.
Didn't know that about the GC defaults.
Context switching is a real thing, and sometimes creates penalties. But sometimes it increases productivity. For me it is very helpful to switch into SQL mode when grabbing data from a store, then switching to Go/Python/JS/Rust/C++/Ruby/etc thinking for the business rules around that data.
Frontend JS and backend JS are not really the same language or environment. They are different in important ways. But they are so very similar that it can be easy to be in "frontend" thinking mode when working on the backend, or vice versa. And I have many many times seen that cause problems.
That's not to say that it is bad to use the same language in both places. I'm just pointing out that there are pluses to context switching as well as negatives.
Well, to be fair, humans have dedicated hardware for natural language encoding/decoding ;)
A package manager is different from package hosting. In the case of Deno you can still build and use third party package managers (and they might be able to utilize Deno's import-maps support to achieve some "magic")
Maybe (just "maybe" for now) we will be able to support plugin imports. In that case dylibs could be directly pulled down from network just like normal files (don't take my words as official though -- we have not decided on that yet)
There have been attempts to add some util functions for loading such plugins easier: https://github.com/denoland/deno/pull/3471
There are some other issues with file stats as well; requiring multiple syscalls to retrieve information that can be had in just one.
It's a mystery to me why they made such a high level decision in such low level code without an escape hatch.. Been a lot of talk but probably won't be fixed any time soon due to backwards compatibility.
Just implement your own directory walk based on `readdir` or whatever fs operations you need directly.
Or use a library that has already done this: https://github.com/karrick/godirwalk#configurable-sorting-of...
The high level interface made one choice. The escape hatch is to use a lower level interface.
Of course one could always just make direct syscalls or use a library that does, but this was a comment about stdlib. These would likely be implemented differently in hindsight per discussions on the Go project; and there have been discussions about improving them somehow in Go 2(readdir2?).