canaryThese pages document the canary: an unreleased build. What they describe may not be in the version you have, and may change before it is.The stable build
Try it in your browsercanary Source

Modules✎

What a script requires, where you declare it, and what each runtime resolves.

Pending review

A module is code in another file that this one uses. Roswaal writes the require for you — but only ever for a module you have declared, and each declaration writes exactly one, at the top of the generated file.

Tip

Nothing is required that the graph does not say. Every import in the generated file is one the panel or the canvas shows.

Declaring one

Modules live in the Variables panel, under their own heading. It is the same question the variables answer — what does this script have to hand — and a dependency belongs somewhere you can see it rather than somewhere you go looking.

Everything this script declares: its variables, its modules, its locals and its functions.

Hover a control or its row to light the other.

  • VariablesValues the whole script reads and writes. See Variables and locals.
  • ModulesWhat this script requires. Each one writes a single require at the top of the generated file, however many places read it — so four uses are four pills and one import.
  • LocalsValues that exist inside one block. See Variables and locals.
  • FunctionsEvery function this script declares. See Functions.
FieldWhat it is
NameThe local it binds to, and what the pill shows. Yours to choose — see below
ModuleWhat goes inside require(...), verbatim
MembersNames pulled off it into locals of their own, comma separated

Drag a module onto the canvas for a Get Module pill — one output, no header, exactly as a variable gives you a Get. Four of them still write one require, because the declaration is on the script rather than on any of the pills.

Require at Top declares one on the canvas instead, for when you would rather see it there. It takes the same specifier and hands back the same module.

What goes in the box

A specifier must start with a prefix. That is not a house style: an unprefixed path is an error in Luau itself, since the require rules were amended — require("Foo") used to resolve and now does not.

FormRobloxLuneWhat it reaches
./nameYesYesA sibling of this file
../nameYesYesUp one, then down
@self/nameYes—A child of this script
@game/Service/nameYes—Down from the DataModel root
@lune/fs—YesLune's standard library
@alias/nameNot yetYesAn alias from a `.luaurc`

Warning

Specifiers are checked against the graph's runtime: @lune/fs in a Roblox graph is an error. A .luaurc alias is a warning in Roblox, which does not resolve them yet — see Aliases and .luaurc.

Naming it yourself

The name is a choice, not a derivation. Two modules can genuinely want to be called util — ./combat/util and ./inventory/util — and only you can say which becomes combatUtil.

So a name you type is used exactly. It is never quietly turned into util2: two declarations wanting one name is an error naming both, because a file can bind it once and the fix is a rename that is yours to pick.

Members, and the Roblox datatypes in Lune

Members bind names from inside the module to locals of their own. It is Lune's own idiom, and it is what makes the Roblox datatypes work there.

luau
local roblox = require("@lune/roblox")
local Vector3 = roblox.Vector3
local CFrame = roblox.CFrame

With Vector3 bound, Vector3.new(1, 2, 3) means what it means in Roblox — so a graph moved between runtimes needs the declaration, not different nodes. Shadowing a name Luau provides is allowed here because it is the point; Roswaal warns, so that naming a module table is a decision rather than an accident.

Where the requires end up

At the top, below the GetService calls — where a hand-written Roblox file puts them, and in the order you declared them.

luau
local Players = game:GetService("Players")

local Combat = require("@game/ReplicatedStorage/Combat")
local config = require("./config")

Info

Deleting a module leaves the pills that read it in place, reporting an error — as deleting a variable does.

Not reviewed yet