Fengari

🐺 φεγγάρι - Lua for the Browser

Github

What is it?

Fengari (Moon in greek) is the Lua VM written in JavaScript. It uses JavaScript's garbage collector so that interoperability with the DOM is non-leaky.

It comes with a simple module, that renders any interaction with JavaScript and the DOM transparent:

local js = require "js"
local window = js.global

window:alert("Hello from Fengari!")
Try it:
local js = require "js" local window = js.global window:alert("Hello from Fengari!")
local js = require "js"
local window = js.global
local document = window.document

print("Document's title: " .. document.title)
Try it:
local js = require "js" local window = js.global local document = window.document print("Document's title: " .. document.title)

Lua in the browser means you can use coroutines to write beautiful asynchronous code:

local js = require "js"
local window = js.global

local function sleep(delay)
    local co = assert(coroutine.running(), "Should be run in a coroutine")

    window:setTimeout(function()
        assert(coroutine.resume(co))
    end, delay*1000)

    coroutine.yield(co)
end

coroutine.wrap(function()
    print "Going to sleep now..."

    sleep(3)

    print "Sleep well?"
end)()
Try it:
local js = require "js" local window = js.global local function sleep(delay) local co = assert(coroutine.running(), "Should be run in a coroutine") window:setTimeout(function() assert(coroutine.resume(co)) end, delay*1000) coroutine.yield(co) end local print = _G.print coroutine.wrap(function() print "Going to sleep now..." sleep(3) print "Sleep well?" end)()

Test it out!

This REPL is itself written in Lua.

Getting started

The easiest way to get started with Fengari in the browser is to use fengari-web. This module will watch the DOM for any <script type="application/lua" src="..." async> and run them with Fengari.

  1. Build fengari-web:

    $ git clone https://github.com/fengari-lua/fengari-web.git
    $ cd fengari-web
    $ npm install
    $ npm run build
  2. Include it in your webpage:

    <script src="dist/fengari-web.js" type="text/javascript"></script>
  3. Now any script of type application/lua will be run by fengari:

    <script type="application/lua">
        print("hello world!")
    </script>
    
    <script src="/my-script.lua" type="application/lua" async></script>

Structure

Fengari is spread across several repositories:

  • fengari: the core, largely a port of the PUC-Rio C implementation of Lua
  • fengari-web: to use Fengari in the browser as easily as you might use JavaScript
  • fengari-interop: a lua library that makes interoperating with JavaScript objects simple, it is already included in fengari-web
  • fengari-node-cli: Lua CLI but running on top of Node.js