diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,18 @@
 
 `hslua-module-system` uses [PVP Versioning][].
 
+## hslua-module-system-1.3.0
+
+Released 2026-01-08.
+
+- Require hslua-packaging 2.4 or later.
+
+## hslua-module-system-1.2.3
+
+Release 2025-08-09.
+
+-   Allowed time-1.15.
+
 ## hslua-module-system-1.2.2
 
 Released 2025-08-09.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019-2024 Albert Krewinkel
+Copyright (c) 2019-2026 Albert Krewinkel
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/hslua-module-system.cabal b/hslua-module-system.cabal
--- a/hslua-module-system.cabal
+++ b/hslua-module-system.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                hslua-module-system
-version:             1.2.3
+version:             1.3.0
 synopsis:            Lua module wrapper around Haskell's System module.
 
 description:         Provides access to system information and
@@ -15,20 +15,15 @@
 license-file:        LICENSE
 author:              Albert Krewinkel
 maintainer:          tarleb@hslua.org
-copyright:           © 2019-2025 Albert Krewinkel <tarleb@hslua.org>
+copyright:           © 2019-2026 Albert Krewinkel <tarleb@hslua.org>
 category:            Foreign
 extra-source-files:  test/test-system.lua
 extra-doc-files:     CHANGELOG.md
                    , README.md
-tested-with:         GHC == 8.8.4
-                   , GHC == 8.10.7
-                   , GHC == 9.0.2
-                   , GHC == 9.2.8
-                   , GHC == 9.4.8
-                   , GHC == 9.6.7
-                   , GHC == 9.8.4
-                   , GHC == 9.10.2
-                   , GHC == 9.12.2
+tested-with:         GHC == 9.6
+                   , GHC == 9.8
+                   , GHC == 9.10
+                   , GHC == 9.12
 
 source-repository head
   type:              git
@@ -39,7 +34,7 @@
   default-language:    Haskell2010
   build-depends:       base                 >= 4.11   && < 5
                      , hslua-core           >= 2.1    && < 2.4
-                     , hslua-packaging      >= 2.3    && < 2.4
+                     , hslua-packaging      >= 2.4    && < 2.5
   default-extensions:  LambdaCase
                      , OverloadedStrings
 
@@ -68,7 +63,7 @@
                      , process              >= 1.2.3  && < 1.7
                      , temporary            >= 1.2    && < 1.4
                      , text                 >= 1.2    && < 2.2
-                     , time                 >= 1.9    && < 1.15
+                     , time                 >= 1.9    && < 1.16
   exposed-modules:     HsLua.Module.System
   other-modules:       HsLua.Module.SystemUtils
   hs-source-dirs:      src
diff --git a/src/HsLua/Module/System.hs b/src/HsLua/Module/System.hs
--- a/src/HsLua/Module/System.hs
+++ b/src/HsLua/Module/System.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module      : HsLua.Module.System
-Copyright   : © 2019-2025 Albert Krewinkel
+Copyright   : © 2019-2026 Albert Krewinkel
 License     : MIT
 Maintainer  : Albert Krewinkel <tarleb@hslua.org>
 Stability   : alpha
@@ -72,16 +72,15 @@
 
 -- | The "system" module.
 documentedModule :: LuaError e => Module e
