{ title: “Creating a Lapis Application with MoonScript” }

Creating a Lapis Application with MoonScript

Creating a Basic Application

You can start a new MoonScript project in the current directory by running the following command:

$ lapis new

This provides us with a default Nginx configuration, nginx.conf, and a skeleton application, app.moon. The skeleton application looks like this:

-- app.moon
lapis = require "lapis"

class extends lapis.Application
  "/": =>
    "Welcome to Lapis #{require "lapis.version"}!"

This defines a regular Lua module that returns our application class. (Implicit return in MoonScript states that the last statement in a block of code is the return value.)

Don’t forget to compile the .moon files when changing and creating them. You can watch the current directory and compile automatically with moonc -w.

Try it out by starting the server:

lapis server

If you’ve compiled the .moon file then http://localhost:8080 will display the page.

Lapis Applications

When we refer to a Lapis application we are talking about a class that extends from lapis.Application. The properties of the application make up the routes the application can serve and the actions it will perform.

Here’s a slightly more complicated exmaple to give you a feel of what they look like:

lapis = require "lapis"

favorite_foods = {
  "pizza": "Wow pizza is the best! Definitely my favorite"
  "egg": "A classic breakfast, never leave home without"
  "ice cream": "Can't have a food list without a dessert"

class App extends lapis.Application
  [index: "/"]: =>
    -- Render HTML inline for simplicity
    @html ->
      h1 "My homepage"
      a href: @url_for("list_foods"), "Check out my favorite foods"

  [list_foods: "/foods"]: =>
    @html ->
      ul ->
        for food in pairs favorite_foods
          li ->
            a href: @url_for("food", name: food), food

  [food: "/food/:name"]: =>
    food_description = favorite_foods[]
    unless food_description
      return "Not found", status: 404

    @html ->
      h2 "My thoughts on this food"
      p food_description

You can learn about each of the components used in this example on the Requests and Actions guide.

MoonScript Tips

Lapis is a bi-language library. It works for either MoonScript or Lua. The rest of this page will have information specific to the MoonScript interface. It might be more helpful to check out the Requests and Actions guide first to learn more about the basics before reading this section.


The members of the application class make up the patterns that can be matched by incoming requests. This is referred to as the route and the action, where the route is the pattern and the action is the function that handles the matching route:

lapis = require "lapis"

class App extends lapis.Application
  "/hello": => "Hello World!"

In this example, the route "/hello" is matched to a function that returns "Hello World!"

The action is the function called in response to a route matching the path of a request. Actions are written with the fat arrow, =>, because they all recieve a first argument from Lapis. You might think that self is an instance of application. It’s actually an instance of Request, a class that’s used to represent the current request.

We can also access the instance of the application with @app. You should treat @app as read only because the instance is shared among many requests.

The members of the class that you want to be routes must start with "/", otherwise they are treated as regular methods of the application class.


As your application becomes more complex it helps to break it apart into multiple sub-applications. Lapis doesn’t place any rules on how you divide your application, instead it facilities the combination of applications.

@include(other_application, [opts])

Let’s say we’ve got a separate application for handling users:

-- applications/users.moon
lapis = require "lapis"

class UsersApplication extends lapis.Application
  [login: "/login"]: do_login!
  [logout: "/logout"]: do_logout!

We can include this application into our main one:

-- app.moon
lapis = require "lapis"

class extends lapis.Application
  @include "applications.users"

  [index: "/"]: =>
    @html ->
      a href: @url_for("login"), "Log in"

In this example applications/users.moon is a module that returns the sub-application. The include class method is used to load this application into our root one. include copies all the routes of the other application, leaving the original untouched.

Sub-applications are allowed to have before filters, and the before filters will only apply to all actions enclosed by the application.

A sub-application supports special path and name class values:

  • path – The patterns of the routes copied are prefixed with path
  • name – The names of all the routes copied are prefixed with name
class UsersApplication extends lapis.Application
  @path: "/users"
  @name: "user_"

  -- etc...

include takes an optional second argument, a table of options. The options can be used to provide or override the path and name values that might have been set in the application.

For example, we might prefix UsersApplication like so:

class extends lapis.Application
  @include "applications.users", path: "/users", name: "user_"

  "/": =>
    @url_for("user_login") -- returns "/users/login"

Class Methods


Returns the function of the action that has the name specified by action_name.