Congratulations on the 1.0 release! I've been using Deno as my primary "hacking" runtime for several months now, I appreciate how quickly I can throw together a simple script and get something working. (It's even easier than ts-node, which I primarily used previously.)
I would love to see more focus in the future on the REPL in Deno. I still find myself trying things in the Node.js REPL for the autocomplete support. I'm excited to see how Deno can take advantage of native TypeScript support to make a REPL more productive: subtle type hinting, integrated tsdocs, and type-aware autocomplete (especially for a future pipeline operator).
There are both ocaml and haskell repls, so it can be done with languages whose type systems are the focus. Not sure if there's anything specific about typescript that would make it hard, though.
Are imports async by default in Deno? That seems to be how it works given that you can import from a URL. This is interesting since async imports are currently a part of JavaScript(or at least a proposal?) by using the `import()` function.
there are no "async" or "sync" imports in js. there are static and dynamic imports. An implementation is free to spend as much time as it likes between parsing a file to get the static imports and actually running the file doing whatever it likes, including fetching urls, reading the file system, etc. dynamic imports return a promise but the implementation is free to resolve that promise immediately (e.g. `return Promise.resolve(loadSync(module))`)
> Internally Deno uses Microsoft's TypeScript compiler to check types and produce JavaScript. Compared to the time it takes V8 to parse JavaScript, it is very slow.
> Early on in the project we had hoped that "V8 Snapshots" would provide significant improvements here. Snapshots have certainly helped but it's still unsatisfyingly slow. We certainly think there are improvements that can be done here on top of the existing TypeScript compiler, but it's clear to us that ultimately the type checking needs to be implemented in Rust.
> This will be a massive undertaking and will not happen any time soon; but it would provide order of magnitude performance improvements in a critical path experienced by developers. TSC must be ported to Rust. If you're interested in collaborating on this problem, please get in touch.
> All of the V8 source code is distributed in the crate itself. Finally rusty_v8 attempts to be a safe interface. It's not yet 100% safe, but we're getting close. Being able to interact with a VM as complex as V8 in a safe way is quite amazing and has allowed us to discover many difficult bugs in Deno itself.
We'll also have to wait on who will be the first to have a production ready Javascript Engine written in Rust that could replace V8, if you're talking about safety.
Even with the "safe" bindings, you will still get the same C and C++ vulnerabilities found in V8 that will also be present in Deno.
For this sort of problem Rust's safety guarantees don't buy you all that much. If you're generating machine code and implementing a GC that's not the sort of thing that Rust's typesystem can prove correct.
That said, a rust JS runtime would be amazing just because it's easier to integrate into rust projects.
Not sure exactly how much it buys you but I suspect there’s still room for research especially since Mozilla themselves has interest in a Rust JS JIT. I am curious to see if HolyJIT goes anywhere and what kinds of safety improvements it could potentially offer.
What is the ongoing performance cost of using the official TypeScript compiler for long-running applications? Or is this primarily a concern of startup time for scripts and short-lived programs like CLIs?
AFAIK, tsc is just a compiler, not a runtime. Once you compiled, you're just executing javascript so it only impacts startup time.
ts-node is a runtime able to run TypeScript. It is definitely much much slower at execution, not just at startup time. It's useful for hacking around, I use it as a REPL but even for a dev environment it's faster to use tsc's incremental compilation with a file watcher, and execute the resulting JS
Deno really shouldn't run TypeScript files directly. Not only is TypeScript too slow for this, it receives far too many breaking changes.
How will Deno decide when to upgrade its TypeScript compiler version? Will Deno have to have breaking changes every three months or so?
Also, Deno appears to allow import TypeScript files with .ts extensions while tsc doesn't. This alone means the same code won't run in Deno and compile with tsc.
JavaScript at Stage 3 and above is a stable compile target, and Deno should just run that.
It's just compiling TypeScript into JS when you import it, and uses tsc to do it. It can load JS just fine as well if you want to use Babel or similar.
My workaround is to use //@ts-ignore above the import, but this is clunky. I just tried Deno and found that TypeScript doesn't support .ts extensions yet.
I would rather have Clojurescript than Typescript, but absolutely, less is more, and it feels like a bad idea to tie implementation of this runtime to another dependency.
My love of the C++, Java, C#, ad nauseum, lineage of Enterprisey OOP languages turned to hate about 15 years ago, though, so take my assessment with a grain of salt.
“C with classes” seemed like a good idea, we were told back in the 80s in school, since garbage collection is impractical. Er, yeah. Worse is better...
I’m a huge TS fan and I agree. Deno is just running tsc for me it seems. So far I don’t see much advantage. It also potentially ties Deno to current trends. TS is pretty dang popular, but what if something else comes along and scoops it?
I read in a comment somewhere else in this post that you can just point deno at JS files to skip the TS compiler. I agree it's probably not a good idea to couple the Typescript version with the runner.
Note that Deno started out as Typescript runtime, it was it's tagline, they added the JavaScript later there.
> TS is pretty dang popular, but what if something else comes along and scoops it?
Earth is rather small, type inferencing dynamic language is really hard. There is simply no other language or team that has achived anything like TS. It's very unlikely that anyone else will do it for JS again. You can just look at amount of work in TS already.
Only thing that can "scoop it" is another language entirely taking off and leaving JS developers in the history. In that case the point becomes useless, it can happen to any runtime for any given language.
though i think it just strips the typescript annotations. but this may be workable if during dev there's some kind of guarantee that the typechecking has already been done.
Massive undertaking is a big understatement. It would be better to not tie into TS/Flow and let one of the two biggest tech companies implement the best, fastest typechecker.
"Automatic asynchronicity[sic]"?! Node and all async io is cooperative multi-tasking, the opposite of automatic. The node event loop is a thin wrapper around the epoll() system-call (or one of its equivalents), and leaves the details of multi-tasking to the app developer. It's no wonder you weren't able to scale under node if you thought something was happening automatically for you!
Maybe he meant forced async as DOM/node blocking APIs are async/callback based since it's the only multitasking model available (or it was before workers)
if you require modules by URL, how does it make sure that the URL always contains the same library?
I've read the docs and it says it caches on the initial execution and doesn't update unless it's forced to update, but what happens when you for example publish a deno module to github, and someone else downloads it and runs it, and turns out the URL contains completely different library at his execution point?
> Deno can store and check module subresource integrity for modules using a small JSON file. Use the --lock=lock.json to enable and specify lock file checking. To update or create a lock use --lock=lock.json --lock-write.
HALLELUJAH that there is a clear, simple separation of when (a) you expect a lock file to be checked to guarantee integrity and (b) when you want it to be generated. The complete insanity that was npm shrinkwrap and lockfiles for years, summed up in this stackoverflow post https://stackoverflow.com/questions/45022048/why-does-npm-in... , always baffled me in that it seemed like it could have just been so easily avoided about being explicit when you're writing a lockfile vs. when you're using it.
That said, why not be even MORE explicit about it, i.e. "--use-lock=lock.json" vs. "--write-lock=lock.json"?
However, it still seems risky to me in case a library is not available. Is there a central repository planned? Or are you expected to vendor everything and ship your project with dependencies included?
This is exciting news indeed. Deno hitting 1.0 still makes the ecosystem surrounding it quite young, but it's an important milestone and I'm excited to see what comes of it in the future.
So at this fine grain of semantic detail, making strong statements about differing labels feels a little silly, but I have always thought that the difference is dynamic refers to typing, whereas scripting is usually a reference to the language being interpreted rather than compiled. Dynamically typed languages can certainly be compiled (I think Clojure qualifies here?).
In the past, Dahl's expressed regrets over choices he made early on in Node's development, and on the direction Node has gone since he left the project many years ago.
The last 10 minutes are a pitch for what a "better Node" would look like, if he were to start from scratch in 2018. The end result of that train of thought this project, which we should probably think of as bourne-again node.
Deno's development is (presumably) strongly influenced by his experience and furstrations with Node's shortcomings in both performance and developer ux.
Not necessarily. I prefer trying to improve what we have verses making a new thing every time we have a relatively minor disagreement, even if that disagreement is with our past self.
EDIT: I'd like to add that clearly he is able to spend his time as he wishes.
I generally agree. Although, some of these are pretty "opinionated" breaking changes (promises all the way down, package manager changes). It would be hard to convince the whole node community that these upgrades are worth the risk forking in a python 2/3-esque way.
Forcing TS is a change node could adopt in the next major version if everybody agreed, but the node community might be too big and diverse at this point, to make such an opinionated switch.
But isn't this an inherent problem in software development that is really super hard to not do?
Let's say you are deciding how to make node when it was first conceived and how it would work. You've made decisions about how the thing fundamentally works. Then after using it and developing for it many years and after having millions of critical software projects dependant on it, you slowly start to see the shortcomings of the software that you could only see at this stage. The problem is that these shortcomings come from a false assumption or solution to the fundamental problems you had to solve when making node. Now, the only way to fix node is to change how it fundamentally works. But if you do that, millions of users' code will break. So, do you require everyone now to fix their broken code and potentially piss everyone off? Or do you give people a choice? Stick with node if you aren't noticing any of those fundamental problems you found, or switch to the new thing on your own time? It's a question of how to affect the least number of people in the least negative way.
I find it amusing that you use the example of Python 2 -> Python 3, a breaking change in a widely used language, that has famously been very difficult and long for organisations to deal with.
Compare that with javascript which has never had a breaking change. On top of that Typescript is a backwards compatible superset of javascript.
More to the point, Ryan has a humble explanation of what regrets he has about Node.js[1], why they exist and in some cases why there isn't an easy fix.
The point that I assume you're making, that sometimes it is better to spend significant energy to fix something, rather than throwing the baby out with the bath water, is a good one. However I'd suggest this is not one of those cases.
> I find it amusing that you use the example of Python 2 -> Python 3, a breaking change in a widely used language, that has famously been very difficult and long for organisations to deal with.
Why is that amusing? I specifically chose that example for that exact reason. I was highlighting the difference in the audience and use case.
> However I'd suggest this is not one of those cases.
I don't see the argument that supports that, either in the post or your reply.
The thing is, I can see Beepboo 1.0 being announced in 2025 to address the things that went wrong with deno. Because there will be design mistakes. And at what point do you say 'oh too many people rely on this software to fix this, I have to start over'?
Couple this with a very real trend-chasing and resume pushing in frontend dev and I'm starting to understand why people are so cynical about this stuff.
Typescript is something more palatable to me because it wasn't throwing the baby out with the bathwater.
> ... there's a tendency to start over when the development gets hard to maintain or support instead of just fixing the mistakes.
The thought that Node.js should have been 'fixed' instead of creating Deno is where I disagree. At a glance I can see a few reasons:
- Node.js maintainers + community may not even think there is something to be fixed (see various discussions in this thread about module resolutions)
- Politics, death by committee, inertia
- Effectively a dependency with npm registry (although not technically)
- Lack of backwards compatibility with changes (e.g. module resolution)
> The thing is, I can see Beepboo 1.0 being announced in 2025
Node.js was initially released in 2009 so it's probably fairer to suggest Beepboo 1.0 will be released in 2030. And yes, if it improved on Deno and solved inherent problems that couldn't be solved internally, I would wholeheartedly cheer it along.
I think it's also worth mentioning that Node.js is at a level of stability and maturity that people who plan to and have already built on it, aren't left abandoned.
PM on part of Cloudflare Workers and someone who was in physical attendance for this talk here.
They're not really directly comparable other than "A JavaScript runtime built on top of V8."
Workers doesn't support TS directly, though you can compile TS to JS and run it, of course. (My team maintains a worker and this is what we do, and it works well)
Deno has its own APIs, as does Workers. Worker's main API is the Service Worker API, Deno's is not.
Workers is focused on V8 isolates as a means of achieving multi-tenency. I don’t believe Deno does anything specific here.
Deno is mostly implemented in Rust, the Workers runtime is written in C++.
Deno is open source, Workers is not.
Workers is being used at scale in production, Deno just launched its 1.0.
I am very excited to see what happens with Deno. :) Fun history: I had been dreaming about doing "Chakra Core + Tokio" a few years back, but didn't find the time. I'm skeptical of the dependency approach Deno is taking, we'll see what happens!
> Workers is focused on V8 isolates as a means of achieving multi-tenency. I don’t believe Deno does anything specific here.
Deno implements the web worker API, which launches different isolates. You could implement something kind of like CF Workers in pure TypeScript, but probably not replicate your resource enforcement.
It's also a pretty good Rust v8 implementation. Before we (fly.io) abandoned our JS runtime we were rebuilding it with that.
Ironically, we also tried Chakra Core + Tokio. It sure would be nice to have a not-google JS engine.
Thanks for confirming, that’s what I meant by “specific”, I was guessing they implemented the spec. It’s just a very big focus of Workers, and I don’t think it’s a focus of Deno. Not good or bad, just a difference.
Ah interesting! Did you abandon it for reasons other than “deno exists”? Would love to hear more about how it turned out, good or bad.
We tossed it because people needed to do much heavier compute than we expected and we realized running arbitrary executables was more useful. It wasn't techniecally bad, just wrong for our customers.
Deno’s existence gives me hope we can bring back the JS API, I'd love to have nginx-as-a-TypeScript-API.
If you're getting into Deno and want to keep up with new stuff from the ecosystem on a regular basis, we're now publishing https://denoweekly.com/ .. issue 2 just went out minutes after the 1.0 release. I've been doing JavaScript Weekly for 487 issues now, so this is not a flash in the pan or anything :-D
Am curious how Parallelism could be handled in the runtime? Besides exposing WebWorkers, would shared memory be a possibility? V8 looks like its heading toward a portable WebAssembly SIMD accelerator.
>>> Promises all the way down
Async / await is a great pattern for render loops by resolving to continuous window.requestAnimationFrame calls. Here is a nifty example computing a Buddhabrot and updating new data quite smoothly:
Hmm, interesting! Thanks for the report. I just ran it through Qualys SSL Labs and everything passed. (We got a B though because we still support TLS 1.1.)
It's a multi-domain Let's Encrypt X3 certificate and I believe most LE users will be in a similar boat now.
I'm Canadian and in Canada for what it's worth. Clicking on the lock tells me that it was verified by lets encrypt. The root is "Digital Signature Trust Co." Common Name "DST Root CA X3".
Cisco sounds like a router might by running a MITM on you?
Edit: This looks to be confirmation that that root (or one by a very similar name) is used by a MITM tool:
> We believe JavaScript is the natural choice for dynamic language tooling; whether in a browser environment or as standalone processes.
I disagree with this assessment. Lua is still far superior as an embed-able scripting language/runtime. I suspect the preference for JavaScript is mostly due to the Deno developers' familiarity and preference.
LuaJIT is nearly 3x faster than V8 JavaScript the last time I checked. Just anecodal DDG search [0]. Maybe V8 has gotten faster since the last time I checked.
I think a big part of the point is to build a js runtime for existing js code and libraries.
Probably it will not replace node soon, but it is a possible outcome.
Also didn't luajit had the problem that it would never move to more recent version of lua? I remember that some years ago there was some talking about this.
It depends what you mean by "superior". JavaScript (well v8) is far safer as a scripting runtime. And there are a ton of existing JS libs for solving problems. AND there's TypeScript, which is pretty great.
> It's basically the same "exposure" as importing a random npm, but it has the benefit if being explicit when you do it.
I'm not sure how this works in detail here, but at least in NPM you got a chance to download packages, inspect them and fix the versions if so desired. Importantly, this gave you control over your transitive dependencies as well.
This seems more like the curl | bash school of package management.
The tldr is Deno also gives you a chance to download + inspect packages, and then lock dependencies. The mechanism for import is different, but the tooling is good.
The good thing about this is you can effectively build a register service that serves the same level of trust that npm provides, because at the end of the day that is the only deferential in this scenario as npm can just as well return malicious code.
AFAIK there is no option to allow a website to read and write random files anywhere to my hard drive period. At most a website can ask the user select a file or offer one for downloading. In the future maybe it can be given a domain specific folder.
That's not true here. If I'm running a web server I'm going to need to give the app permission to read the files being served and access to the database. That something that never happens in the browser.
> It's basically the same "exposure" as importing a random npm, but it has the benefit if being explicit when you do it.
This is definitely false. For all the problems with the NPM registry and the Node dependency situation, an NPM package at a specific version is not just at the whims of whatever happens to be at the other end of a URL at any given moment it's requested. This is a huge vulnerability that the Node/NPM world does not currently have.
That is a fair point. I don't think most people who use npms really pay much attention, though, and you're still just an npm update away from getting something unexpected (because really, who puts explicit versions in package.json?).
Why are you _regularly_ clearing lock files? If you're bypassing lock files you're going to have the exact same issue with npm or yarn or any other package manager that downloads from the internet.
Dunno about OP but I pin versions in package.json because it allows me to control the versions and upgrade major versions only when explicit and necessary, and rely only on the lock file to keep it the same between commit time and the production build.
That's fine for one developer pushing to production from their own machine. But I've you have aCI server and you're working with other people you're going to want to know that everyone is working with the same modules.
That doesn’t actually work and gives you a false sense of reproducibility and stability. Sure your top level dependencies might not change without explicit changes to package.json but every time you run npm install without a lock file all transitive dependencies are re-resolved and can change.
What about the dependencies of your dependencies? You're gonna get burned when a breaking change gets introduced a few levels deeper than your package.json. Not everyone follows semver perfectly, and sometimes malicious code gets distributed as one of these transitive dependencies.
I'm not sure how a lock file would help in this scenario, unless you're also committing your cache to source control (like a lot of folks did in the bad old days of NPM). The local cache is great, but that doesn't prevent the content of those URLs changing for someone who doesn't have access to your cache.
For Deno the only issue is the first time when you do not have it cached. Deno compiles in all dependencies when building so the only point of failure is the machine you’re building on.
I don’t know the state of the art anymore, but I’m sure they have ways to make it easy to vendor deps in the repo.
From the article: "Also like browsers, code is executed in a secure sandbox by default. Scripts cannot access the hard drive, open network connections, or make any other potentially malicious actions without permission."
Except that with Deno, everything IO related is turned off by default and has to be granted access before it becomes a process. It's the first bullet point on the landing page.
That still doesn't prevent imported modules from yoinking anything you did grant access to, though. For instance, if my service connects to a DB then `uuid` can slurp the contents.
It'd be nice to have some capability model where modules can only access things through handles passed to them, but probably infeasible for a project like this.
Does Deno have some built in way to vendor / download the imports pre-execution? I don't want my production service to fail to launch because some random repo is offline.
Deno caches local copies and offer control on when to reload them. in term of vendoring you can simply download everything yourself and use local paths for imports.
How would this work with transitive dependencies? Sure I can control which parts I import myself, but how do I keep a vendored file from pulling in another URL a level deeper?
Unlike node, recommended deno practice is to check-in your dependencies to the VCS.
> Production software should always bundle its dependencies. In Deno this is done by checking the $DENO_DIR into your source control system, and specifying that path as the $DENO_DIR environmental variable at runtime.
Ah from that perspective I can see how this might appear to be better. Personally, I like the 'magic' of NPM (which to be honest I don't really think is all that magical, it's quite transparent what's happening behind the scenes). This 'magic' means I no longer have to write 200 line makefiles, so it definitely makes my life easier.
Some of that convenience will still be included, a couple of things that deno will do differently from node will be that there is no standard index.* file to load and import path include the extension.
You can also use the built in bundle command to bundle all of your dependencies and your code into a single, easily deployable file. https://deno.land/manual/tools/bundler.
deno requires that you give the process explicitly which permissions it has. I think it's much better than praying that a package has not gone rough like with node. If you don't trust the remote script, run it without any permission and capture the output. Using multiple process with explicit permissions are much safer.
i'm wondering if they'll end up adding a 'dependencies.json' to eliminate the boilerplate from 'deps.ts' and to simplify tooling. that'd be revolutionary! ;)
jokes aside, i wonder how import-via-url will impact tooling. having to parse arbitrary JS (or even run it, for dynamic imports?) seems like it'd make writing a "list all dependencies" tool much harder than a "dumb" JSON/TOML/whatever file would. though i guess Go does a similar thing, and afaik they're fine
It's not just about the integrity. The url may very well provide what they claim to provide, so checksums would match, but it's the direct downloading and running of remote code that is terrifying.
This is pretty much like all the bash one-liners piping and executing a curl/wget download. I understand there are sandbox restrictions, but are the restrictions on a per dependency level, or on a program level?
If they are on a program level, they are essentially useless, since the first thing I'm going to do is break out of the sandbox to let my program do whatever it needs to do (read fs/network etc.). If it is on a per dependency level, then am I really expected to manage sandbox permissions for all of my projects dependencies?
If you afraid of "direct" downloading and executing some of that code, then what do you think happen when you npm install/pip install a package?
I'm very interested if you can expose a new attack vector that didn't exist with the previous solutions.
You can generate modules on the fly on the server, that require next generated module recursively blowing up your disk space. If deno stores those files uncompressed, you can generate module full of comments/zeros so it compresses very well for attacker and eats a lot of space on consumer side.
Sure, I probably phrased that poorly -- it's not a unique advantage, but benefit of having URLs be the only way to link to dependencies versus a centralized, dominant package manager.
I thought a lot about it, and it seems as secure as node_modules, because anybody can publish to npm anyway. You can even depend to your non-npm repo (github, urls...) from a npm-based package.
If you want to "feel" as safe, you have import maps in deno, which works like package.json.
Overall, I think Deno is more secure because it cuts the man in the middle (npm) and you can make a npm mirror with low effort, a simple fork will do. Which means you can not only precisely pin which code you want, but also make sure nobody knows you use those packages either.
Take it with an open mind, a new "JSX" or async programming moment. People will hate it, then will start to see the value of this design down the road.
One advantage of having a centralized repository is that the maintainers of that repository have the ability to remove genuinely malicious changes (even if it's at the expense of breaking builds). Eliminating the middle man isn't always a great thing when one of the people on the end is acting maliciously.
I'm just thinking out loud here, but it seems to me that you could just make sure you're importing all your dependencies from trusted package repos, right? And since the URL for a package is right there in the `import` statement, it seems like it'd be pretty easy to lint for untrusted imports.
I don't detest NPM in the way that some people do, but I have always worried about the implications of the fact that nearly the entire community relies on their registry. If they ever fell over completely, they would have hamstrung a huge amount of the JS community.
> I thought a lot about it, and it seems as secure as node_modules, because anybody can publish to npm anyway
npm installs aren't the same as installing from a random URL, because:
* NPM (the org) guarantees that published versions of packages are immutable, and will never change in future. This is definitely not true for a random URL.
* NPM (the tool) stores a hash of the package in your package-lock.json, and installing via `npm ci` (which enforces the lockfile and never updates it in any case) guarantees that the package you get matches that hash.
Downloading from a random URL can return anything, at the whims of the owner, or anybody else who can successfully mitm your traffic. Installing a package via npm is the same only the very first time you ever install it. Once you've done that, and you're happy that the version you're using is safe, you have clear guarantees on future behaviour.
That solves this specific problem nicely, although AFAIK IPFS doesn't guarantee long-term availability of any content, right? If you depend on a package version that's not sufficiently popular, it could disappear, and then you're in major trouble.
It'd be interesting to look at ways to mitigate that by requiring anybody using a package version to rehost it for others (since they have a copy locally anyway, by definition). But then you're talking about some kind of IPFS server built into your package manager, which now needs to be always running, and this starts to get seriously complicated & practically challenging...
>> Internally Deno uses Microsoft's TypeScript compiler to check types and produce JavaScript. Compared to the time it takes V8 to parse JavaScript, it is very slow.
>> We certainly think there are improvements that can be done here on top of the existing TypeScript compiler, but it's clear to us that ultimately the type checking needs to be implemented in Rust.
Funny, I was just talking about something like this in an earlier TypeScript discussion today. I was saying that I don't understand why Microsoft doesn't have their own native TypeScript runtime engine by now.
I have nothing against TypeScript as a language but I hate the TypeScript transpiler; it should be packaged as an engine, not as a transpiler. I just hate having to debug mangled transpiled code and dealing with sourcemaps. I want to be able to run and debug my own code, not some alternative mangled version of it.
I think Deno is a promising project in the sense that they seem to understand the drawbacks of transpilation and are actually trying to provide TypeScript support which feels native. Everyone else seems to be ignoring this problem including the creators of TypeScript.
They have ChakraCore (which is js), but the thing about a "TypeScript runtime" is it's not that different from a JS runtime. TypeScript is a super set of JavaScript so it already has to do the JS runtime work. v8 is pretty good at that.
> I don't understand why Microsoft doesn't have their own native TypeScript runtime engine by now
what would they do with it? ship it in Edge? great, now some small fraction of users can run TS natively. but most can't, so everyone would still transpile to JS anyway...
it could work if Google did it, but i don't think MS has enough market share to have an influence here
>I just hate having to debug mangled transpiled code and dealing with sourcemaps. I want to be able to run and debug my own code, not some alternative mangled version of it.
Look into ts-node. It lets me run and debug the TypeScript itself before transpiling it.
You know what would be extra amazing? Incorporating (at some point in the future) all of the very smart stuff that the unison people have been doing. That would be _tremendous_ for code re-use and guarantees about remote packages. What I wouldn't give for a JS vm that could do all that. . . .
Maybe I’m missing something but the reason why the concept behind unison is so neat is that identifying libraries by AST allows for the kind of code re use that Joe Armstrong was talking about. It’s not about urls as identifiers, that’s superficial.
So it's an alternative to Node? Sounds incredibly cool, honestly. This:
> Supports TypeScript out of the box.
Seems like a small thing, but it has me interested all on its own. It's a huge pain to set up a whole build process just for TypeScript (which is generally the only preprocessing you need outside of the browser).
Word of warning though - ts-node can be excruciatingly slow. We recently switched a project from using ts-node in our dev environment to compiling with tsc and running with node, and shaved around 5 minutes from our startup time.
Well, that answers something I was wondering about recently.
I noticed in a couple of popular TypeScript (+React fullstack) boilerplates, that they were using ts-node to run the server in production.
Unlike babel-node, there's no mention in the documentation to avoid using it in production - but I figured there'd be performance impact, since it's transpiling on the fly (I suppose just once per require).
More then one second and people will test their code less often. Five minutes and people start relying on the type-checker. Like with the chicken and egg problem, what came first, the type-checker or the need to have a type checker?
It doesn't really help that much with TypeScript native NPM-packages being published with JS and D.TS (TypeScript-definitions) instead of the original source, does it?)
The very first line of sample code is linking to Deno standard modules, basically the standard library for Deno, aiming to be feature complete enough to bring down the side of dependencies
597 comments
[ 3.1 ms ] story [ 264 ms ] threadI would love to see more focus in the future on the REPL in Deno. I still find myself trying things in the Node.js REPL for the autocomplete support. I'm excited to see how Deno can take advantage of native TypeScript support to make a REPL more productive: subtle type hinting, integrated tsdocs, and type-aware autocomplete (especially for a future pipeline operator).
> fish
I see what you did there, and I approve.
I think stepping outside the npm ecosystem is going to be a bigger issue then people think.
> Early on in the project we had hoped that "V8 Snapshots" would provide significant improvements here. Snapshots have certainly helped but it's still unsatisfyingly slow. We certainly think there are improvements that can be done here on top of the existing TypeScript compiler, but it's clear to us that ultimately the type checking needs to be implemented in Rust.
> This will be a massive undertaking and will not happen any time soon; but it would provide order of magnitude performance improvements in a critical path experienced by developers. TSC must be ported to Rust. If you're interested in collaborating on this problem, please get in touch.
> All of the V8 source code is distributed in the crate itself. Finally rusty_v8 attempts to be a safe interface. It's not yet 100% safe, but we're getting close. Being able to interact with a VM as complex as V8 in a safe way is quite amazing and has allowed us to discover many difficult bugs in Deno itself.
We'll also have to wait on who will be the first to have a production ready Javascript Engine written in Rust that could replace V8, if you're talking about safety.
Even with the "safe" bindings, you will still get the same C and C++ vulnerabilities found in V8 that will also be present in Deno.
That said, a rust JS runtime would be amazing just because it's easier to integrate into rust projects.
https://neon-bindings.com/
ts-node is a runtime able to run TypeScript. It is definitely much much slower at execution, not just at startup time. It's useful for hacking around, I use it as a REPL but even for a dev environment it's faster to use tsc's incremental compilation with a file watcher, and execute the resulting JS
TypeScript is just an extra.
How will Deno decide when to upgrade its TypeScript compiler version? Will Deno have to have breaking changes every three months or so?
Also, Deno appears to allow import TypeScript files with .ts extensions while tsc doesn't. This alone means the same code won't run in Deno and compile with tsc.
JavaScript at Stage 3 and above is a stable compile target, and Deno should just run that.
The issue is that the TypeScript it loads today, it might not load in the future.
My love of the C++, Java, C#, ad nauseum, lineage of Enterprisey OOP languages turned to hate about 15 years ago, though, so take my assessment with a grain of salt.
“C with classes” seemed like a good idea, we were told back in the 80s in school, since garbage collection is impractical. Er, yeah. Worse is better...
And in the 80s it was even more so due to CPU and RAM performance.
> TS is pretty dang popular, but what if something else comes along and scoops it?
Earth is rather small, type inferencing dynamic language is really hard. There is simply no other language or team that has achived anything like TS. It's very unlikely that anyone else will do it for JS again. You can just look at amount of work in TS already.
Only thing that can "scoop it" is another language entirely taking off and leaving JS developers in the history. In that case the point becomes useless, it can happen to any runtime for any given language.
though i think it just strips the typescript annotations. but this may be workable if during dev there's some kind of guarantee that the typechecking has already been done.
I'm writing as a former Node.js user.
https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
I've read the docs and it says it caches on the initial execution and doesn't update unless it's forced to update, but what happens when you for example publish a deno module to github, and someone else downloads it and runs it, and turns out the URL contains completely different library at his execution point?
HALLELUJAH that there is a clear, simple separation of when (a) you expect a lock file to be checked to guarantee integrity and (b) when you want it to be generated. The complete insanity that was npm shrinkwrap and lockfiles for years, summed up in this stackoverflow post https://stackoverflow.com/questions/45022048/why-does-npm-in... , always baffled me in that it seemed like it could have just been so easily avoided about being explicit when you're writing a lockfile vs. when you're using it.
That said, why not be even MORE explicit about it, i.e. "--use-lock=lock.json" vs. "--write-lock=lock.json"?
However, it still seems risky to me in case a library is not available. Is there a central repository planned? Or are you expected to vendor everything and ship your project with dependencies included?
I'm the co-founder of https://deno.services . We would like to make Deno first language in history comes with its own infrastructure.
Deno's lead is Ryan Dahl, the creator of Node.
In the past, Dahl's expressed regrets over choices he made early on in Node's development, and on the direction Node has gone since he left the project many years ago.
He bravely presented on this topic at jsconf eu, 2018: https://www.youtube.com/watch?v=M3BM9TB-8yA, it's a fantastic talk.
The last 10 minutes are a pitch for what a "better Node" would look like, if he were to start from scratch in 2018. The end result of that train of thought this project, which we should probably think of as bourne-again node.
Deno's development is (presumably) strongly influenced by his experience and furstrations with Node's shortcomings in both performance and developer ux.
EDIT: I'd like to add that clearly he is able to spend his time as he wishes.
Forcing TS is a change node could adopt in the next major version if everybody agreed, but the node community might be too big and diverse at this point, to make such an opinionated switch.
This really feels like the fundamental response in the js world and why we see much churn.
Let's say you are deciding how to make node when it was first conceived and how it would work. You've made decisions about how the thing fundamentally works. Then after using it and developing for it many years and after having millions of critical software projects dependant on it, you slowly start to see the shortcomings of the software that you could only see at this stage. The problem is that these shortcomings come from a false assumption or solution to the fundamental problems you had to solve when making node. Now, the only way to fix node is to change how it fundamentally works. But if you do that, millions of users' code will break. So, do you require everyone now to fix their broken code and potentially piss everyone off? Or do you give people a choice? Stick with node if you aren't noticing any of those fundamental problems you found, or switch to the new thing on your own time? It's a question of how to affect the least number of people in the least negative way.
People in JS/frontend world are willing to drop the world for the latest new thing, I see this as less jarring than, say, Python 2 -> Python 3.
Except there aren't any breaking changes in JavaScript, are there? Even in Node if anything is deprecated that is done over time in many years.
Compare that with javascript which has never had a breaking change. On top of that Typescript is a backwards compatible superset of javascript.
More to the point, Ryan has a humble explanation of what regrets he has about Node.js[1], why they exist and in some cases why there isn't an easy fix.
The point that I assume you're making, that sometimes it is better to spend significant energy to fix something, rather than throwing the baby out with the bath water, is a good one. However I'd suggest this is not one of those cases.
[1] https://www.youtube.com/watch?v=M3BM9TB-8yA
Why is that amusing? I specifically chose that example for that exact reason. I was highlighting the difference in the audience and use case.
> However I'd suggest this is not one of those cases.
I don't see the argument that supports that, either in the post or your reply.
The thing is, I can see Beepboo 1.0 being announced in 2025 to address the things that went wrong with deno. Because there will be design mistakes. And at what point do you say 'oh too many people rely on this software to fix this, I have to start over'?
Couple this with a very real trend-chasing and resume pushing in frontend dev and I'm starting to understand why people are so cynical about this stuff.
Typescript is something more palatable to me because it wasn't throwing the baby out with the bathwater.
My apologies I misread.
> ... there's a tendency to start over when the development gets hard to maintain or support instead of just fixing the mistakes.
The thought that Node.js should have been 'fixed' instead of creating Deno is where I disagree. At a glance I can see a few reasons:
- Node.js maintainers + community may not even think there is something to be fixed (see various discussions in this thread about module resolutions)
- Politics, death by committee, inertia
- Effectively a dependency with npm registry (although not technically)
- Lack of backwards compatibility with changes (e.g. module resolution)
> The thing is, I can see Beepboo 1.0 being announced in 2025
Node.js was initially released in 2009 so it's probably fairer to suggest Beepboo 1.0 will be released in 2030. And yes, if it improved on Deno and solved inherent problems that couldn't be solved internally, I would wholeheartedly cheer it along.
I think it's also worth mentioning that Node.js is at a level of stability and maturity that people who plan to and have already built on it, aren't left abandoned.
Software changes, languages change. Billion dollar companies adapt or migrate.
Or maybe as Perl 6
Is it fair to say (a managed) deno is what Cloudflare Workers is? If not, what would be key differences between them?
They're not really directly comparable other than "A JavaScript runtime built on top of V8."
Workers doesn't support TS directly, though you can compile TS to JS and run it, of course. (My team maintains a worker and this is what we do, and it works well)
Deno has its own APIs, as does Workers. Worker's main API is the Service Worker API, Deno's is not.
Workers is focused on V8 isolates as a means of achieving multi-tenency. I don’t believe Deno does anything specific here.
Deno is mostly implemented in Rust, the Workers runtime is written in C++.
Deno is open source, Workers is not.
Workers is being used at scale in production, Deno just launched its 1.0.
I am very excited to see what happens with Deno. :) Fun history: I had been dreaming about doing "Chakra Core + Tokio" a few years back, but didn't find the time. I'm skeptical of the dependency approach Deno is taking, we'll see what happens!
Deno implements the web worker API, which launches different isolates. You could implement something kind of like CF Workers in pure TypeScript, but probably not replicate your resource enforcement.
It's also a pretty good Rust v8 implementation. Before we (fly.io) abandoned our JS runtime we were rebuilding it with that.
Ironically, we also tried Chakra Core + Tokio. It sure would be nice to have a not-google JS engine.
Ah interesting! Did you abandon it for reasons other than “deno exists”? Would love to hear more about how it turned out, good or bad.
Deno’s existence gives me hope we can bring back the JS API, I'd love to have nginx-as-a-TypeScript-API.
Of course, Deno has an official Twitter account as well at https://twitter.com/deno_land :-)
Am curious how Parallelism could be handled in the runtime? Besides exposing WebWorkers, would shared memory be a possibility? V8 looks like its heading toward a portable WebAssembly SIMD accelerator.
>>> Promises all the way down
Async / await is a great pattern for render loops by resolving to continuous window.requestAnimationFrame calls. Here is a nifty example computing a Buddhabrot and updating new data quite smoothly:
http://www.albertlobo.com/fractals/async-await-requestanimat...
It's a multi-domain Let's Encrypt X3 certificate and I believe most LE users will be in a similar boat now.
Cisco sounds like a router might by running a MITM on you?
Edit: This looks to be confirmation that that root (or one by a very similar name) is used by a MITM tool:
https://docs.umbrella.com/deployment-umbrella/docs/rebrand-c...
I disagree with this assessment. Lua is still far superior as an embed-able scripting language/runtime. I suspect the preference for JavaScript is mostly due to the Deno developers' familiarity and preference.
I disagree with this assessment.
[0] https://duckduckgo.com/?t=ffab&q=is+luajit+faster+than+v8+ja...
Probably it will not replace node soon, but it is a possible outcome.
Also didn't luajit had the problem that it would never move to more recent version of lua? I remember that some years ago there was some talking about this.
> Deno is a new runtime for executing JavaScript and TypeScript outside of the web browser.
So Lua, but Javascript? Could be neat
I'm sure I'm missing something obvious in that example, but that capability terrifies me.
It's also exactly what the websites you visit do. ;)
I'm not sure how this works in detail here, but at least in NPM you got a chance to download packages, inspect them and fix the versions if so desired. Importantly, this gave you control over your transitive dependencies as well.
This seems more like the curl | bash school of package management.
Edit: This is explained in more detail at https://deno.land/manual/linking_to_external_code and indeed seems a lot more sane.
> It's also exactly what the websites you visit do. ;)
Well yes, and it causes huge problems there already - see the whole mess we have with trackers and page bloat.
Even with all NPMs flaws, I do feel this is a bit of throwing the baby out with the bath water. Time will tell.
That's not true here. If I'm running a web server I'm going to need to give the app permission to read the files being served and access to the database. That something that never happens in the browser.
This is definitely false. For all the problems with the NPM registry and the Node dependency situation, an NPM package at a specific version is not just at the whims of whatever happens to be at the other end of a URL at any given moment it's requested. This is a huge vulnerability that the Node/NPM world does not currently have.
Deno does have lockfiles: https://deno.land/manual/linking_to_external_code/integrity_...
I prefer imports from URLs. And I loathe npm. I get why people would disagree though.
Always commit your lock files people
I don’t know the state of the art anymore, but I’m sure they have ways to make it easy to vendor deps in the repo.
"web browsers already do this ;)" isn't a good comparison.
Actually, no Deno webserver I've written gets fs access. Some only get --allow-net.
Here is the page with more detail. https://deno.land/manual/getting_started/permissions
It can even restrict access down to a specific directory or host. This is cool.
Whereas any NPM module can map your subnet, lift your .ssh directory, and yoink environment variables, wily-nily.
It's happened before.
It'd be nice to have some capability model where modules can only access things through handles passed to them, but probably infeasible for a project like this.
> Production software should always bundle its dependencies. In Deno this is done by checking the $DENO_DIR into your source control system, and specifying that path as the $DENO_DIR environmental variable at runtime.
https://deno.land/manual/linking_to_external_code
So I basically have to do manually, what NPM/yarn do for me already?
You can use lock-files, bundles, and many other features that makes dependencies management easier.
https://deno.land/manual/linking_to_external_code
I don't find versioned URLs much more difficult to work with than package@<version> though.
jokes aside, i wonder how import-via-url will impact tooling. having to parse arbitrary JS (or even run it, for dynamic imports?) seems like it'd make writing a "list all dependencies" tool much harder than a "dumb" JSON/TOML/whatever file would. though i guess Go does a similar thing, and afaik they're fine
You can add an “integrity” attribute to script tags in the browser.
https://developer.mozilla.org/en-US/docs/Web/Security/Subres...
This is pretty much like all the bash one-liners piping and executing a curl/wget download. I understand there are sandbox restrictions, but are the restrictions on a per dependency level, or on a program level?
If they are on a program level, they are essentially useless, since the first thing I'm going to do is break out of the sandbox to let my program do whatever it needs to do (read fs/network etc.). If it is on a per dependency level, then am I really expected to manage sandbox permissions for all of my projects dependencies?
If you want to "feel" as safe, you have import maps in deno, which works like package.json.
Overall, I think Deno is more secure because it cuts the man in the middle (npm) and you can make a npm mirror with low effort, a simple fork will do. Which means you can not only precisely pin which code you want, but also make sure nobody knows you use those packages either.
Take it with an open mind, a new "JSX" or async programming moment. People will hate it, then will start to see the value of this design down the road.
I don't detest NPM in the way that some people do, but I have always worried about the implications of the fact that nearly the entire community relies on their registry. If they ever fell over completely, they would have hamstrung a huge amount of the JS community.
npm installs aren't the same as installing from a random URL, because:
* NPM (the org) guarantees that published versions of packages are immutable, and will never change in future. This is definitely not true for a random URL.
* NPM (the tool) stores a hash of the package in your package-lock.json, and installing via `npm ci` (which enforces the lockfile and never updates it in any case) guarantees that the package you get matches that hash.
Downloading from a random URL can return anything, at the whims of the owner, or anybody else who can successfully mitm your traffic. Installing a package via npm is the same only the very first time you ever install it. Once you've done that, and you're happy that the version you're using is safe, you have clear guarantees on future behaviour.
they know there is a bad mitm vector and won't fix it
It'd be interesting to look at ways to mitigate that by requiring anybody using a package version to rehost it for others (since they have a copy locally anyway, by definition). But then you're talking about some kind of IPFS server built into your package manager, which now needs to be always running, and this starts to get seriously complicated & practically challenging...
Do you trust this thing? Better off developing it yourself, or working with something you trust then.
>> We certainly think there are improvements that can be done here on top of the existing TypeScript compiler, but it's clear to us that ultimately the type checking needs to be implemented in Rust.
Funny, I was just talking about something like this in an earlier TypeScript discussion today. I was saying that I don't understand why Microsoft doesn't have their own native TypeScript runtime engine by now.
I have nothing against TypeScript as a language but I hate the TypeScript transpiler; it should be packaged as an engine, not as a transpiler. I just hate having to debug mangled transpiled code and dealing with sourcemaps. I want to be able to run and debug my own code, not some alternative mangled version of it.
I think Deno is a promising project in the sense that they seem to understand the drawbacks of transpilation and are actually trying to provide TypeScript support which feels native. Everyone else seems to be ignoring this problem including the creators of TypeScript.
what would they do with it? ship it in Edge? great, now some small fraction of users can run TS natively. but most can't, so everyone would still transpile to JS anyway...
it could work if Google did it, but i don't think MS has enough market share to have an influence here
Look into ts-node. It lets me run and debug the TypeScript itself before transpiling it.
You know what would be extra amazing? Incorporating (at some point in the future) all of the very smart stuff that the unison people have been doing. That would be _tremendous_ for code re-use and guarantees about remote packages. What I wouldn't give for a JS vm that could do all that. . . .
* https://www.unisonweb.org/docs/tour
What’s the relevance of IPFS?
> Supports TypeScript out of the box.
Seems like a small thing, but it has me interested all on its own. It's a huge pain to set up a whole build process just for TypeScript (which is generally the only preprocessing you need outside of the browser).
The catch for me is that it's probably not suitable for a sever in production as mentioned elsewhere in this thread.
I noticed in a couple of popular TypeScript (+React fullstack) boilerplates, that they were using ts-node to run the server in production.
Unlike babel-node, there's no mention in the documentation to avoid using it in production - but I figured there'd be performance impact, since it's transpiling on the fly (I suppose just once per require).
Reminds me of https://npm.anvaka.com/#/view/2d/react-native
Good luck, though. Everyone lives in a different (mental) tribe I suppose...