-documentedModule = Module
-  { moduleName = "system"
-  , moduleFields =
+documentedModule = defmodule "system"
+  `withFields`
       [ arch
       , compiler_name
       , compiler_version
       , cputime_precision
       , os
       ]
-  , moduleFunctions =
+  `withFunctions`
       [ cmd
       , cp
       , cputime
@@ -105,11 +104,8 @@
       , write_file
       , xdg
       ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  , moduleDescription =
+  `withDescription`
       "Access to the system's information and file functionality."
-  }
 
 --
 -- Fields
@@ -118,64 +114,58 @@
 -- | Module field containing the machine architecture on which the
 -- program is running. Wraps @'Info.arch'@
 arch :: Field e
-arch = Field
-  { fieldName = "arch"
-  , fieldType = "string"
-  , fieldDescription =
-      "The machine architecture on which the program is running."
-  , fieldPushValue = pushString Info.arch
-  }
+arch = deffield "arch"
+  `withType`
+    stringType
+  `withDescription`
+    "The machine architecture on which the program is running."
+  `withValue`
+    pushString Info.arch
 
 -- | Module field containing the Haskell implementation with which the
 -- host program was compiled. Wraps @'Info.compilerName'@.
 compiler_name :: Field e
-compiler_name = Field
-  { fieldName = "compiler_name"
-  , fieldType = "string"
-  , fieldDescription = "The Haskell implementation with which the host "
-                       `T.append` "program was compiled."
-  , fieldPushValue = pushString Info.compilerName
-  }
+compiler_name = deffield "compiler_name"
+  `withType`
+    stringType
+  `withDescription`
+    "The Haskell implementation with which the host program was compiled."
+  `withValue`
+    pushString Info.compilerName
 
 -- | Module field containing the version of `compiler_name` with which
 -- the host program was compiled.
 compiler_version :: LuaError e => Field e
-compiler_version = Field
-  { fieldName = "compiler_version"
-  , fieldType = "string"
-  , fieldDescription = T.unwords
-      [ "The Haskell implementation with which the host "
-      , "program was compiled." ]
-  , fieldPushValue = pushList pushIntegral $
-                     versionBranch Info.compilerVersion
-  }
+compiler_version = deffield "compiler_version"
+  `withType`
+    stringType
+  `withDescription`
+    "The Haskell implementation with which the host program was compiled."
+  `withValue`
+    pushList pushIntegral (versionBranch Info.compilerVersion)
 
 -- | Field containing the smallest measurable difference in CPU time.
 cputime_precision :: Field e
-cputime_precision = Field
-  { fieldName = "cputime_precision"
-  , fieldType = "integer"
-  , fieldDescription = T.unlines
+cputime_precision = deffield "cputime_precision"
+  `withType` integerType
+  `withDescription` T.unlines
       [ "The smallest measurable difference in CPU time that the"
       , "implementation can record, and is given as an integral number of"
       , "picoseconds."
       ]
-  , fieldPushValue = pushIntegral CPUTime.cpuTimePrecision
-  }
+  `withValue` pushIntegral CPUTime.cpuTimePrecision
 
 -- | Field containing the operating system on which the program is
 -- running.
 os :: Field e
-os = Field
-  { fieldName = "os"
-  , fieldType = "string"
-  , fieldDescription = T.unlines
+os = deffield "os"
+  `withType` "string"
+  `withDescription` T.unlines
     [ "The operating system on which the program is running."
     , "The most common values are `darwin` (macOS), `freebsd`, `linux`,"
     , "`linux-android`, `mingw32` (Windows), `netbsd`, `openbsd`."
     ]
-  , fieldPushValue = pushString Info.os
-  }
+  `withValue` pushString Info.os
 
 
 --
diff --git a/src/HsLua/Module/SystemUtils.hs b/src/HsLua/Module/SystemUtils.hs
--- a/src/HsLua/Module/SystemUtils.hs
+++ b/src/HsLua/Module/SystemUtils.hs
@@ -1,6 +1,6 @@
 {-|
 Module      : HsLua.Module.SystemUtils
-Copyright   : © 2019-2025 Albert Krewinkel
+Copyright   : © 2019-2026 Albert Krewinkel
 License     : MIT
 Maintainer  : Albert Krewinkel <tarleb@hslua.org>
 
diff --git a/test/test-hslua-module-system.hs b/test/test-hslua-module-system.hs
--- a/test/test-hslua-module-system.hs
+++ b/test/test-hslua-module-system.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE TypeApplications  #-}
 {-|
 Module      : Main
-Copyright   : © 2019-2024 Albert Krewinkel
+Copyright   : © 2019-2026 Albert Krewinkel
 License     : MIT
 Maintainer  : Albert Krewinkel <tarleb@hslua.org>
 Stability   : alpha
