Open-source project
IppClub/YueScript avatar
IppClub/YueScript

YueScript is a modernised MoonScript that still compiles to Lua

A delightful language that compiles to Lua

618 stars45 forksLuaMIT

At a glance

What is it?
YueScript is a C++17 compiler for a MoonScript derived language aimed at Lua development, kept in step with the original where possible and extended with macros, an existential operator, a pipe operator and JavaScript style exports. It ships both as a Lua module and as a command line tool, and it is developed alongside the Dora SSR game engine.
Who is it for?
Adopt YueScript if you want MoonScript style syntax with a maintained compiler, you need macros or the pipe operator that the original does not have, and your Lua code is allowed to be compiled ahead of time. Do not adopt it if you need the exact MoonScript 0.5.0 semantics, if your toolchain cannot run C++17, or if you need the lpeg based parser that YueScript has deliberately replaced.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly Lua, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A fork of MoonScript 0.5.0, kept deliberately compatible

YueScript is a language that compiles to Lua, and its lineage is stated in the first line of the description. It is derived from MoonScript 0.5.0 and continues to adopt new features to stay up to date. The relationship to the original is a deliberate, bounded one rather than a clean sheet.

The reason the fork exists is also stated. MoonScript has been used to build real world projects such as Lapis, itch.io and streak.club, and MoonScript itself was influenced by languages such as CoffeeScript. The problem was maintenance: as the original implementation became harder to evolve without risking compatibility, YueScript was created as a modernized code base for pushing the language forward.

That framing sets the expectation. YueScript is not trying to be a different language with a similar feel, it is the same language with the implementation replaced and the feature set extended. The README says it supports most MoonScript features and generates Lua code in a style compatible with the original compiler, which matters if you are diffing generated output against what MoonScript produced.

The project is MIT licensed, the primary language is recorded as Lua, the default branch is main, and the homepage is yuescript.org with a documentation site, an online playground at yuescript.org/try and a Discord community. The release history shows v0.34.1, v0.34.2 and v0.34.3 in July, July and September 2026, and the last push was on 2026-10-11.

One small cultural detail that says something about the project: the name is Yue, the Chinese word for moon, pronounced jyɛ, and the mascot is Xiaoyu.

The parser was replaced, and lpeg went with it

The single most consequential implementation decision is in the features list, and it is easy to skim past.

YueScript is based on a modified parserlib with performance enhancements, and lpeg is no longer required. The original MoonScript implementation was built around lpeg, the Lua PEG parser library. Removing it means the compiler no longer needs a Lua PEG library present on the host system, which removes a class of install failure and a class of version mismatch.

The rest of the implementation choices are equally pragmatic. The compiler is written in C++17, so you need a modern toolchain, and the language of the compiler itself is not Lua even though the primary language field says Lua, because the repository's own code and its Lua test fixtures both live there.

The generated output has one property that matters more than it sounds: it preserves source line numbers in the generated Lua to improve debugging. When a transpiled Lua script fails, the line number in the error points back at the YueScript source rather than at an arbitrary line in the generated file. For a language whose main selling point is that it produces Lua you can still debug, that is the difference between a tool you trust in production and one you only use for quick scripts.

The generated code is also in a style compatible with the original compiler, which keeps the output readable for anyone who has to look at it, and keeps diffs between the two compilers meaningful.

Two ways to consume it: a Lua module and a command line tool

The project ships in two forms, and the choice between them is a real decision rather than a packaging detail.

The Lua module is built as a shared object with make, and the Lua and library paths are passed in:

sh
> make shared LUAI=/usr/local/include/lua LUAL=/usr/local/lib/lua

The resulting binary is in bin/shared/yue.so, and the alternative route is LuaRocks:

sh
> luarocks install yuescript

Once installed, you require it from Lua. The short form compiles a file, and the long form gives you the compiler API directly:

lua
require("yue")("main") -- require `main.yue`

local yue = require("yue")
local codes, err, globals = yue.to_lua([[
f = -> print "hello world"
f!
]],{
  implicit_return_root = true,
  reserve_line_number = true,
  lint_global = true
})

The to_lua call returns three values, the generated code, an error, and the globals. The options map is where the compiler behaviour is set, and the three shown here are worth understanding. implicit_return_root makes the last expression of a block the returned value, which is the MoonScript habit of returning everything implicitly. reserve_line_number keeps the line correspondence between source and output. lint_global asks the compiler to report the globals it finds, which is a way of catching an accidental missing local before it becomes a runtime bug.

The command line tool is built from a clone of the repository with make install, and the Makefile has switches for the two features you might want to leave out:

sh
> make install NO_MACRO=true

and:

sh
> make install NO_LUA=true

NO_MACRO builds the tool without the macro feature, and NO_LUA builds it without the built-in Lua binary, which is what you want when the tool is going to shell out to a Lua interpreter you provide. The tool's own help output shows it accepts files and directories, an -e flag for code or a file, and a -w flag for watch mode.

The extensions: macros, existential operator, pipes and exports

The features list names the additions over MoonScript, and they are the reason to use YueScript rather than the original.

Macros are the substantial one. A macro system is a metaprogramming facility, and in a compiled language it means the compiler can rewrite your source before it becomes Lua, so a macro can generate whole functions or rewrite repeated syntax. The Makefile's NO_MACRO switch exists because the macro feature is optional at build time, which tells you it is a substantial subsystem rather than a syntax sugar.

