Wren: A classy little scripting language

2025-10-2216:2120064wren.io

Getting Started Contributing Blog Try it! Wren CLI Embedding Performance Q & A Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.…

Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.

System.print("Hello, world!")

class Wren {
  flyTo(city) {
    System.print("Flying to %(city)")
  }
}

var adjectives = Fiber.new {
  ["small", "clean", "fast"].each {|word| Fiber.yield(word) }
}

while (!adjectives.isDone) System.print(adjectives.call())
  • Wren is small. The VM implementation is under 4,000 semicolons. You can skim the whole thing in an afternoon. It’s small, but not dense. It is readable and lovingly-commented.

  • Wren is fast. A fast single-pass compiler to tight bytecode, and a compact object representation help Wren compete with other dynamic languages.

  • Wren is class-based. There are lots of scripting languages out there, but many have unusual or non-existent object models. Wren places classes front and center.

  • Wren is concurrent. Lightweight fibers are core to the execution model and let you organize your program into a flock of communicating coroutines.

  • Wren is a scripting language. Wren is intended for embedding in applications. It has no dependencies, a small standard library, and an easy-to-use C API. It compiles cleanly as C99, C++98 or anything later.

You can try it in your browser!
If you like the sound of this, let’s get started.
Excited? You’re also welcome to get involved!


Read the original article

