The _ENV Model in Lua 5.2+
Understand how _ENV replaced setfenv and enables environment control.
The _ENV Model in Lua 5.2+ is a free Lua Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, and your progress syncs across the web and the CoddyKit app. The Lua Academy course includes 4 lessons in total.
What Is _ENV?
In Lua 5.2+, every chunk has an implicit upvalue called _ENV. All global variable accesses are rewritten as field accesses on _ENV. So print(x) becomes _ENV.print(_ENV.x).
_ENV Replaces setfenv
In Lua 5.1, setfenv(fn, env) changed a function's global environment. In 5.2+, this is gone. Instead, set _ENV as a local to change the environment of a chunk or block.
Changing _ENV in a Chunk
Set _ENV at the top of a chunk to redirect all global accesses.
-- Everything in this chunk uses myEnv as globals
local _ENV = myEnv
print("hello") -- calls myEnv.print("hello")Local _ENV for a Block
Scope _ENV changes to a do...end block to limit the effect.
do
local _ENV = {print = print, x = 42}
print(x) -- 42 from local _ENV
end
print(x) -- original _ENV.x (global x)Using load with _ENV
load(chunk, chunkname, mode, env) executes a string as a chunk with a custom environment. This is the primary sandboxing mechanism in 5.2+.
local env = {print = print, math = math}
local fn, err = load("print(math.sqrt(16))", "sandbox", "t", env)
if fn then fn() end -- 4.0Reading the Current _ENV
The current chunk's globals are _ENV. To get a reference: local myEnv = _ENV.
Modifying _ENV at Runtime
Setting a global variable is _ENV.varName = value. Since _ENV is an upvalue, you can swap it for a different table at any point in the code.
Inheritance with __index
Give the sandbox environment a metatable with __index = _G to fall back to the real global table for functions you haven't explicitly blocked.
local sandboxEnv = setmetatable({}, {__index = _G})
-- then block dangerous ones:
sandboxEnv.os = nil
sandboxEnv.io = nil
sandboxEnv.load = nilDetecting _ENV Access Attempts
Replace dangerous globals with a sentinel that logs access attempts for security auditing.
sandboxEnv.os = setmetatable({}, {
__index = function(_, k)
ngx.log(ngx.WARN, "Blocked access: os." .. k)
return nil
end
})Compatibility Note
Libraries using Lua 5.1's setfenv/getfenv need to be rewritten for 5.2+. Some use a compatibility shim in init code.
Practical Impact
The _ENV model makes sandboxing cleaner and more consistent. There is one clear mechanism for environments rather than two (setfenv for functions vs globals for top-level).
_ENV Question
How does Lua 5.2+ rewrite the global access print(x)?
Recap: _ENV Model
Lua 5.2+ makes all global access go through the _ENV upvalue. Use load(code, name, "t", env) to execute code in a custom environment. This is the standard sandboxing mechanism replacing setfenv.
Learn Lua with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 40
- Lessons
- 159
Frequently Asked Questions
Is the “The _ENV Model in Lua 5.2+” lesson free?
Yes — any 3 lessons of the Lua Academy learning path, including “The _ENV Model in Lua 5.2+”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Lua Academy course includes 4 lessons in total.
What will I learn in “The _ENV Model in Lua 5.2+”?
Understand how _ENV replaced setfenv and enables environment control. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.
How long does the “The _ENV Model in Lua 5.2+” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The _ENV Model in Lua 5.2+
- Building a Restricted Sandbox
- Preventing Sandbox Escapes
- Resource Limits and Instrumentation