top | item 25366484

Deno 1.6 supports compiling TypeScript to a single executable

657 points| andyfleming | 5 years ago |github.com

280 comments

order
[+] j1elo|5 years ago|reply
I've been using vercel/pkg with great success, in order to achieve a similar target and package a whole application into a standalone executable:

https://github.com/vercel/pkg

This can be useful for people wanting to do this with Node. It's nice to have a single file that can be started right away without any external dependency. And also, it prevents from having to distribute the full sources. Kudos to the Deno devs who have integrated this option directly into the runtime.

[+] galaxyLogic|5 years ago|reply
I'm using vercel/pkg as well. I have a Node.js server which generates HTML and opens a browser on Windows which then asks the server for that html at 127.0.0.1.

So browser will be my GUI and Node.js packaged with vercel/pkg my back-end. It is more flexible than say Electron because GUI can be anything I want it to be.

My concern is only will users accept a local server running on their desktop. I've tried to configure the executable so that the server accepts connections only from the same host as where the http-requests are coming from.

I assume the same situation would exist with Denon, if you build a product with it and want to use the browser as your front-end. Are users OK with a server running on their PC?

[+] 205g0|5 years ago|reply
What I like about not integrating the build-step as Deno does: You allow competition and the market comes up with great ideas like Vercel did with pkg.

Building TS projects is quite demanding and I doubt if one party monopolizes this important step and thinks it does the best job it will degenerate an ecosystem. Even the TS team says the build system is not the core of their work, they just have one for convenience but encourage the community to compete and complement. Integrating build systems is good for beginners who struggle with them but for the rest? IDK.

