Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
New QuickJS Release (github.com/bellard)
78 points by rdtsc on Dec 9, 2023 | hide | past | favorite | 27 comments


I just upgraded quickjs-emscripten - my JS-in-JS wrapper library - to this new version of the upstream quickjs.

If you want to safely evaluate untrusted Javascript in the browser or Node with control over CPU time and memory use, a custom module system, or call async code synchronously, check it out: https://github.com/justjake/quickjs-emscripten

It's used by a few projects like Hoppscotch, a Postman-like visual API client (https://hoppscotch.io/). They use it for request scripting: https://docs.hoppscotch.io/documentation/getting-started/res...


Also see quickjs-ng [0], which is a fork in active development. A lot of missing ES features have already been added. [1]

[0] https://github.com/quickjs-ng/quickjs

[1] https://github.com/quickjs-ng/quickjs/issues/54


QuickJS is really cool! You can use it to embed JS code in a native binary, which is nice if you're trying to use a NodeJS library outside of the JS ecosystem.

I put together a proof of concept for this about a year ago, in case this is a use case you currently have: https://github.com/ijustlovemath/jescx


stupid question but... doesn't Deno also promise that possibility? Or at least to compile a js app into a binary


Yes, although the sizes of the binaries differ greatly. See this [1] Twitter reply. A "hello world" example produced an ~85mb binary in Node and Deno, whereas QuickJS produced a 6MB binary.

[1] https://nitter.net/kebsworld/status/1648488613351657474#m


The standard library or use-cases are not even comparable though, right?

If I wanted to make a HTTPS request in quickjs I'd probably need to pull in openssl, write a http parser, etc, etc.

I might be wrong, but comparing quickjs to node/deno seems like comparing a aquarium pump to an electric car. They both contain engines that are driven by electricity, but the similarities stop there. They are both good at what they do, but I would never replace one with the other.


No, you are right. Deno and Node include the V8 engine which was built by a team at Google for the Chromium browser. QuickJS was built by Fabrice Bellard for the purposes of making an embeddable JavaScript engine. They have completely different scopes. But it is not impossible that your use-case may not need HTTP or other functionality afforded by larger runtimes, in which case, I'd rather have a 6MB binary over an 85MB binary that has a bunch of things I don't need.

> I might be wrong, but comparing quickjs to node/deno seems like comparing a aquarium pump to an electric car.

My intention was not to compare QuickJS to Node/Deno, only their ability to create small binaries.


From what I can tell, Deno doesn't allow you to compile JS code into a native library, which was my primary use case. Also, QuickJS is much easier for me personally to grok, and to integrate into my existing build system, so it was a no-brainer.

The only time I'd prefer another runtime is if I had really high performance expectations, but if that was the case, I'd probably write a new implementation of the JS library in a performance focused language versus try to shoehorn JS into doing something it wasn't designed to do


Even if it does, it's always nice to have other options with different trade-offs


As an example, I had a Makefile that ran a JS engine a few hundred times and Deno had ~240ms of startup overheard (on a very slow computer) versus QuickJS having around 20ms. But when running CPU-intensive JS (Marked.js and highlight.js), Deno was roughly 6x faster.

I wanted to try Bun, but it had some blocking bugs at the time (which have since been resolved—or so I’ve read).


One quick improvement would be to have a Readme.


There is a readme on the project's main page: https://bellard.org/quickjs/

The newsworthy bit here is that the activity seemed to have stalled for year or two and now Fabrice pushed a few fixes and made a new release.


When I look at quickJS, I am thinking: Can we design a DOM, minimal enough, but good enough for a new "web", with ultra stable ABIs/APIs in time, which would not require one of the grotesquely and absurdely massive and complex current web engines? (including their SDKs). Which I could compile with a near 0 SDK and a simple C compilers (avoiding the latest ISO C tantrums and compiler-specific extensions)

Event loops, a dynamic pixel canvas, very little and basic audio/video/network/vector drawing interfaces.

Something along that line. I know that the hard parts would be to decide when this framework is "done" and keep it immune to non critical change/feature creeps etc.


We’ve been considering this library at work for a performance sensitive application (real time game). Can anyone here speak to the performance and memory usage of QuickJS?


Performance is pretty good if you consider starting and running small scripts. There is an interesting feature of compiling a js file into a C array bytecode so your runtime code could load that directly skipping the parsing step.

For a long running orlarge JS code something like Spidermonkey or V8 with their JITs might be faster. But they are not as embedding friendly and their code bases are much larger.


Here are some benchmarks: https://bellard.org/quickjs/bench.html


Out of curiosity, why not Lua?


Is Lua performance sensitive? Other guess is Javascript is much more programmer friendly than Lua.


Some would argue Lua is friendlier than JS.

LuaJIT is pretty good as far as performance goes. In these benchmarks, sometimes slower than Node/Bun but uses consistently less memory too:

https://programming-language-benchmarks.vercel.app/lua-vs-ja...


Why Lua?


I am truly impressed and grateful by the immense work done by Fabrice in this and other projects. He stood out with few other greats.


I'm glad the project isn't dead-dead but still not a good sign it didn't get any love for 2+ years.


I guess because it is mostly finished.

Just need adding some new "pertinent" standard stuff, once in while.


Whats the difference between this and JS Shadow Realms? At a glance it sounds similar


Sorry, actually went to the website itself and read up on QuickJS - the repo wasn't clear due to lack of read-me.


Based on your comment below I think you figured out the difference - but if you're looking to execute untrusted Javascript from Javascript in Node or the browser, you can pick between ShadowRealm (where available, or using a polyfill) or my library quickjs-emscripten.

Pros of quickjs-emscripten over ShadowRealm:

- You can use quickjs today in any browser with WASM. ShadowRealm isn't available yet, and polyfills have had security issues in the past. See https://www.figma.com/blog/an-update-on-plugin-security/

- In ShadowRealm eval, untrusted code can consume arbitrary CPU cycles. With QuickJS, you can control the CPU time used during an `eval` using an [interrupt handler] that's called periodically during the eval.

- In ShadowRealm eval, untrusted code can allocate arbitrary amounts of memory. With QuickJS, you can control both the [stack size] and the [heap size] available inside the runtime.

- quickjs-emscripten can do interesting things with custom module loaders and facades that allow synchronous code inside the runtime to call async code on the host.

Pros of ShadowRealm over QuickJS:

- ShadowRealm will (presumably?) execute code using your native runtime, probably v8, JavaScriptCore, or SpiderMonkey. Quickjs is orders of magnitude slower than JIT'd javascript performance of v8 etc. It's also slower than v8/JSC's interpreters, although not by a huge amount. See [benchmarks] from 2019.

- You can easily call and pass values to ShadowRealm imported functions. Talking to quickjs-emscripten guest code requires a lot of fiddly and manual object building.

- Overall the quickjs(-emscripten) API is verbose, and requires manual memory management of references to values inside the quickjs runtime.

[interrupt handler]: https://github.com/justjake/quickjs-emscripten/blob/main/doc...

[stack size]: https://github.com/justjake/quickjs-emscripten/blob/main/doc...

[heap size]: https://github.com/justjake/quickjs-emscripten/blob/main/doc...

[benchmarks]: https://bellard.org/quickjs/bench.html


First release since 2021-03-27.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: