diff --git a/modules/system/launchd.nix b/modules/system/launchd.nix
new file mode 100644
index 00000000..fc85af4f
--- /dev/null
+++ b/modules/system/launchd.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.system;
+
+ text = import ../system/write-text.nix {
+ inherit lib;
+ mkTextDerivation = pkgs.writeText;
+ };
+
+ launchAgents = filter (f: f.enable) (attrValues config.environment.launchAgents);
+ launchDaemons = filter (f: f.enable) (attrValues config.environment.launchDaemons);
+
+in
+
+{
+ options = {
+
+ environment.launchAgents = mkOption {
+ type = types.loaOf (types.submodule text);
+ default = {};
+ description = ''
+ Set of files that have to be linked in /Library/LaunchAgents.
+ '';
+ };
+
+ environment.launchDaemons = mkOption {
+ type = types.loaOf (types.submodule text);
+ default = {};
+ description = ''
+ Set of files that have to be linked in /Library/LaunchDaemons.
+ '';
+ };
+
+ };
+
+ config = {
+
+ system.build.launchd = pkgs.runCommand "launchd" {} ''
+ mkdir -p $out/Library/LaunchAgents $out/Library/LaunchDaemons
+ cd $out/Library/LaunchAgents
+ ${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") launchAgents}
+ cd $out/Library/LaunchDaemons
+ ${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") launchDaemons}
+ '';
+
+ system.activationScripts.launchd.text = ''
+ # Set up launchd services in /Library/LaunchAgents and /Library/LaunchDaemons
+ echo "setting up launchd services..."
+
+ ${concatMapStringsSep "\n" (attr: "launchctl unload '/Library/LaunchAgents/${attr.target}'") launchAgents}
+ ${concatMapStringsSep "\n" (attr: "launchctl unload '/Library/LaunchDaemons/${attr.target}'") launchDaemons}
+ ${concatMapStringsSep "\n" (attr: "cp -f '${cfg.build.launchd}/Library/LaunchAgents/${attr.target}' '/Library/LaunchAgents/${attr.target}'") launchAgents}
+ ${concatMapStringsSep "\n" (attr: "cp -f '${cfg.build.launchd}/Library/LaunchDaemons/${attr.target}' '/Library/LaunchDaemons/${attr.target}'") launchDaemons}
+ ${concatMapStringsSep "\n" (attr: "launchctl load '/Library/LaunchAgents/${attr.target}'") launchAgents}
+ ${concatMapStringsSep "\n" (attr: "launchctl load '/Library/LaunchDaemons/${attr.target}'") launchDaemons}
+ '';
+
+ };
+}