The existential operator is the Lua-style nil check. Instead of writing a guard and then dereferencing, the operator asks whether a value exists in one expression, which removes a lot of defensive boilerplate from code that is dealing with optional tables.

The pipe operator changes how a value flows through a call. Instead of nesting a function inside another function, the value is passed forward, which is the same idea that made pipes popular elsewhere, and it reads left to right in a way Lua's nested calls do not.

The JavaScript-like export syntax is about module boundaries, giving a clearer way to say what a file provides to the rest of the program.

The README is careful to frame all of this as additive. It says YueScript supports most MoonScript features and adds features like these, and points to CHANGELOG.md for the details, which is the file to read if you are porting a codebase and need to know exactly which construct changed behaviour.

There is also an online playground at yuescript.org/try, which is the fastest way to see how a given MoonScript idiom translates before you install anything.

Dora SSR is where the language is being tested

The About Dora SSR section is the most informative paragraph in the README for anyone deciding whether to depend on this project.

YueScript is being developed and maintained alongside the open source game engine Dora SSR, also from IppClub. It has been used to create engine tools, game demos and prototypes, validating its capabilities in real world scenarios while enhancing the Dora SSR development experience.

That is a real usage, and it is the kind of usage that exposes a language's rough edges quickly. A game engine needs tool scripts, command line utilities and build helpers, which is exactly the kind of code that is short, repetitive and benefits from a concise syntax. A game engine also needs the compiler to be reliable, because a broken build script stops the whole team rather than one service.

It also explains the shape of the project. YueScript is developed and maintained alongside Dora SSR rather than as a standalone product with its own release plan, and the repository layout reflects a language that has to support a real toolchain: a makefile, a CMakeLists.txt, a rockspec named yuescript-dev-1.rockspec for the LuaRocks path, a docker/ directory, a wasm/ directory, a win-build/ directory for Windows builds, a tup/ directory as an alternative build system, a spec/ directory for the test suite, a src/ directory for the compiler sources and a doc/ directory holding the documentation site.

The repository's own topic list names cpp, lua, moonscript, transpiler and yuescript, which is an accurate summary: it is a C++ compiler for a MoonScript dialect with a Lua ecosystem behind it.

What to check before you commit to it

There are three decisions worth making deliberately.

The first is the compatibility question. YueScript is derived from MoonScript 0.5.0, so if your existing code is MoonScript, the safest assumption is that most of it compiles, and the places to look are the extensions, since macros, the existential operator and the pipe operator are YueScript additions that MoonScript does not have. If your code is plain Lua, the transpilation is a rewrite of your syntax, and the line number preservation is what keeps your debugger usable afterwards.

The second is how you will invoke the compiler. The Lua module suits applications that compile code at runtime, for example a plugin host or a build system that wants to evaluate a user script, and the command line tool suits a build pipeline that compiles files ahead of time. The tool accepts files and directories, an -e flag for inline code and a -w watch mode, and the make install flags let you remove the macro feature or the bundled Lua binary depending on what your pipeline already provides.

The third is the toolchain. C++17 is required, and if you are building the compiler yourself rather than taking the LuaRocks package, that is a real prerequisite rather than a formality.

The practical constraint that remains is the boundary of the language. YueScript compiles to Lua, so it inherits Lua's runtime model, its single threaded execution unless you use libraries for concurrency, and its memory behaviour. If your problem is that Lua itself is too slow, a compiler that emits Lua does not solve it.

Editorial conclusion

Adopt YueScript if you want MoonScript style syntax with a maintained compiler, you need macros or the pipe operator that the original does not have, and your Lua code is allowed to be compiled ahead of time. Do not adopt it if you need the exact MoonScript 0.5.0 semantics, if your toolchain cannot run C++17, or if you need the lpeg based parser that YueScript has deliberately replaced. Before you start, check the CHANGELOG.md for the feature set your project depends on, and decide between the Lua module and the command line tool, since the macro feature can be compiled out with NO_MACRO=true.

Frequently asked questions

How do I install YueScript?

As a Lua module you can install it with LuaRocks using `luarocks install yuescript`, or build the shared object with `make shared LUAI=/usr/local/include/lua LUAL=/usr/local/lib/lua` and take yue.so from bin/shared. As a command line tool, clone the repository and run `make install`.

What is the difference between YueScript and MoonScript?

YueScript is derived from MoonScript 0.5.0 and supports most of its features while generating Lua in a compatible style, but it adds features such as macros, an existential operator, a pipe operator and JavaScript-like export syntax. It also replaces the lpeg based parser with a modified parserlib, written in C++17, and preserves source line numbers in the generated Lua.

Can I build YueScript without the macro feature?

Yes. The Makefile provides a NO_MACRO switch, so `make install NO_MACRO=true` builds the tool without macros, and `make install NO_LUA=true` builds it without the built-in Lua binary for use with your own interpreter.

How is YueScript maintained and who uses it?

The README says YueScript is developed and maintained alongside the open source game engine Dora SSR, and it has been used to create engine tools, game demos and prototypes. Releases v0.34.1, v0.34.2 and v0.34.3 were published in July and September 2026.

Official sources

  1. IppClub/YueScript on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ippclub-yuescript.svg)](https://hysenlabs.com/projects/ippclub-yuescript)

Was this useful?