Deno v1 was released a couple of months ago and there were a lot of different opinions about it. Personally, I had a chance to quickly look at its documentation and did kinda like it, I also trust Ryan Dahl - the creator behind Deno (and Node.js).
So, here a deeper look into Deno and what it can potentially do.
Deno's goals
First, we should understand why Deno was created in the first place, what problems it is solving:
Deno aims to be a productive and secure scripting environment for the modern programmer.
- Deno's documentation
This definitely sounds very general. I had to look further into its documentation to understand what problems Deno is solving.
First of all, although Deno and Node.js can co-exist, being another TypeScript/JavaScript runtime, Deno's ultimate end goal is definitely to replace Node.js, which means it was built to solve Node.js's problems. By describing Deno "a productive and secure scripting environment" Deno creator is saying that Deno is solving the problem of Node.js being not productive and insecure. As I worked with Node.js and a few other modern languages (Go, Kotlin) before, I definitely can relate that Node.js has these two issues:
-
Not productive:
- Did you ever switch from TypeScript back to JavaScript then realize that was a wrong choice? The number of LOCs in JavaScript codebase although can be fewer than the same project in TypeScript and no restriction seems to be easier, writing and collaborating in JavaScript is just much slower nowadays.
- The Node.js devtool ecosystem though is powerful, is very fragmented: npm, yarn, CDN, linter, formatter, TypeScript, Flow, etc. You see all the "starter" projects with tons of configuration files?
Insecure: I don't know if you have this feeling but every time I installed a new Node.js package, I wish the developer didn't push a virus script into it. The
node_modules
and installation process always feel cumbersome and insecure.
How Deno solve these problems?
TypeScript out of the box, no configuration.
Ship only an executable file, no
node_modules
, and run everywhere without an installation process (except for the executable itself).Secure by default, you have to explicitly grant certain permissions before a script can do certain critical tasks.
Have builtin devtools (
deno fmt
,deno bundle
,deno lint
, etc) and is a package manager itself.ES Modules native. Imports via URLs.
Be browser-compatible.
What does that mean?
Looking at Deno's features set, I had to say its vision is more ambitious than I thought. All with a single executable:
Write secure-by-default system scripts and server-side applications in TypeScript with zero configuration. TypeScript compilation is also abstracted away, for scripting experience, it is like running TypeScript natively (what ts-node does).
Have builtin fast (swc) compiler and bundler for modern ES syntax supported by modern browsers, essentially replacing
webpack
,parcel
,rollup
, etc.Have builtin
fmt
andlint
tools, essentially replacingprettier
,eslint
, etc.Write, compile, and deploy code for both servers and modern browsers.
Common misconception
Import by URLs??
A lot of people are skeptical about this and are afraid of unexpected changes upstream. However, this concept was originally designed in ES standard and is implemented in most modern browsers, Deno doesn't reinvent the wheel here.
First of all, there shouldn't be concern about changes upstream, production software should always vendor 3rd packages, we have always been doing that by bundling applications. Lock versions can also be done easily by keeping checksums of previously downloaded packages.
This pattern also helps to have truly on-demand imports, you only load a package when your execution reach its import, while in Node.js everything is fetched no matter when and whether you'll use it.
Web protocol also enables more advanced import features (by communicating metadata in HTTP headers, etc), allows to opt in interceptors doing complex tasks, for example on-demand compilation.
Top-level await
This isn't just about allowing us to do "cool" async
and await
at top-level in our index.ts
or app.ts
. This is built in combination with native ESM to further enable async on-demand imports and secure-by-default features:
A package is only loaded (downloaded) when a user did a certain action (went to a screen, used a feature), we can display a loading while importing the package.
A permission may be asked and granted only until an import is loaded.
Summary
I love it! I can picture a bright future with Deno, where you can write, compile, bundle, and deploy performance TypeScript applications to both server and client, with just a single Deno executable and little-to-zero configuration.
Top comments (10)
The main hurdle for me is building a React or Vue app when those packages don't exist on Denoland.
I found this approach on a tutorial. Yes it means you are using NPM registry, but you don't use the NPM command and you get packages to choose from
Have you tried that out?
More notes on JSPM
That's definitely the way, there is a lot of CDN supporting this mechanism right now, there are also unpkg, skypack, etc. I personally use Skypack.
And for your concern, it is a very common hurdle among devs when they see a URL being imported, however you think about it correctly, it's exactly what NPM does for you, except you don't have to install NPM and run installation scripts (which is insecure). What NPM does essentially is to download the package somewhere from its API (also a URL) and keep in the node_modules. So, there is really no difference.
Hope it helps!
Ah thanks. I knew of unpkg from npm stuff - so it does something like JSPM?
I'll check out skypack
I see skypack.dev/ even covers deno on their homepage
Yeah, skypack is pretty dope, but be aware that not all packages are compatible, packages using Node.js specific won't work.
Did you mean:
production software should always version (or lock) 3rd-party packages
Yes, exactly. There is a good explanation here that you may find useful: stackoverflow.com/questions/262174...
Okay thanks. I have never heard vendor as a verb.
BTW In Ruby, the packages directory is caller
vendor
.Deno looks very good, I am going to try it...
Yeah, glad you like it, too.