Comments

  • By plainOldText 2025-10-2620:406 reply

    Reminder the creator of Wren wrote the awesome Crafting Interpreters book [0].

    [0] https://craftinginterpreters.com/

    • By thw_9a83c 2025-10-2621:452 reply

      It is an excellent book and one of the canonical texts on the subject. My only suggestion for the "Lox" language would be to include an implementation of arrays, and preferably also hash/dict arrays. Other than that, the book contains everything you need to know about implementing a programming language.

      • By smnplk 2025-10-2622:364 reply

        I wish he would have used C for everything. You need to buyin into Java's whole OOP thing, which I am not a fan of.

        • By SatvikBeri 2025-10-270:251 reply

          It's not too hard to adapt the first half of the book into whatever language you want. People have posted versions in dozens of languages: https://github.com/munificent/craftinginterpreters/wiki/Lox-...

          (There are fewer options for the second half, since you need more control over memory management.)

          • By Conscat 2025-10-274:322 reply

            It's hard to say what "that hard" should be considered, but the book's first half involves Java reflection, which isn't obvious code to port to different languages in my opinion.

            • By pansa2 2025-10-275:031 reply

              > the book's first half involves Java reflection

              Does it? I know it uses metaprogramming (a Java program that outputs another Java program), but that’s probably easier in other languages than in Java. In my Python implementation I was able to significantly simplify that part of the code by using `eval`.

              • By scuff3d 2025-10-2716:291 reply

                Yeah I don't recall reflection either.

                I do remember him using the visitor pattern to implement part of the parser I think. I thought that was kind of an odd choice, especially since it seemed like he was really just trying to avoid Java boilerplate.

                Regardless, the book is incredible, and the choice of Java to start with makes sense. Its probably going to be the most universally approachable for everyone, even if they aren't super familiar. C can be pretty overwhelming if you aren't familiar it.

                • By pansa2 2025-10-280:281 reply

                  > I do remember him using the visitor pattern to implement part of the parser I think. I thought that was kind of an odd choice, especially since it seemed like he was really just trying to avoid Java boilerplate.

                  It's used to allow writing a "resolver" and an "interpreter" that both know how to handle every type of node in the AST. It's almost a functional approach, and I actually think it might increase boilerplate because Java is more designed around the object-oriented approach of adding `resolve` and `interpret` methods directly to each node type.

                  The two approaches result in very different code organisation, though - maybe the visitor approach was easier to explain in prose.

                  • By scuff3d 2025-10-284:041 reply

                    It's been a while since I read it, but I remember him saying something about the more natural (my word not his) approach being a single data structure that you would pass through both components, but he didn't want to do that because Java doesnt really encourage that kind of design, and you have a bunch of boilerplate for each class. It just struck me as an odd choice since the book was more about compiler/interpreter fundamentals, and I feel like the visitor pattern is a bit in the weeds in terms of OOP design.

                    I wonder if he wrote today if he would have used a Record and done the more straightforward implementation.

                    • By nogridbag 2025-10-2818:351 reply

                      I went through the Crafting Interpreters book with modern Java. I posted this on reddit, but I basically used records and sealed interfaces. With modern Java there's no need for visitor pattern.

                          private void execute(Stmt statement) {
                              switch (statement) {
                                  case Stmt.Expression expression -> evaluate(expression.expr());
                                  case Stmt.Block block -> executeBlock(block.statements(),
                                     new Environment(environment));
                                  ...
                      
                          public sealed interface Expr permits
                              Expr.Assign,
                              Expr.Binary,
                              Expr.Call,
                              Expr.Function,
                              .... more exprs here

                      • By scuff3d 2025-10-2822:53

                        Interesting. Almost all my actual experience writing Java is in Java 8, so I'm not super familiar with the modern stuff (other then a few things like Records). I'll have to take a look.

                        Most of the people I know who write Java would have an aneurysm at seeing a switch statement.

                        To be clear, that's a critique of the Java mindset, not your code. Lol

            • By SatvikBeri 2025-10-2711:20

              It's been a few years now, but there's no real reason to port the Java code directly – you can just read what it's trying to do, and implement that using your language's idioms. I don't remember anything as complex as trying to port reflection.

        • By thw_9a83c 2025-10-2623:07

          I understand. I wasn't a Java person when I read that book, yet I still prefer Java over more esoteric options. If Golang is easier for you to understand (no OOP), then I can recommend this one:

          https://interpreterbook.com/

          BTW, I'm not the author of either of those books, but I have read both of them.

        • By nine_k 2025-10-2622:42

          Wren, the topic of the post, is positioned as a descendant of Smalltalk, the most OOP language of them all. The author clearly finds the OOP paradigm important.

        • By codr7 2025-10-277:38

          I recently did a dual implementation of a simple language in Java/C for educational purposes:

          https://github.com/codr7/shi

      • By x-yl 2025-10-289:01

        An optional challenge gives an implementation of arrays for jlox at least: https://github.com/munificent/craftinginterpreters/blob/4a84...

    • By mhaberl 2025-10-2621:11

      and he wrote Game Programming Patterns [0]

      [0] https://gameprogrammingpatterns.com/

    • By ronbenton 2025-10-2621:18

      Knowing this is the author makes me 1000% more interested in Wren. What a great book!

    • By l9o 2025-10-2621:001 reply

      This is awesome. Thank you for sharing. I have been working on a small interpreted language for shell scripts with lots of help from Claude Code. The main idea is to automatically generate the cli interface for the scripts based on function definitions. However, I'm far from a programming languages expert, so I've been a bit hesitant to share my work. Going to give this book a read this week to see how far I am. Thank you!

    • By pansa2 2025-10-271:02

      Yeah, my understanding is that the bytecode interpreter in the second half of the book is essentially a stripped-down version of the Wren virtual machine.

    • By alberth 2025-10-2621:45

      Is Bob still involved (in Wren)?

      I thought his focus was Dart these days given being employed by Google.

  • By apitman 2025-10-2619:502 reply

    I was working on a custom runtime for minimal wasm apps recently. I didn't want to have to write all apps in C or Rust, so I went looking for tiny scripting languages. Lua is pretty small, but I wasn't able to get it to compile to wasm IIRC due to POSIX dependencies. This turned out to be quite easy with Wren[0].

    [0]: https://github.com/wren-lang/wren/issues/1199

    • By MattJ100 2025-10-2620:512 reply

      That's unusual that you struggled to build Lua. Lua is primarily C89, and used on non-POSIX microcontrollers for example. There are some optional bits of the standard library you would have to leave out - module loading uses dlopen(). This is done simply by defining the right feature macros for your target environment: https://www.lua.org/source/5.4/luaconf.h.html

      You may also be interested in this project: https://github.com/fengari-lua/fengari

      • By nsagent 2025-10-2623:27

        I've used fengari and it's a great option for lua in the browser, but it is quite slow.

      • By JonChesterfield 2025-10-2720:45

        setjmp/longjmp are irritating to implement and used by the pcall machinery

    • By Imustaskforhelp 2025-10-2622:511 reply

      Wow, I really went into a rabbithole after opening up your hackernews profile seeing indiebits and remembering my time scouring your github awesome tunneling page and then I went to discourse forum and somehow found new resources about self hosting and saw yunohost and others as well all in matter of minutes.

      Thank you for your service in self-hosting. I had so much fun trying to break nats with awesome tunneling projects and I even created my own but it actually requires a custom patch of ssh with pinggy to work without nat (let me know if you are interested, as I had discovered this a year ago but I just am a little lazy haha)

      I have created only one issue on the awesome tunneling but let me tell you some of them don't work in nat's/broke

      https://freedomhascost.bearblog.dev/

      Just created the bearblog post, not sure why the name but just wanted to say thank you and wanted to share any knowledge I have in the process as well to strengthen the hacking/tinkering community. Thanks once again

      Also its just a bit of a coincidence that we are talking on a wren page as I was literally reading about wren once again and playing with it just yesterday and joined their discord server yesterday or day before that to tinker with it. Wren is really elegant and I feel like I want to write more software which integrates it instead of lua as a thought experiment as well and wasm seems a cool idea too in that regards.

      • By apitman 2025-10-2920:55

        Thank you for the kind words!

  • By gnabgib 2025-10-2216:25

    Popular in 2022 (301 points, 130 comments) https://news.ycombinator.com/item?id=32631553

    2020 (122 points, 54 comments) https://news.ycombinator.com/item?id=23660464

HackerNews