diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
 
 `lua` uses [PVP Versioning][].
 
+## lua-2.3.1
+
+Released 2023-03-17.
+
+-   New module *Lua.Debug*: the module provides bindings to a
+    subset of functions of the Lua debug interface. Currently the
+    module only binds `lua_getupvalue` and `lua_setupvalue`.
+
 ## lua-2.3.0
 
 Released 2023-03-13.
diff --git a/lua.cabal b/lua.cabal
--- a/lua.cabal
+++ b/lua.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                lua
-version:             2.3.0
+version:             2.3.1
 synopsis:            Lua, an embeddable scripting language
 description:         This package provides bindings and types to bridge
                      Haskell and <https://www.lua.org/ Lua>.
@@ -115,6 +115,7 @@
                      , Lua.Auxiliary
                      , Lua.Call
                      , Lua.Constants
+                     , Lua.Debug
                      , Lua.Ersatz
                      , Lua.Ersatz.Auxiliary
                      , Lua.Ersatz.Functions
diff --git a/src/Lua.hs b/src/Lua.hs
--- a/src/Lua.hs
+++ b/src/Lua.hs
@@ -225,6 +225,10 @@
   , fromReference
   , toReference
 
+    -- * Debug interface
+  , lua_getupvalue
+  , lua_setupvalue
+
     -- * Ersatz functions
   , hsluaL_newstate
   , hsluaL_tolstring
@@ -267,6 +271,7 @@
 import Lua.Auxiliary
 import Lua.Call
 import Lua.Constants
+import Lua.Debug
 import Lua.Ersatz.Functions
 import Lua.Ersatz.Auxiliary
 import Lua.Lib
diff --git a/src/Lua/Debug.hs b/src/Lua/Debug.hs
new file mode 100644
--- /dev/null
+++ b/src/Lua/Debug.hs
@@ -0,0 +1,53 @@
+{-|
+Module      : Lua.Debug
+Copyright   : © 2023 Albert Krewinkel
+License     : MIT
+Maintainer  : Albert Krewinkel <tarleb@hslua.org>
+
+Haskell bindings to Lua's debug interface.
+-}
+module Lua.Debug
+  ( lua_getupvalue
+  , lua_setupvalue
+  )
+where
+
+import Foreign.C
+import Lua.Types as Lua
+
+-- | Gets information about the @n@-th upvalue of the closure at index
+-- @funcindex@. It pushes the upvalue\'s value onto the stack and
+-- returns its name. Returns @NULL@ (and pushes nothing) when the index
+-- @n@ is greater than the number of upvalues.
+--
+-- See
+-- <https://www.lua.org/manual/5.4/manual.html#pdf-debug.getupvalue debug.getupvalue>
+-- for more information about upvalues.
+--
+-- @[0, +(0|1), -]@
+--
+-- <https://www.lua.org/manual/5.4/manual.html#lua_getupvalue lua_getupvalue>.
+foreign import ccall unsafe "lua.h lua_getupvalue"
+  lua_getupvalue :: Lua.State
+                 -> StackIndex  -- ^ funcindex
+                 -> CInt        -- ^ n
+                 -> IO CString
+
+-- | Sets the value of a closure’s upvalue. It assigns the value on the
+-- top of the stack to the upvalue and returns its name. It also pops
+-- the value from the stack.
+--
+-- Returns @NULL@ (and pops nothing) when the index @n@ is greater than
+-- the number of upvalues.
+--
+-- Parameters @funcindex@ and @n@ are as in the function
+-- 'lua_getupvalue'.
+--
+-- @[-(0|1), +0, -]@
+--
+-- <https://www.lua.org/manual/5.4/manual.html#lua_setupvalue lua_setupvalue>.
+foreign import ccall unsafe "lua.h lua_setupvalue"
+  lua_setupvalue :: Lua.State
+                 -> StackIndex  -- ^ funcindex
+                 -> CInt        -- ^ n
+                 -> IO CString
