xllify

Why xllify uses Lua as its scripting language

Lua is tiny, fast, and embeddable by design. It sounds simple, but that simplicity is exactly what makes it a good fit for Excel add-ins.

When you embed a scripting language into something, the choice matters more than it first appears. It shapes the runtime, the safety guarantees, and what writing functions actually feels like.

The obvious candidates were Python, JavaScript, and Lua.

Python brings too much baggage. You can’t just embed it cleanly - users need a matching installation, and distributing a self-contained XLL with Python inside produces bloated binaries and a fragile setup story. The GIL also makes multi-threaded recalculation awkward.

JavaScript has the same problem from the other direction. Office.js runs out-of-process with a communication bridge, so every function call has noticeable latency.

Lua is tiny, fast to embed, clean C interop, intentionally minimal standard library. It has been around for over thirty years, battle-tested in games, networking equipment, and embedded systems. The VM is register-based and performs well where it matters most for spreadsheet functions: table operations, string handling, and common numeric patterns. The syntax is approachable if you’ve ever written VBA or Python. See the Lua cheat sheet for a quick overview of the key differences.

The sandbox story is straightforward. Lua’s VM has no os, io, or require unless you explicitly provide them. xllify doesn’t, so your functions run sandboxed by default rather than by bolt-on restriction. The bytecode compiler produces compact output, which is what makes it possible to target both the XLL and Office Add-in runtimes from the same source.

Lua is a great target for AI code generation

Lua has a small, well-defined surface area, and that turns out to matter a lot for AI code generation. Models like Claude can target it reliably - the language is constrained enough that generated code is almost always syntactically correct and idiomatic. This is what makes the xllify Assistant work well: describe a function in plain English and get something that actually runs. With Python or JavaScript there are ten ways to do everything, which makes reliable generation much harder.

C interop and ecosystem

Lua’s C API is intentionally minimal - registering a native function is a handful of lines. xllify uses this to implement stdlib functions in C, registered into the VM at startup. Only what xllify explicitly registers is available to scripts. require is not exposed, so user code has no path to libraries outside the sandbox.

But what about pandas, numpy or some other Python package?

They’re great, but possibly bulldozers to plant some daffodils. If you’re doing serious data science work they’re the right tool. But for most Excel custom functions - lookups, string manipulation, date arithmetic, domain-specific calculations: do you actually need them? The honest answer is usually no, it might just be habit. What you need is a bit of logic and some decent standard library coverage, not a full scientific computing stack that weighs hundreds of megabytes and requires a managed Python environment to run.

The xllify standard library is growing. Common operations are already covered, and more are being added. For the cases where you genuinely need something heavier, that’s a reasonable conversation - but it shouldn’t be the default starting point.

Lua has been around for thirty years. It works and you’ve probably used it without knowing.

← All posts