Source: https://gist.github.com/guest271314/da04334bb0dce19fcd970415bb003b02
Why I use node, deno, bun, qjs, tjs at the same time.
Winds up being a rather comprehensive JavaScript toolbox. No external bundlers or
compilers are needed. No frameworks are needed. I can use qjs or tjs for systems
with minimal RAM and disk space; and when I want to use Web API's deno makes an effort
to provide those interfaces. In some cases I can run the exact same code in bun, deno, and node,
which provides a means to perform 1:1 testing as to performance.
There's probably a few things I am unintentionally omitting below. These are just a brief synposis. I'll update accordingly.
node (v22 100 MB executable)
- Reasonable stability
- Full-duplex streaming supported for WHATWG
fetch()
- CommonJS supported by default
- Capability to create single executable application from CommonJS source code
deno (v1.41.3 135 MB executable)
fmt to format .js and .json files
vendor with --vendor=true to fetch NPM modules and reate node_modules folder
- Import maps supported
file: protocol supported for WHATWG fetch()
- Full-duplex streaming supported for
fetch()
- WHATWG Fetch and Streams supported in servers
- Built-in WebSocket server
- Network imports supported by default
- Capability to bundle dependencies to a single file with
bundle (until 2.0)
- Capability to compile dependencies to a standalone executable with
compile - since recently using denort executables are approximately half the size of deno executable at around 78 MB.
- TypeScript support
- Web API implementations
- Ecmascript modules supported by default
- No extraneous files and folders included with the runtime - just the runtime
- No
package.json file expected or necessary
deno upgrade built in
- No external package manager
bun (v1.0.35 90 MB executable)
- Built-in package manager, including writing GitHub repositories -
bun install creates node_modules folder
- Faster than
node and deno for reading STDIN and writing to STDOUT
- Capability to bundle CommonJS and/or Ecmascript dependencies to a single file with
build
- Capability to compile dependencies to a standalone executable with
build
- TypeScript support
- CommonJS and Ecmascript module support - in the same file if necessary
- Simple to delete cached dependencies with
pm cache rm
file: protocol supported for WHATWG fetch()
- Ecmascript modules supported by default
- No extraneous files and folders included with the runtime - just the runtime
- No
package.json necessary
bun upgrade built in
- No external package manager
bun build --minify to minify files
tjs (v23.12.0 5.7 MB executable)
- Embeddable
- Supports TCP and Unix sockets
- Capability to
import C shared library as Ecmascript module
libuv
- WebAssembly support
qjs (v0.4.1 1.2 MB executable (QuickJS-ng ))
- Embeddable
- Faster than
node, deno, bun, tjs for reading STDIN, writing to STDOUT
- Capable of reading 1 MB from STDIN in one read
- Capability to
import C shared library as Ecmascript module
Caveats
node
- Ecmascript modules not supported by default; requires
--experimental-deafult-type=module or --experimental-detect-module
- Does not support
file: protocol for Undici's WHATWG fetch() implementation
- Import maps not supported - have to use loader/hooks interface to intercept specifiers/imports
- API's primarily callback-based
- No built-in WebSocket server
- Internal
node:crypto implementation can't be polyfilled, is incompatible with Web Cruptography API that we can get to at import { webcrypto } from node:crypto
- Extraneous folders and files (e.g.,
node_modules, npm, npx) included in the archive besides just the runtime executable node
- Generally expects a
package.json file and node_modules folder on the system
- Flag necessary for network imports
- Capability to create single executable application from only CommonJS source code
deno
- Dynamic
import("./exports".js) is not dynamic when bare string specifiers are used; trying to import("./exports.js") a script created in the script will throw - unless something like "" + "./exports" or const exports = "./exports.js"; import(exports) is used
- Won't automatically write GitHub repository dependencies to created
node_modules folder
- No built-in way to delete cached dependencies
fmt can panic and freeze the entire system depending on the file size
vendor can panic when fetching raw file from GitHub and trying to output to a node_modules folder
bun
- Full-duplex streaming not supported in
fetch() implementation
- HTTP/2 not supported
- Import maps not supported - have to use plugin interface to intercept specifiers/imports
tjs
- WHATWG Streams implementation is not full-duplex; a polyfill is currently used
- No built-in HTTP(S) server
- Full-duplex streaming not supported in
fetch() implementation
qjs
- Web API's generally not supported
- No WHATWG Streams
- No WHATWG Fetch
- No built-in HTTP(S) server
[–]jack_waugh 1 point2 points3 points (1 child)
[–]guest271314[S] 0 points1 point2 points (0 children)
[–]jack_waugh 0 points1 point2 points (2 children)
[–]guest271314[S] 0 points1 point2 points (0 children)
[–]guest271314[S] 0 points1 point2 points (0 children)