Welcome to our website.

How Lua’s require Finds, Loads, and Caches Modules

A quick five-minute look at how require works in Lua

In Lua, require looks simple from the outside: pass in a module name, get the module back. Under the hood, though, it follows a clear loading and caching process. Understanding that process helps explain why the same file is usually executed only once, and how to force it to run again when needed.

Where does require look for files?

When require loads a module, it uses package.path to build the possible file paths. Lua takes the module name passed to require, substitutes it into the ? placeholders in package.path, and checks each candidate path in order. If a matching file exists, Lua loads it through a loader.

print(package.path)
--Windows测试环境
--;.??.lua;C:\Program Files (x86)\Lua\5.1\lua\?.lua;C:\Program Files (x86)\Lua\5.1\lua\?\init.lua;C:\Program Files (x86)\Lua\5.1\?.lua;C:\Program Files (x86)\Lua\5.1\?\init.lua;C:\Program Files (x86)\Lua\5.1\lua\?.luac

Each ? in the path string is replaced with the requested module name. The semicolons separate multiple lookup locations, and their order determines the search priority.

Where are loaded modules stored?

Modules loaded through require are stored in package.loaded. You can inspect it directly:

require "main"

for k, v in pairs(package.loaded) do
    print("loaded:" .. k .. "")
end

-- loaded:string
-- loaded:debug
-- loaded:package
-- loaded:_G
-- loaded:io
-- loaded:os
-- loaded:table
-- loaded:math
-- loaded:coroutine
-- loaded:main 这边出现了main文件名

After require "main" runs, main appears in package.loaded, alongside Lua’s already-loaded standard modules.

Why the same module is not loaded twice

Create a main.lua file like this:

main = {}

print("load file main")

return main
--缺省情况下默认return true

Then require it twice:

local ma1 = require "main"
print(ma1)

local ma2 = require "main"
print(ma2)

-- load file main
-- table: 00EA98E8
-- table: 00EA98E8

The output shows that "load file main" is printed only once. The two returned values point to the same table address, which means the second require did not execute main.lua again. Instead, Lua returned the cached value from package.loaded.

This is the default behavior: once a module has been required successfully, Lua keeps its result and reuses it on later calls.

Making a required module execute more than once

If a module does not explicitly return a value, Lua treats it as if it returned true, and the module is still cached. That means the file’s top-level code only runs once.

One way to make require execute the file again is to explicitly return false. In that case, the cached value does not behave like a normal loaded module result, so each require can trigger the loading process again.

main = {}

print("load file main")

return false

在调用的文件中:

require "main"
require "main"

输出:

load file main
load file main

Another way is to manually remove the module from package.loaded. If package.loaded.main is set to nil, the next require "main" will no longer find the cached module, so Lua will search for and load it again.

main = {}

print("load file main")

return main

在调用的文件中:

require "main"
package.loaded.main = nil
require "main"

输出:

load file main
load file main

So the key point is that require is not just a file loader. It is also a module cache manager. It searches according to package.path, stores loaded results in package.loaded, and skips repeated execution unless the cached entry is missing or the module is made to avoid normal caching behavior.

Related Posts