> Is the module system similar to Nix's? Nix modules define imports, config schema and config values, which are merged together to produce an expression for the state of the whole system, e.g. configuration.nix. How's that work in GuixSD?

The way the Guix system is configured differs a lot from how it's done in NixOS. (Note, though, that I've never used NixOS, so I'll just talk about how it works in Guix.)

First about the term "modules" to avoid confusion: Guix code is organized in Guile modules. A Guile module is a file containing definitions. A module can export variable names. Other modules can use those variable names. That's just like how you'd do "import foo" in Python --- in Guile you do "(use-modules (where foo is))".

This is nothing to do with system configuration, of course; it's just a language feature.

The way a system is configured is through the `operating-system` record. Much like the `package` record for defining first class package values the `operating-system` record is used to declare operating systems. Here's an example straight from the manual:

(use-modules (gnu))
(use-service-modules networking ssh)
(use-package-modules screen)

(operating-system
(host-name "komputilo")
(timezone "Europe/Berlin")
(locale "en_US.utf8")

;; Boot in "legacy" BIOS mode, assuming /dev/sdX is the
;; target hard disk, and "my-root" is the label of the target
;; root file system.
(bootloader (bootloader-configuration
(bootloader grub-bootloader)
(target "/dev/sdX")))
(file-systems (cons (file-system
(device (file-system-label "my-root"))
(mount-point "/")
(type "ext4"))
%base-file-systems))

;; This is where user accounts are specified. The "root"
;; account is implicit, and is initially created with the
;; empty password.
(users (cons (user-account
(name "alice")
(comment "Bob's sister")
(group "users")

;; Adding the account to the "wheel" group
;; makes it a sudoer. Adding it to "audio"
;; and "video" allows the user to play sound
;; and access the webcam.
(supplementary-groups '("wheel"
"audio" "video")))
%base-user-accounts))

;; Globally-installed packages.
(packages (cons screen %base-packages))

;; Add services to the baseline: a DHCP client and
;; an SSH server.
(services (append (list (service dhcp-client-service-type)
(service openssh-service-type
(openssh-configuration
(port-number 2222))))
%base-services)))

The "packages" field is for declaring globally available packages, nothing special. What's interesting, though, is the "services" field. This is not just about services in the sense of daemons (i.e. Shepherd services that can be started and stopped), but about anything really to extend the system.

System services can be composed and may extend one another, see <https://www.gnu.org/software/guix/manual/en/html_node/Servic.... This can be used for complex system setup like web applications that require a web server configuration (e.g. by adding an nginx server block), a database, and so on. An example is the Zabbix system service. We also use the service framework for generating PAM policies, creating files in /etc, for udev rules, etc.

This framework was described also in comparison with NixOS in a 2015 blog post: https://www.gnu.org/software/guix/blog/2015/service-composit...

"guix system" operates on an "operating-system" value (read from a file or read as a Scheme expression) to instantiate a VM, a container image, or a bare-metal system.