Fabrice Bellard Releases MicroQuickJS

17 hours ago (github.com)

If this had been available in 2010, Redis scripting would have been JavaScript and not Lua. Lua was chosen based on the implementation requirements, not on the language ones... (small, fast, ANSI-C). I appreciate certain ideas in Lua, and people love it, but I was never able to like Lua, because it departs from a more Algol-like syntax and semantics without good reasons, for my taste. This creates friction for newcomers. I love friction when it opens new useful ideas and abstractions that are worth it, if you learn SmallTalk or FORTH and for some time you are lost, it's part of how the languages are different. But I think for Lua this is not true enough: it feels like it departs from what people know without good reasons.

  • I don't love a good deal of Lua's syntax, but I do think the authors had good reasons for their choices and have generally explained them. Even if you disagree, I think "without good reasons" is overly dismissive.

    Personally though, I think the distinctive choices are a boon. You are never confused about what language you are writing because Lua code is so obviously Lua. There is value in this. Once you have written enough Lua, your mind easily switches in and out of Lua mode. Javascript, on the other hand, is filled with poor semantic decisions which for me, cancel out any benefits from syntactic familiarity.

    More importantly, Lua has a crucial feature that Javascript lacks: tail call optimization. There are programs that I can easily write in Lua, in spite of its syntactic verbosity, that I cannot write in Javascript because of this limitation. Perhaps this particular JS implementation has tco, but I doubt it reading the release notes.

    I have learned as much from Lua as I have Forth (SmallTalk doesn't interest me) and my programming skill has increased significantly since I switched to it as my primary language. Lua is the only lightweight language that I am aware of with TCO. In my programs, I have banned the use of loops. This is a liberation that is not possible in JS or even c, where TCO cannot be relied upon.

    In particular, Lua is an exceptional language for writing compilers. Compilers are inherently recursive and thus languages lacking TCO are a poor fit (even if people have been valiantly forcing that square peg through a round hole for all this time).

    Having said all that, perhaps as a scripting language for Redis, JS is a better fit. For me though Lua is clearly better than JS on many different dimensions and I don't appreciate the needless denigration of Lua, especially from someone as influential as you.

    • > For me though Lua is clearly better than JS on many different dimensions and I don't appreciate the needless denigration of Lua, especially from someone as influential as you.

      Is it needless? It's useful specifically because he is someone influential, and someone might say "Lua was antirez's choice when making redis, and I trust and respect his engineering, so I'm going to keep Lua as a top contender for use in my project because of that" and him being clear on his choices and reasoning is useful in that respect. In any case where you think he has a responsibility to be careful what he says because of that influence, that can also be used in this case as a reason he should definitely explain his thoughts on it then and now.

    • > I think the distinctive choices are a boon. You are never confused about what language you are writing because Lua code is so obviously Lua. There is value in this.

      This. And not just Lua , but having different kind of syntax for scripting languages or very high level languages signal it is something entirely different, and not C as in system programming language.

      The syntax is also easier for people who dont intend to make programming as their profession, but simply want something done. It used to be the case in the old days people would design simple PL for new beginners, ActionScript / Flash era and even Hypercard before that. Unfortunately the industry is no longer interested in it, and if anything intend to make every as complicated as possible.

    • Formally JavaScript is specified as having TCO as of ES6, although for unfortunate and painful reasons this is spec fiction - Safari implements it, but Firefox and Chrome do not. Neither did QuickJS last I checked and I don't think this does either.

    • > Lua has a crucial feature that Javascript lacks: tail call optimization.

      I'm not familiar with Lua, but I expect tco to be a feature of the compiler, not of the language. Am I wrong?

      16 replies →

    • I do not think your compiler argument in support of TCO is very convincing.

      Do you really need to write compilers with limitless nesting? Or is nesting, say, 100.000 deep enough, perhaps?

      Also, you'll usually want to allocate some data structure to create an AST for each level. So that means you'll have some finite limit anyway. And that limit is a lot easier to hit in the real world, as it applies not just to nesting depth, but to the entire size of your compilation unit.

      1 reply →

    • > as my primary language

      I'd love to hear more how it is, the state of the library ecosystem, language evolution (wasn't there a new major version recently?), pros/cons, reasons to use it compared to other languages.

      About tail-calls, in other languages I've found sometimes a conversion of recursive algorithm to a flat iterative loop with stack/queue to be effective. But it can be a pain, less elegant or intuitive than TCO.

      1 reply →

    • Re: TCO

      Does the language give any guarantee that TCO was applied? In other words can it give you an error that the recursion is not of tail call form? Because I imagine a probability of writing a recursion and relying on it being TCO-optimized, where it's not. I would prefer if a language had some form of explicit TCO modifier for a function. Is there any language that has this?

      6 replies →

    • > More importantly, Lua has a crucial feature that Javascript lacks: tail call optimization. There are programs that I can easily write in Lua, in spite of its syntactic verbosity, that I cannot write in Javascript because of this limitation. Perhaps this particular JS implementation has tco, but I doubt it reading the release notes.

      > [...] In my programs, I have banned the use of loops. This is a liberation that is not possible in JS or even c, where TCO cannot be relied upon.

      This is not a great language feature, IMO. There are two ways to go here:

      1. You can go the Python way, and have no TCO, not ever. Guido van Rossum's reasoning on this is outlined here[1] and here[2], but the high level summary is that TCO makes it impossible to provide acceptably-clear tracebacks.

      2. You can go the Chicken Scheme way, and do TCO, and ALSO do CPS conversion, which makes EVERY call into a tail call, without language user having to restructure their code to make sure their recursion happens at the tail.

      Either of these approaches has its upsides and downsides, but TCO WITHOUT CPS conversion gives you the worst of both worlds. The only upside is that you can write most of your loops as recursion, but as van Rossum points out, most cases that can be handled with tail recursion, can AND SHOULD be handled with higher-order functions. This is just a much cleaner way to do it in most cases.

      And the downsides to TCO without CPS conversion are:

      1. Poor tracebacks.

      2. Having to restructure your code awkwardly to make recursive calls into tail calls.

      3. Easy to make a tail call into not a tail call, resulting in stack overflows.

      I'll also add that the main reason recursion is preferable to looping is that it enables all sorts of formal verification. There's some tooling around formal verification for Scheme, but the benefits to eliminating loops are felt most in static, strongly typed languages like Haskell or OCaml. As far as I know Lua has no mature tooling whatsoever that benefits from preferring recursion over looping. It may be that the author of the post I am responding to finds recursion more intuitive than looping, but my experience contains no evidence that recursion is inherently more intuitive than looping: which is more intuitive appears to me to be entirely a function of the programmer's past experience.

      In short, treating TCO without CPS conversion as a killer feature seems to me to be a fetishization of functional programming without understanding why functional programming is effective, embracing the madness with none of the method.

      EDIT: To point out a weakness to my own argument: there are a bunch of functional programming language implementations that implement TCO without CPS conversion. I'd counter by saying that this is a function of when they were implemented/standardized. Requiring CPS conversion in the Scheme standard would pretty clearly make Scheme an easier to use language, but it would be unreasonable in 2025 to require CPS conversion because so many Scheme implementations don't have it and don't have the resources to implement it.

      EDIT 2: I didn't mean for this post to come across as negative on Lua: I love Lua, and in my hobby language interpreter I've been writing, I have spent countless hours implementing ideas I got from Lua. Lua has many strengths--TCO just isn't one of them. When I'm writing Scheme and can't use a higher-order function, I use TCO. When I'm writing Lua and can't use a higher order function, I use loops. And in both languages I'd prefer to use a higher order function.

      [1] https://neopythonic.blogspot.com/2009/04/tail-recursion-elim...

      [2] https://neopythonic.blogspot.com/2009/04/final-words-on-tail...

      1 reply →

    • No offence but it seems that all of the people that are replying to this comment are essentially screaming in the void, if anything among each other.

      I scrolled most of this sub thread and gp seem to not be replying to any of the replies they got.

  • > it feels like it departs from what people know without good reasons.

    Lua was first released in 1993. I think that it's pretty conventional for the time, though yeah it did not follow Algol syntax but Pascal's and Ada's (which were more popular in Brazil at the time than C, which is why that is the case)!

    Ruby, which appeared just 2 years later, departs a lot more, arguably without good reasons either? Perl, which is 5 years older and was very popular at the time, is much more "different" than Lua from what we now consider mainstream.

    • > Ruby, which appeared just 2 years later, departs a lot more, arguably without good reasons either?

      I doubt we ever would have heard about Ruby without it's syntax decisions. From my understanding it's entire raison d'être was readability.

      1 reply →

    • I don't think you understand his point. Ruby has a different syntax because it presents different/more language features than a very basic C-like language; it's inspired by Lisp/SmallTalk, after all. Lua doesn't but still decided to change its looks a lot, according to him.

    •     def ruby(is)
            it = is 
            a = "bad"
            example()
            begin
              it["had"] = pascal(:like)
            rescue
              flow
            end
          end

  • I read this comment, about to snap back with an anecdote how I as a 13 year old was able to learn Lua quite easily, and then I stopped myself because that wasn't productive, then pondered what antirez might think of this comment, and then I realized that antirez wrote it.

    • I’m tickled that one of my favorite developers is commenting on another of my favorites work. Would be great if Nicolas Cannasse were also in this thread!

    • I think the older you are the harder Lua is to learn. GP didn't say it made wrong choices, just choices that are gratuitously different from other languages in the Algol family.

  • It sounds like you're trying to articulate why you don't like Lua, but it seems to just boil down to syntax and semantics unfamiliarity?

    I see this argument a lot with Lua. People simply don't like its syntax because we live in a world where C style syntax is more common, and the departure from that seem unnecessary. So going "well actually, in 1992 when Lua was made, C style syntax was more unfamiliar" won't help, because in the current year, C syntax is more familiar.

    The first language I learned was Lua, and because of that it seems to have a special place in my heart or something. The reason for this is because in around 2006, the sandbox game "Garry's Mod" was extended with scripting support and chose Lua for seemingly the same reasons as Redis.

    The game's author famously didn't like Lua, its unfamiliarity, its syntax, etc. He even modified it to add C style comments and operators. His new sandbox game "s&box" is based on C#, which is the language closest to his heart I think.

    The point I'm trying to make is just that Lua is familiar to me and not to you for seemingly no objective reason. Had Garry chosen a different language, I would likely have a different favorite language, and Lua would feel unfamiliar and strange to me.

  • It wouldn't fix the issue of semantics, but "language skins"[1][2] are an underexplored area of programming language development.

    People go through all this effort to separate parsing and lexing, but never exploit the ability to just plug in a different lexer that allows for e.g. "{" and "}" tokens instead of "then" and "end", or vice versa.

    1. <https://hn.algolia.com/?type=comment&prefix=true&query=cxr%2...>

    2. <https://old.reddit.com/r/Oberon/comments/1pcmw8n/is_this_sac...>

    • Not "never exploit"; Reason and BuckleScript are examples of different "language skins" for OCaml.

      The problem with "skins" is that they create variety where people strive for uniformity to lower the cognitive load. OTOH transparent switching between skins (about as easy as changing the tab sizes) would alleviate that.

      10 replies →

    • One day Brython (python with braces allowing copy paste code to autoindent) will be well supported by LSPs and world peace will ensure

      1 reply →

  • Lua has been a wild success considering it was born in Brazil, and not some high wealth, network-effected country with all its consequent influential muscle (Ruby? Python? C? Rust? Prolog? Pascal? APL? Ocaml? Show me which one broke out that wasn't "born in the G7"). We should celebrate its plucky success which punches waaay above its adoption weight. It didn't blindly lockstep ALGOL citing "adooooption!!", but didn't indulge in revolution either, and so treads a humble path of cooperative independence of thought.

    Come to think of it I don't think I can name a single mainstream language other than Lua that wasn't invented in the G7.

  • Lua having a JIT compiler seems like a big difference though. It was a while since that got major updates, but probably relevant at the time?

  • JavaScript in 2010 was a totally different beast, standartization-wise. Lots of sharp corners and blank spaces were still there.

    So, even if an implementation like MicroQuickJS existed in 2010, it's unlikely that too many people would have chosen JS over Lua, given all the shortcomings that JavaScript had at the time.

  • Out of interest, was Tcl considered? It's the original embeddable language.

    • In 1994 at the second WWW conference we presented "An API to Mosaic". It was TCL embedded inside the (only![1]) browser at the time - Mosaic. The functionality available was substantially similar to what Javascript ended up providing. We used it in our products especially for integrating help and preferences - for example HTML text could be describing color settings, you could click on one, select a colour from the chooser and the page and setting in our products would immediately update. In another demo we were able to print multiple pages of content from the start page, and got a standing ovation! There is an alternate universe where TCL could have become the browser language.

      For those not familiar with TCL, the C API is flavoured like main. Callbacks take a list of strings argv style and an argc count. TCL is stringly typed which sounds bad, but the data comes from strings in the HTML and script blocks, and the page HTML is also text, so it fits nicely and the C callbacks are easy to write.

      [1] Mosaic Netscape 0.9 was released the week before

  • I also strongly disliked luas syntax at first but now I feel like the meta tables and what not and pcall and all that stuff is kinda worth it. I like everything about Lua except some of the awkward syntax but I find it so much better then JS, but I haven't been a web dev in over a decade

  • Lua only departs from norms if you’ve had a very narrow experience with other programming languages.

    Frankly, I welcome the fact that Redis doesn’t use JavaScript. It’s an abomination of a language. The fewer times I need to use it the better.

    • I think criticizing JavaScript has become a way of signaling "I'm a good programmer." Yes, good programmers ten years ago had valid reasons to criticize it. But today, attacking the efforts of skilled engineers who have improved the language (given the constraints and without breaking half of the web) seems unfair. They’ve achieved a Herculean task compared to the Python dev team, which has broken backward compatibility so many times yet failed to create a consistent language, lacking a single right way to do many things.

      3 replies →

  • > it feels like it departs from what people know without good reasons.

    Lua is a pretty old language. In 1993 the world had not really settled on C style syntax. Compared to Perl or Tcl, Lua's syntax seems rather conventional.

    Some design decisions might be a bit unusual, but overall the language feels very consistent and predictable. JS is a mess in comparison.

    > because it departs from a more Algol-like syntax

    Huh? Lua's syntax is actually very Algol-like since it uses keywords to delimit blocks (e.g. if ... then ... end)

    • I known for very long time that c (and co) inherited the syntax from algol.

      But only after long time I tried to check what Algol actually looked like. To my surprise, Algol does not look anything like C to me.

      I would be quite interested in the expanded version of “C has inherited syntax from Algol”

      Edit: apparently the inheritance from Algol is a formula: lexical scoping + value returning functions (expression based) - parenthesitis. Only last item is about visual part of the syntax.

      Algol alternatives were: cobol, fortan, lisp, apl.

      1 reply →

    • > consistent and predictable

      That's what matters to me, not how similar Lua is to other languages, but that the language is well-designed in its own system of rules and conventions. It makes sense, every part of it contributes to a harmonious whole. JavaScript on the other hand.

      When speaking of Algol or C-style syntax, it makes me imagine a "Common C" syntax, like taking the best, or the least common denominator, of all C-like languages. A minimal subset that fits in your head, instead of what modern C is turning out to be, not to mention C++ or Rust.

      5 replies →

  • What are the chances of switching to MQJS or something like it in the future?

  • Not to mention the 1-based indexing sin. JavaScript has a lot of WTFs but they got that right at least.

This engine restricts JS in all of the ways I wished I could restrict the language back when I was working on JSC.

You can’t restrict JS that way on the web because of compatibility. But I totally buy that restricting it this way for embedded systems will result in something that sparks joy

If anyone wants to try out MicroQuickJS in a browser here's a simple playground interface for executing a WebAssembly compiled version of it: https://tools.simonwillison.net/microquickjs

It's a variant of my QuickJS playground here: https://tools.simonwillison.net/quickjs

The QuickJS page loads 2.28 MB (675 KB transferred). The MicroQuickJS one loads 303 KB (120 KB transferred).

  • I was interested to try Date.now() since this is mentioned as being the only part of the Date implementation that is supported but was surprised to find it always returns 0 for your microquickjs version - your quickjs variant appears to return the current unix time.

    • Good catch. WebAssembly doesn't have access to the current time unless the JavaScript host provides it through injecting a function, so the WASM build would need to be hooked up specially to support that.

Well, as Jeff Atwood famously said [0], "any application that can be written in JavaScript, will eventually be written in JavaScript". I guess that applies to embedded systems too

[0] https://en.wikipedia.org/wiki/Jeff_Atwood

Clarification added later: One of my key interests at the moment is finding ways to run untrusted code from users (or generated by LLMs) in a robust sandbox from a Python application. MicroQuickJS looked like a very strong contender on that front, so I fired up Claude Code to try that out and build some prototypes.

I had Claude Code for web figure out how to run this in a bunch of different ways this morning - I have working prototypes of calling it as a Python FFI library (via ctypes), as a Python compiled module and compiled to WebAssembly and called from Deno and Node.js and Pyodide and Wasmtime https://github.com/simonw/research/blob/main/mquickjs-sandbo...

PR and prompt I used here: https://github.com/simonw/research/pull/50 - using this pattern: https://simonwillison.net/2025/Nov/6/async-code-research/

  • Down to -4. Is this generic LLM-dislike, or a reaction to perceived over-self-promotion, or something else?

    No matter how much you hate LLM stuff I think it's useful to know that there's a working proof of concept of this library compiled to WASM and working as a Python library.

    I didn't plan to share this on HN but then MicroQuickJS showed up on the homepage so I figured people might find it useful.

    (If I hadn't disclosed I'd used Claude for this I imagine I wouldn't have had any down-votes here.)

    • I think many subscribe to this philosophy: https://distantprovince.by/posts/its-rude-to-show-ai-output-...

      Your github research/ links are an interesting case of this. On one hand, late AI adopters may appreciate your example prompts and outputs. But it feels like trivially reproducible noise to expert LLM users, especially if they are unaware of your reputation for substantive work.

      The HN AI pushback then drowns out your true message in favor of squashing perceived AI fluff.

      10 replies →

    • Thank you for sharing.

      A lot of HN people got cut by AI in one way or another, so they seem to have personal beefs with AI. I am talking about not only job shortages but also general humbling of the bloated egos.

      2 replies →

    • It is because you keep over promoting AI almost every day of the week in the HN comments.

      In this particular case AI has nothing to do with Fabrice Bellard.

      We can have something different on HN like what Fabrice Bellard is up to.

      You can continue AI posting as normal in the coming days.

      18 replies →

    • I was hoping you experimented with this! I am right there with you, hoping for an easier wasm sandbox for LLMs.

      (Keep posting please. Downvotes due to mentioning LLMs will be perceived as a quaint historic artifact in the not so distant future…)

      1 reply →

    • I think the people interacting with this post are just more likely to appreciate the raw craftsmanship and talent of an individual like Bellard, and coincidentally might be more critical of the machinery that in their perception devalues it. I count myself among them, but didn’t downvote, as I generally think your content is of high quality.

    • Your tireless experimenting (and especially documenting) is valuable and I love to see all of it. The avant garde nature of your recent work will draw the occasional flurry of disdain from more jaded types, but I doubt many HN regulars would think you had anything but good intentions! Guess I am basically just saying.. keep it up.

    • I didn't downvote you. You're one of "the AI guys" to me on HN. The content of your post is fine, too, but, even if it was sketch, I'd've given you the benefit of the doubt.

    • I downvoted because I'm tired of people regurgitating how they've done this or that with whatever LLM of the week on seemingly every technical post.

      If you care that much, write a blog post and post that, we don't need low effort LLM show and tell all day everyday.

      5 replies →

  • What is the purpose of compiling this to web assembly? What web assembly runtimes are there where there is not already an easily accessible (substantially faster) js execution environment? I know wasmtime exists and is not tied to a js execution engine like basically every other web assembly implementation, but the uses of wasmtime are not restricted from dependencies like v8 or jsc. Usually web assembly is used for providing sandboxing something a js execution environment is already designed to provide, and is only used when the code that requires sandboxing is native code not javascript. It sounds like a good way to waste a lot of performance for some additional sandboxing, but I can't imagine why you would ever design a system that way if you could choose a different (already available and higher performance) sandbox.

    • I want to build features - both client- and server-side - where users can provide JavaScript code that I then execute safely.

      Just having a WebAssembly engine available isn't enough for this - something has to take that user-provided string of JavaScript and execute it within a safe sandbox.

      Generally that means you need a JavaScript interpreter that has itself been compiled to WebAssembly. I've experimented with QuickJS itself for that in the past - demo here: https://tools.simonwillison.net/quickjs - but MicroQuickJS may be interesting as a smaller alternative.

      If there's a better option than that I'd love to hear about it!

      7 replies →

    • As I noted in another comment Figma has used QuickJS to run JS inside Wasm ever since a security vulnerability was discovered in their previous implementation.

      In a browser environment it's much easier to sandbox Wasm successfully than to sandbox JS.

      1 reply →

It's unfortunate that he uploaded this without notable commit history, it would be interesting to see how long it takes a programmer of his caliber to bring up a project like this.

That said, judging by the license file this was based on QuickJS anyway, making it a moot comparison.

I wonder if this could become the most lightweight way for yt-dlp to solve YouTube Javascript challenges.

https://github.com/yt-dlp/yt-dlp/wiki/EJS

(Note that Bellard's QuickJS is already a supported option.)

  • Not likely:

    > It only supports a subset of Javascript close to ES5 [...]

    I have not read the code of the solver, but solving YouTube's JS challenge is so demanding that the team behind yt-dlp ditched their JS emulator written in Python.

  • There's no reason it has to be lightweight, what it has to do is solve Youtube challenges without workarounds due to limited Javascript syntax.

I'm not an embedded systems guy (besides using esp32 boards) so this might be a dumb question but does something like this open up the possibility of programming an esp32/arduino board with Javascript, like Micro/Circuit Python?

  • That's been possible with Moddable/Kinoma's XS engine, which is standards compliant with ES6 and beyond.

    <https://www.moddable.com/faq#comparison>

    If you take a look at the MicroQuickJS README, you can see that it's not a full implementation of even ES5, and it's incompatible in several ways.

    Just being able to run JS also isn't going to automatically give you any bindings for the environment.

  • Sort of related: About ten years ago there was a device called the Tessel by Technical Machine which you programmed with Javascript, npm, the whole nine yards. It was pretty clever - the javascript got transpiled to Lua VM bytecode and ran in the Lua VM on the device (a Cortex M3 I believe). I recently had Claude rewrite their old Node 0.8 CLI tools in Rust because I wasn't inclined to do the javascript archeology needed to get the old tools up and running. Of course then I put the Tessel back in its drawer, but fun nonetheless.

Timing really is everything for making the frontpage, I posted this last night and it got no traction.

  • Some other guy tried it as well after you, also no luck.

    One strategy is to wait for US to wake up, then post, during their morning.

    Other strategy is to post the same thing periodically until there is response.

> It compiles and runs Javascript programs with as low as 10 kB of RAM.

Just in time for RAM to become super expensive. How easy would it be to shove this into Chromium and Electron?

  • Hard because of web compatibility.

    The good news is that it would probably not matter much for chromium's memory footprint anyway...

    • This makes me wonder, is there analysis of the syntax and if so can't it pick the lightest implementation? I see how light dillo is on the same page as chrome and I don't know why a web browser of the caliber of chrome does so much worse than a browser worked by a handful of people.

When reading through the projects list of JS restrictions for "stricter" mode, I was expecting to see that it would limit many different JS concepts. But in fact none of the things which are impossible in this subset are things I would do in the course of normal programming anyway. I think all of the JS code I've written over the past few years would work out of the box here.

  • I was surprised by this one that only showed up lower in the document:

    - Date: only Date.now() is supported. [0]

    I certainly understand not shipping the js date library especially in an embedded environment both for code-size, and practicality reasons (it's not a great date library), but that would be an issue in many projects (even if you don't use it, libraries yo use almost certainly do.

    https://github.com/bellard/mquickjs/blob/main/README.md#:~:t...

    • Good catch. I didn't realize that there was a longer list of restrictions below the section called "Stricter mode", and it seems like a lot of String functions I use are missing too.

      1 reply →

Fabrice Bellard is widely considered one of the most productive and versatile programmers alive:

- FFmpeg: https://bellard.org

- QEMU: https://bellard.org/qemu/

- JSLinux: https://bellard.org/jslinux/

- TCC: https://bellard.org/tcc/

- QuickJS: https://bellard.org/quickjs/

Legendary.

  • For all the praise he gets here, few seem interested in his methods: writing complete programs, based on robust computer science, with minimal dependencies and tooling.

    • When I first read the source for his original QuickJS implementation I was amazed to discover he created the entirety of JavaScript in a single xxx thousand line C file (more or less).

      That was a sort of defining moment in my personal coding; a lot of my websites and apps are now single file source wherever possible/practical.

      17 replies →

    • This is like Feynman's method for solving hard scientific problems: write down the question, think very hard, write down the answer.

      It doesn't necessarily translate to people who are less brilliant.

      1 reply →

    • I agree: he loves to "roll your own" a lot. Re: minimal dependencies - the codebase has a software FP implementation including printing and parsing, and some home-rolled math routines for trigonometric and other transcendental functions.

      Honestly, it's a reminder that, for the time it takes, it's incredibly fun to build from scratch and understand through-and-through your own system.

      Although you have to take detours from, say, writing a bytecode VM, to writing FP printing and parsing routines...

    • Because he choose the hardest path. Difficult problems, no shortcuts, ambitious, taking time to complete. Our environment in general is the opposite of that.

      1 reply →

    • He's one of my programming heroes but that's based purely on the sheer volume of high quality output he has.

      Can you elaborate a little about the methods you mention and how you analysed them?

    • > few seem interested in his methods:

      You are absolutely wrong here. Most of us wish that somebody would get him to sit for an in-depth interview and/or get him to write a book on his thinking, problem-solving approach, advice etc. i.e. "we want to pick his brain".

      But he is not interested and seems to live on a different plane :-(

  • Don't forget his LZEXE from the good old DOS days which was an excellent piece of work at the time.

    • I remember LZEXE from those olden days. When I discovered the author of FFmpeg and QEMU also created LZEXE, I was so impressed. I've been using his software for my entire computing career.

      It's similar to the respect I have for the work of Anders Hejlsberg, who created Turbo Pascal, with which I learned to program; and also C# and TypeScript.

    • Self-decompressing executables felt like magic to me at the time. Fantastic work, overall.

  • Always interesting when people as talented as Bellard manage to (apparently) never write a "full-on" GUI-fronted application, or more specifically, a program that sits between a user with constantly shifting goals and workflows and a "core" that can get the job done.

    I would not want to dismiss or diminish by any amount the incredible work he has done. It's just interesting to me that the problems he appears to pick generally take the form of "user sets up the parameters, the program runs to completion".

    • Reading some of these comments, it's clear very few in here have ever written a productive customer facing full stack app "javascript is really good for a single file app!!!" ok, maybe if you're rendering static HTML... -> these are not serious people

  • Whenever someone says there's no such thing as a 10x programmer, I point them to Fabrice and they usually change their mind.

    • People only deny the existence of such people based on their own ego, believing that no one could possibly be worth 10x more or produce 10x more than they can. Those who have seen those people know full well these people exist.

      It's kind of crazy it ever became some accepted world view, given how every field has a 10xer that is rather famous for it, whether it be someone who dominates in sport, an academic like Paul Erdős or Euler, a programmer like Fabrice or Linus Torvalds, a leader like Napoleon , or any number of famous inventors throughout history.

  • Don't forget his LLM based text compression software that won awards.

    Guy is a genius. I hope he tries Rust someday

    • Fabrice, if you're reading this, please consider replacing Rust instead with your own memory safe language.

      The design intent of Rust is a powerful idea, and Rust is the best of its class, but the language itself is under-specified[1] which prevents basic, provably-correct optimizations[0]. At a technical level, Rust could be amended to address these problems, but at a social level, there are now too many people who can block the change, and there's a growing body of backwards compatibility to preserve. This leads reasonable people to give up on Rust and use something else[0], which compounds situations like [2] where projects that need it drop it because it's hard to find people to work on it.

      Having written low-level high-performance programs, Fabrice Bellard has the experience to write a memory safe language that allows hardware control. And he has the faculties to assess design changes without tying them up in committee. I covet his attentions in this space.

      [0]: https://databento.com/blog/why-we-didnt-rewrite-our-feed-han...

      [1]: https://blog.polybdenum.com/2024/06/07/the-inconceivable-typ...

      [2]: https://daniel.haxx.se/blog/2024/12/21/dropping-hyper/

      4 replies →

  • At this point I'm convinced that they're not a 'real person' and the 'Fabrice' is an operational code name for a very mature hacker collective.

    Real people have to sleep at some point!

  • Wikipedia doesn't list any honours awarded by the French Government. Nor do I see anything from ACM. Definitely overdue some official recognition.

  • Funny how people know Fabrice for all the software stuff but none of the hardware antics:

    played with implementing analog modem DSP in software in 1999 (linmodem is ~50-80% there, sadly never finished)

    probably leading to

    played with implementing SDR (again DSP) using VGA output to transmit DVB-T/NTSC/PAL in 2005

    probably leading to

    Amarisoft SDR 5G base station, commercial product started in 2012 - his current job https://www.amarisoft.com/company/about-us

  • For all the praise he's receiving, I think his web design skills have gone overlooked. bellard.org is fast, responsive and presents information clearly. Actually I think the fancier the website, the shittier the software. Examples: Tarsnap - minimal website, brilliant software. Discord - Whitespacey, animation-heavy abomination of a website. Software: hundreds of MB of JS slop, government wiretap+botnet for degenerates.

    The math checks out.

I easily managed to build quickJS to WebAssembly for running in https://exaequOS.com . So I need to do the same for MicroQuickJS !

  • I'm curious what practical purpose you could have for running a js execution engine in an environment that already contains a (substantially faster) js execution engine? Is it just for the joy of doing it (if so good for you, absolutely nothing wrong with that).

    • WebAssembly also runs in places other than the web, where there isn't a JavaScript interpreter at hand. It'd be nice to have a fast JavaScript engine that integrates inside the WebAssembly sandbox, and can call and be called by other languages targeting WebAssembly.

      That way, programs that embed WebAssembly in order to be scriptable can let people use their choice of languages, including JavaScript.

    • It allows, for example, to create bindings as I did for raylib graphics library. exaequOS can run any program that can be built to WebAssembly It will soon support WASI p1 and p2. So many programming languages will be possible for creating programs targeting exaequOS

      3 replies →

If there were a software engineering hall of fame, I nominate Fabrice.

>> Arrays cannot have holes. Writing an element after the end is not allowed:

    a = []
    a[0] = 1; // OK to extend the array length
    a[10] = 2; // TypeError

If you need an array like object with holes, use a normal object instead

Guess I'm a bit fuzzy on this, I wouldn't use numeric keys to populate a "sparse array", but why would it be a problem to just treat it as an iterable with missing values undefined? Something to do with how memory is being reserved in C...? If someone jumps from defining arr[0] to arr[3] why not just reserve 1 and 2 and inform that there's a memory penalty (ie that you don't get the benefit of sparseness)?

I wonder if AI is so good why dont we have this kind of software released by people here who yap about it.

On a phone at the moment so I can't try it out, but in regards to this "stricter mode" it says global variables must be declared with var. I can't tell if that means that's just the only way to declare a global or if not declaring var makes it scoped in this mode. Based on not finding anything skimming through the examples, I assume the former?

  • I'm guessing the use of undeclared variables result in an error, instead of implicitly creating a global variable.

  • it also talks about the global object not being a place to add properties. So how you might do `window.foo = ...` or `globalThis.foo = ...` to make something from the local context into a global object. in this dialect I guess you would have to reserve any global objects you wanted to set with a `var` and then set them by reference eg

        // global. initialized by SomeConstructor
        var fooInstance
    
        class SomeConstructor {
           constructor(...) {
              fooInstance = this;
           }
           static getInstance(...) {
              if (fooInstance != null) return fooInstance;
              return new SomeConstructor(...);
           }
        }

  • I think it means you can't assign to unbounded names, you must either declare with var for global, or let/const for local

People talk about how productive Fabrice Bellard is, but I don't think anyone appreciates just how productive he is.

Here's the commit history for this project

b700a4d (2025-12-22T1420) - Creates an empty project with an MIT license

295a36b (2025-12-22T1432) - Implements the JavaScript engine, the C API, the REPL, and all documentation

He went from zero to a complete JS implementation in just 12 minutes!

I couldn't do that even if you gave me twice as much time.

Okay, but seriously, this is super cool, and I continue to be amazed by Fabrice. I honestly do think it would be interesting to do an analysis of a day or week of Fabrice's commits to see if there's something about his approach that others can apply besides just being a hardworking genius.

  • It's funny how many people replying here just got whooshed. This comment is satire; they don't actually think Bellard wrote everything in 12 minutes.

  • Doesn't say much. Probably had it largely written down and put it together. I don't think it'd even be humanely possible to do that in 12 minutes.

  • That doesn't mean anything. I quite often start with writing a proof-of-concept, and only initialize the git repository when I'm confident the POC will actually lead to something useful. Common sense says that those files already existed at the time of the first commit.

Anyone know how this compares to Espruino? The target memory footprint is in the same range, at least. (I know very little about the embedded js space, I just use shellyplugs and have them programmed to talk to BLE lightswitches using some really basic Espruino Javascript.)

I wish for this new year we reboot the Web with a super light standard and accompanying ecosystem with

    - A small and efficient JS subset, HTML, CSS
    - A family of very simple browsers that do just that
    - A new Web that adheres to the above

That would make my year.

  • This would never happen because there's zero incentive to do this.

    Browsers are complex because they solve a complex problem: running arbitrary applications in a secure manner across a wide range of platforms. So any "simple" browser you can come up with just won't work in the real world (yes, that means being compatible with websites that normal people use).

    • > that means being compatible with websites that normal people use

      No, new adhering websites would emerge and word of mouth would do the rest : normal people would see this fast nerd-web and want rid of their bloated day-to-day monster of a web life.

      One can still hope..

      5 replies →

    • I have to disagree, AMP showed that even Google had an internal conflict with the results of WHATWG.. It's naturally quite hard to reach agreements on a subset when many parties will prefer to go backwards to everything but there situations like the first iPhone, ebooks, TV browsing, etc, where normal people buy simpler things and groups that use the simpler subset achieve more in total than those stuck in the complex only format.

      (There are even a lot of developers who would inherently drop any feature usage as soon as you can get 10% of users to bring down their stats on caniuse.com to bellow ~90%.)

    • I think both wearables and AI assistant could be an incentive on one hand, also towards a more HATEOAS web. However, I guess we haven't really figured out how to replace ad revenue as the primary incentive to make things as complex as possible.

  • Lots of comments talking about how existing browsers can already do this, but the big benefit that current browsers can't give you is the sheer level of speed and efficiency that a highly restricted "lite web" browser could achieve, especially if the restrictions are made with efficiency in mind.

    The embedded use case is obvious, but it'd also be excellent for things like documentation — with such a browser you could probably have a dozen+ doc pages open with resource usage below that of a single regular browser tab. Perfect for things that you have sitting open for long periods of time.

  • While we're wishing, can we split CSS into two parts - styling and layout? Also, I'd like to fix the spelling on the "referer" header...

    • why does it need to be two languages? why not style.css and layout.css and you self-maintain the distinction

  • There could be a way: This HTML-lite spec would be subset of current standard so that if you open this HTML lite page in normal browser it would still work. but HTML-lite browser would only open HTML-lite sites, apart from tech itch it could be used in someplace where not full browser is needed, especially if you are control content generation. - TV screens UI - some game engines embed chrome embed thing ( steam store page kind) - some electron apps / lighter cross platform engine - less sucky QML - i think weechat or sth has own xml bashed app froamework thing (so could be useful to people wanting to build everything app app platform - much richer markdown format ?

  • Years ago I wrote a tiny xhtml-basic browser for a job. It was great. Some of my best work. But then the iPhone came out and xhtml-basic died practically overnight.

  • Do it, man. Call it "MicroWeb" or whatever. Write an agent, make it "viewable with regular browsers". I think this could be cool.

  • I would actually merge html and js in a single language and bring the layout part of css too (something like having grid and flexbox be elements themselves instead of display styles, more typst kind of showed this is possible in a nice way) and keep css only for the styling part.

    Or maybe just make it all a single lispy language

  • Not likely to happen. There is geminiprotocol with gemtext though for those of us that are fine with that level of simplicity.

    Work towards an eventual feature freeze and final standardisation of the web would be fantastic though, and a huge benefit to pretty much everyone other than maybe the Chrome developers.

  • I can't think of an instance of the web contracting like that. Maybe when Apple decided not to support Adobe Flash.

    • In the earlier days of the web, there were a lot more plugins you'd install to get around on most websites: not just Flash, but things like PDF viewers, Real Video, etc. You'd regularly have to install new codecs, etc. To say nothing of the days when there were some sites you'd have to use a different browser for. A movement towards more of a standards-driven web (in the sense of de facto, not academic, standards) is what made most of this possible.

  • I think there needs to be a split between the web browser as a document renderer and link follower, and the web browser as a portable target for GUI applications. But frankly my biggest gripe is that you need HTML, JS, and CSS. Three distinct languages that are extremely dissimilar in syntax and semantics that you need all three of (or some bastard cross compiler for your JSX to convert from one format to them). Just make a decent scripting language and interface for the browser and you don't need that nonsense.

    I understand this has been tried before (flash, silverlight, etc). They weren't bad ideas, they were killed because of companies that were threatened by the browser as a standard target for applications.

    • I think this is the ideal direction mainly because a lot of the webs current tech problems stem from websites that don't need app-level features using them. I was in web dev at the advent of SPA-style navigation and understand why everyone switched to it, but at the same time I feel like it's the source of many if not most bugs an performance issues that frustrate the average user.

    • I agree. Something componenty like Flash, yes. But it'd be easier to subset what already exists..

  • You can already create websites to these standards. Then truncate large parts of webkit and create a new browser. Or base it on Servo.

  • I mean, you can do all that now, so that's not the problem. The problem would be convincing millions of people to switch, when 99.99999% of them couldn't care less.

    • My idea is to use Markdown over HTTP(S). It's relatively easy to implement Markdown renderer, compared to HTML renderer. It's possible to browse that kind of website with HTML browser with very simple wrapper either on client or server side, so it's backwards compatible. It's rich enough for a lot of websites with actually useful content.

      Now I know that Markdown generally can include HTML tags, so probably it should be somewhat restricted.

      It could allow to implement second web in a compatible way with simple browsers.

      3 replies →

    • A few too many 9s there I think. You're estimating that only 1 person in every 10 million could care less. So less than 50 such people in the USA for example

    • Maybe you dont need a big enough % to change but a sufficient absolute number, which given internet size might happen with the right 0.00001%

    • Oh they would care if one shows them much snappier versions of services they use. They just don't know better.

  • And if you find you need more features than that - just build an app, don't make the web browser into some overly bloated app!

    • But most "apps" are just webviews running overcomplicated websites in them, many of which are using all the crazy features that the GP post wants to strip out.

Love it! Needing only 10K of RAM, it looks like a much better solution to CircuitPython (can squeeze into 32K).

this would be a killer replacement for micro/circuitpython for embedded devices, assuming there's an elegant TS->MQJS transpile

  • It’s not even the languages or runtimes that inhibit embedded adoption but the software to hardware tooling. Loader scripts, HAL/LL/CMSIS, flashing, etc. They all suck.

  • It looks like if you write the acceptable MQJS subset of JS+types, then run your code through a checker+stripper that doesn't try to inject implementations of TS's enums and such it should just work?

  • I don't think you can transpile arbitrary TS in mqjs's JS subset. Maybe you can lint your code in such a way that certain forbidden constructs fail the lint step, but I don't think you can do anything to avoid runtime errors (i.e. writing to an array out of its bonds).

I find frustrating that imagination of very smart, talented and capable people is captured by JavaScript language, surely they could have done better.