Or in other words, Deno wants to be more than just an opinionated node-Typescript-distribution nobody cares about but then they need to create this ecosystem and focus on the core (what's their core and value add other than repackaging node and TS would be the next discussion).

With integrating the build step they do the exact opposite, they shut-down an ecosystem before it can even start. There's a night and day difference between good and bad build systems and only competition and a rich ecosystem can bring up the best solutions.

FWIW, there're tons of ways to compile TS, every with different trade-offs and it's good that we have these options.

[+] cocktailpeanuts|5 years ago|reply
I'm not very familiar with Deno but I wonder how deno compile compares to pkg when it comes to native modules.

One of my gripes with PKG (and all other node.js packaging tools) has been that it's a pain in the ass to package when your dependency includes a native module, for example SQLite.

Since Deno has a different architecture and works in different ways, thought I would ask just in case there's a solution for this on Deno, that would be great.

[+] mrkurt|5 years ago|reply
This is such a good feature. Go has been great for shipping single purpose binaries (like the CLI for https://fly.io), but I really enjoy writing TypeScript more than Go.
[+] echelon|5 years ago|reply
A lot of languages are doing single static binary deploys now. Rust, Nim, Go. It's a really nice pattern.

Static binaries are so much easier that the gross PHP / Ruby / Python pattern that has to ship directories full of files that (usually) have to be put in the correct place.

It's also easier than shipping a runtime like a JVM.

With a single binary, containers get even slimmer.

[+] Siilwyn|5 years ago|reply
Definitely, I do wonder how it compares in binary size. Especially the 'baseline' size of a hello world.
[+] bartlomieju|5 years ago|reply
Hey, Bartek from deno.land here.

I'll be more than happy to answer your questions about Deno and its development.

[+] nikisweeting|5 years ago|reply
Last time I tried deno there was some friction with depending on npm packages that didn't natively support deno without vendoring, is that easier nowadays? Can we seamlessly import anything from npm inside deno-run code and use the deno stdlib side-by-side with node_modules code? We love the Deno direction and would even willing to donate $ to grow its development, but for us it's pretty much non-starter to switch to a different runtime until we can use the wealth of packages available on npm without any additional friction.

The Deno docs here almost seem to purposefully avoid answering this question: https://deno.land/[email protected]/examples/import_export

[+] christophilus|5 years ago|reply
Last I looked, there was no clear crypto story for Deno. Has that improved, or are there any concrete plans for it? Deno was really quite nice when I kicked the tires, but didn't seem quite ready for prime time web development with no crypto functions.
[+] flowerlad|5 years ago|reply
OK, so what is Deno? How is it different from Node? Why did you make Deno given that Node exists?

Looks like Deno can run .ts files without first compiling to .js. What are the other benefits?

[+] the_gipsy|5 years ago|reply
What's your plan for importing other typescript packages, natively?

Last I remember is that every project/library has vastly different tsconfigs.

[+] jbirer|5 years ago|reply
What are you wearing right now?
[+] lemax|5 years ago|reply
We use vercel/pkg to distribute our product as a standalone executable that runs in on-prem windows environments. Our product is actually comprised of multiple NodeJS servers that are spawned as child processes in one master Node procees, and that module gets built using pkg. We also have a windows installer that configures a windows service to run the executable/keep it up. It’s proven to be a really simple way to distribute our app to the enterprise that’s been working for a few years. It doesn’t really protect source code, but provides a decent enough level of obsfuscation for our needs.
[+] thisjeremiah|5 years ago|reply
We’ve been following a similar process for our internal tools and have found it to be a good solution. Manually including native libraries is probably the only lousy part. Out of curiosity, what are you using to achieve the windows service installation? We’ve been using nssm, which has worked okay, but I’m curious if there’s a better way of doing it.
[+] kumarvvr|5 years ago|reply
I wonder if it's possible for TypeScript to be a .NET CLR supported language. It would be great to have a powerful scripting language for the .NET Ecosystem.

I know C# can be used for scripting, but I want something like Python, an easy to use, dynamic language that has the performance of the .NET VM

[+] rodrigoj42|5 years ago|reply
YMMV but I think F# fills that gap nicely
[+] breatheoften|5 years ago|reply
deno seems really amazing. This is essentially single file distribution of a secure runtime for application code -- that is a lot of platform-capability-bang for the distribution-reach-complexity buck! This has to already be the best server container format for typical application code in terms of the security possibilities doesn't it?

I'd almost like to see deno grow some kind of puppeteer based browser api as server-app platform --

http request -> deno server process runtime (with secure sandbox) and puppeteer-like handle to the client browser for state transfer -> client ui render ... it would be quite interesting to think of the client browser page tabs as a "child process launched by the server" rather than as as a stateless request from an http client -- as most server rest api architectures tend to push you towards ...

[+] qaq|5 years ago|reply
Once ecosystem grows a bit Deno will be a very good alternative to Node. This particular feature is great for simpler deployment.
[+] corytheboyd|5 years ago|reply
Just throwing it out there for visibility, ncc will compile a TS entrypoint down to a single file as well, without having to use Deno https://www.npmjs.com/package/@vercel/ncc

Edit: I completely missed that this Deno release packaged the runtime as well, disregard this as an alternative! Guess I’ll eat the downvotes I deserve :P

[+] kungfufrog|5 years ago|reply
Not sure ncc is an equivalent. I think nexe or pkg are comparable, they bundle a runtime into the exe whereas ncc just reduces the code down to a single distributable code file in that you still need node installed to run it on the target host.
[+] mdtusz|5 years ago|reply
This still requires a node runtime. As far as I understand, the deno usage creates a single executable - batteries included.
[+] jonny_eh|5 years ago|reply
> without having to use Deno

But you need to use ncc? What's the relevant difference?

[+] josephg|5 years ago|reply
I really like this.

I've been thinking a lot over the last few years about Docker. Arguably docker is just another abstraction for "statically linked executable". But we've had static executables for years; and they work well, and the ABI for the linux kernel is very stable. So increasingly I'm not convinced docker is worth it, compared to just building and deploying bundled executables. And executables can be run anywhere, they don't need a separate testing environment, they can be debugged easily[1], and so on.

[1] Well, if you like systemd or have a reasonable replacement.

[+] SiVal|5 years ago|reply
Node is almost perfectly matched to the "Oops, well, too late now" design ethos of JavaScript itself. Nobody was stupid. We humans just can't really predict what will work out and what won't in the future, and this was one of those frustrating cases like carving in stone, where every mistake you make is permanent.

But a combination of various factors made the web an enormously impactful medium. It's too important to take the approach of "well, let's just add some good stuff to the bad and live with it" where we don't have to. We have to in the browser, but we don't have to on the server. I want to see the "benefit of hindsight, rebuild it better" design of TypeScript matched with a server-side equivalent, which looks like Deno.

I hope Deno succeeds.

[+] qsort|5 years ago|reply
> Node is almost perfectly matched to the "Oops, well, too late now" design ethos of JavaScript itself.

Anything even remotely successful has to commit to its previous choices, even when they were unfortunate (did anybody say C++?).

One of the reasons why Node had the impact it had was that it used plain JS and committed to supporting the standard language.

I myself prefer writing in statically-typed languages, but the JS direction is frankly commendable; ES6 looks nothing like OG JS, and the fact you can run basically the same code on the browser and on node is a massive bonus.

With that said, I hope Deno succeeds as well, having more choices is a good problem to have!

[+] earthboundkid|5 years ago|reply
TBF, on the browser side, they have been slowly fixing some of the worst "oops" stuff. First they added "strict mode" and now they have type="module", both of which turn off a lot of bad behaviors. Deno is kind of like that for the backend.
[+] offtop5|5 years ago|reply
Does this offer a speed increase vs running the the code directly using $ deno test.js ( not sure what the exact command is )
[+] CraftThatBlock|5 years ago|reply
Not really (at least yet, I think). This simply bundles the Deno binary and the script (I think the pre-compiled, as in TypeScript -> JavaScript, then possibly as pre-compiled AST). This is why the output binary size is the original Deno binary + the script size (roughly).

So it's functionally equivalent to running using deno test.js

[+] andyfleming|5 years ago|reply
No, there's not really any optimization. It's more of a bundling convenience. It still includes V8.
[+] sandGorgon|5 years ago|reply
Whoa!

Potentially this can make React Native hit the same performance as Flutter+Dart.

as the Dart team claimed - https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf

>Dart is one of very few languages (and perhaps the only “mainstream” language) that is well suited to being compiled both AOT and JIT. Supporting both kinds of compilation provides significant advantages to Dart and (especially) Flutter.

[+] tarruda|5 years ago|reply
What this deno feature does is not AOT, but simply packaging the JS as an embedded resource in the executable. JS is still parsed and compiled at runtime.
[+] jariel|5 years ago|reply
Question for those who know better: wouldn't this better be accomplished by some kind of archive/bundle? ie keep the packaging structure intact, but just archive it?
[+] peanut_worm|5 years ago|reply
Wow that’s really cool. I have a lot of hope for Deno, seems very promising.
[+] motyar|5 years ago|reply
How to make it work for mac?
[+] jerrygreenest|5 years ago|reply
47mb executable for a simple cat command? Huh, there's huge area for improvements indeed
[+] slmjkdbtl|5 years ago|reply
You should never use deno to make small programs like cat where you don't absolutely rely on deno features. Tons of other languages / tools can give you 100kb and faster binaries.
[+] svnpenn|5 years ago|reply
Yeah, and the executable is 47 MB. You can do the same thing with Go:

    package main
    import "os"
    func main() {
       for _, s := range os.Args[1:] {
          o, _ := os.Open(s)
          os.Stdout.ReadFrom(o)
       }
    }
and the executable is 1 MB.
[+] PaulBGD_|5 years ago|reply
This would be more comparable to packaging a Java program into an executable, which would have to also contain the JIT. I don't think it's fair to compare a JIT'd language to a AOT'd language.
[+] dguaraglia|5 years ago|reply
Sure, and you can do something similar with C and obtain a ~10kb executable, or even less if you put some effort. Or write that in Java and need a complex setup including the JRE and a bunch of packages to support it.

The point is that this makes deploying a Deno application simpler. Binary size is kind of the wrong metric to worry about.

[+] txdv|5 years ago|reply
Why is Go's binary so big?
[+] ameliaquining|5 years ago|reply
If the 47 MB executable has no dependencies other than the kernel, then in many scenarios it'd be a lot easier to deploy than if you had to separately install a language runtime.

Of course, Node.js can also do this with pkg, and also I don't know whether executables produced this way really are dependency-free (although depending only on widely-available shared libraries would be almost as good).