diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix
index 6f06f4510..aa06a883d 100644
--- a/krebs/3modules/default.nix
+++ b/krebs/3modules/default.nix
@@ -50,7 +50,6 @@ let
       ./secret.nix
       ./setuid.nix
       ./shadow.nix
-      ./syncthing.nix
       ./tinc.nix
       ./tinc_graphs.nix
       ./urlwatch.nix
diff --git a/krebs/3modules/syncthing.nix b/krebs/3modules/syncthing.nix
deleted file mode 100644
index 799ed7eda..000000000
--- a/krebs/3modules/syncthing.nix
+++ /dev/null
@@ -1,206 +0,0 @@
-{ config, pkgs, ... }: with import <stockholm/lib>;
-
-let
-
-  kcfg = config.krebs.syncthing;
-  scfg = config.services.syncthing;
-
-  devices = mapAttrsToList (name: peer: {
-    name = name;
-    deviceID = peer.id;
-    addresses = peer.addresses;
-  }) kcfg.peers;
-
-  folders = mapAttrsToList ( _: folder: {
-    inherit (folder) path id type;
-    devices = map (peer: { deviceId = kcfg.peers.${peer}.id; }) folder.peers;
-    rescanIntervalS = folder.rescanInterval;
-    fsWatcherEnabled = folder.watch;
-    fsWatcherDelayS = folder.watchDelay;
-    ignoreDelete = folder.ignoreDelete;
-    ignorePerms = folder.ignorePerms;
-  }) kcfg.folders;
-
-  getApiKey = pkgs.writeDash "getAPIKey" ''
-    ${pkgs.libxml2}/bin/xmllint \
-      --xpath 'string(configuration/gui/apikey)'\
-      ${scfg.configDir}/config.xml
-  '';
-
-  updateConfig = pkgs.writeDash "merge-syncthing-config" ''
-    set -efu
-
-    # XXX this assumes the GUI address to be "IPv4 address and port"
-    host=${shell.escape (elemAt (splitString ":" scfg.guiAddress) 0)}
-    port=${shell.escape (elemAt (splitString ":" scfg.guiAddress) 1)}
-
-    # wait for service to restart
-    ${pkgs.untilport}/bin/untilport "$host" "$port"
-
-    API_KEY=$(${getApiKey})
-
-    _curl() {
-      ${pkgs.curl}/bin/curl \
-          -Ss \
-          -H "X-API-Key: $API_KEY" \
-          "http://$host:$port/rest""$@"
-    }
-
-    old_config=$(_curl /system/config)
-    new_config=${shell.escape (toJSON {
-      inherit devices folders;
-    })}
-    new_config=$(${pkgs.jq}/bin/jq -en \
-        --argjson old_config "$old_config" \
-        --argjson new_config "$new_config" \
-        '
-          $old_config * $new_config
-          ${optionalString (!kcfg.overridePeers) ''
-            * { devices: $old_config.devices }
-          ''}
-          ${optionalString (!kcfg.overrideFolders) ''
-            * { folders: $old_config.folders }
-          ''}
-        '
-    )
-    echo $new_config | _curl /system/config -d @-
-    _curl /system/restart -X POST
-  '';
-
-in
-
-{
-  options.krebs.syncthing = {
-
-    enable = mkEnableOption "syncthing-init";
-
-    cert = mkOption {
-      type = types.nullOr types.absolute-pathname;
-      default = null;
-    };
-
-    key = mkOption {
-      type = types.nullOr types.absolute-pathname;
-      default = null;
-    };
-
-    overridePeers = mkOption {
-      type = types.bool;
-      default = true;
-      description = ''
-        Whether to delete the peers which are not configured via the peers option
-      '';
-    };
-    peers = mkOption {
-      default = {};
-      type = types.attrsOf (types.submodule ({
-        options = {
-
-          # TODO make into addr + port submodule
-          addresses = mkOption {
-            type = types.listOf types.str;
-            default = [];
-          };
-
-          #TODO check
-          id = mkOption {
-            type = types.str;
-          };
-
-        };
-      }));
-    };
-
-    overrideFolders = mkOption {
-      type = types.bool;
-      default = true;
-      description = ''
-        Whether to delete the folders which are not configured via the peers option
-      '';
-    };
-    folders = mkOption {
-      default = {};
-      type = types.attrsOf (types.submodule ({ config, ... }: {
-        options = {
-
-          path = mkOption {
-            type = types.absolute-pathname;
-            default = config._module.args.name;
-          };
-
-          id = mkOption {
-            type = types.str;
-            default = config._module.args.name;
-          };
-
-          peers = mkOption {
-            type = types.listOf types.str;
-            default = [];
-          };
-
-          rescanInterval = mkOption {
-            type = types.int;
-            default = 3600;
-          };
-
-          type = mkOption {
-            type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
-            default = "sendreceive";
-          };
-
-          watch = mkOption {
-            type = types.bool;
-            default = true;
-          };
-
-          watchDelay = mkOption {
-            type = types.int;
-            default = 10;
-          };
-
-          ignoreDelete = mkOption {
-            type = types.bool;
-            default = false;
-          };
-
-          ignorePerms = mkOption {
-            type = types.bool;
-            default = true;
-          };
-
-        };
-      }));
-    };
-  };
-
-  config = mkIf kcfg.enable {
-
-    systemd.services.syncthing = mkIf (kcfg.cert != null || kcfg.key != null) {
-      serviceConfig.PermissionsStartOnly = mkDefault true;
-      preStart = ''
-        ${optionalString (kcfg.cert != null) ''
-          cp ${toString kcfg.cert} ${scfg.configDir}/cert.pem
-          chown ${scfg.user}:${scfg.group} ${scfg.configDir}/cert.pem
-          chmod 400 ${scfg.configDir}/cert.pem
-        ''}
-        ${optionalString (kcfg.key != null) ''
-          cp ${toString kcfg.key} ${scfg.configDir}/key.pem
-          chown ${scfg.user}:${scfg.group} ${scfg.configDir}/key.pem
-          chmod 400 ${scfg.configDir}/key.pem
-        ''}
-      '';
-    };
-
-    systemd.services.syncthing-init = {
-      after = [ "syncthing.service" ];
-      wantedBy = [ "multi-user.target" ];
-
-      serviceConfig = {
-        User = scfg.user;
-        RemainAfterExit = true;
-        Type = "oneshot";
-        ExecStart = updateConfig;
-      };
-    };
-  };
-}
diff --git a/lass/1systems/mors/config.nix b/lass/1systems/mors/config.nix
index 03ff42132..fe0b6d85b 100644
--- a/lass/1systems/mors/config.nix
+++ b/lass/1systems/mors/config.nix
@@ -49,17 +49,17 @@ with import <stockholm/lib>;
       ];
     }
     {
-      krebs.syncthing = {
-        peers.schasch.addresses = [ "schasch.r:22000" ];
+      services.syncthing.declarative = {
+        devices.schasch.addresses = [ "schasch.r:22000" ];
         folders = {
           the_playlist = {
             path = "/home/lass/tmp/the_playlist";
-            peers = [ "mors" "phone" "prism" "xerxes" ];
+            devices = [ "mors" "phone" "prism" "xerxes" ];
           };
           free_music = {
             id = "mu9mn-zgvsw";
             path = "/home/lass/tmp/free_music";
-            peers = [ "mors" "schasch" ];
+            devices = [ "mors" "schasch" ];
           };
         };
       };
diff --git a/lass/1systems/xerxes/config.nix b/lass/1systems/xerxes/config.nix
index 8630d0f4b..e4a4fb505 100644
--- a/lass/1systems/xerxes/config.nix
+++ b/lass/1systems/xerxes/config.nix
@@ -41,11 +41,11 @@
     displayManager.lightdm.autoLogin.user = "lass";
   };
 
-  krebs.syncthing = {
+  services.syncthing.declarative = {
     folders = {
       the_playlist = {
         path = "/home/lass/tmp/the_playlist";
-        peers = [ "mors" "phone" "prism" "xerxes" ];
+        devices = [ "mors" "phone" "prism" "xerxes" ];
       };
     };
   };
diff --git a/lass/2configs/green-host.nix b/lass/2configs/green-host.nix
index 1421eede7..0cccbc30e 100644
--- a/lass/2configs/green-host.nix
+++ b/lass/2configs/green-host.nix
@@ -20,7 +20,7 @@ with import <stockholm/lib>;
     }
   ];
 
-  krebs.syncthing.folders."/var/lib/sync-containers".peers = [ "icarus" "skynet" "littleT" "shodan" ];
+  services.syncthing.declarative.folders."/var/lib/sync-containers".devices = [ "icarus" "skynet" "littleT" "shodan" ];
   krebs.permown."/var/lib/sync-containers" = {
     owner = "root";
     group = "syncthing";
diff --git a/lass/2configs/radio.nix b/lass/2configs/radio.nix
index 1a5aadeba..74b15a0ab 100644
--- a/lass/2configs/radio.nix
+++ b/lass/2configs/radio.nix
@@ -277,9 +277,9 @@ in {
       alias ${html};
     '';
   };
-  krebs.syncthing.folders."the_playlist" = {
+  services.syncthing.declarative.folders."the_playlist" = {
     path = "/home/radio/music/the_playlist";
-    peers = [ "mors" "phone" "prism" "xerxes" ];
+    devices = [ "mors" "phone" "prism" "xerxes" ];
   };
   krebs.permown."/home/radio/music/the_playlist" = {
     owner = "radio";
diff --git a/lass/2configs/sync/decsync.nix b/lass/2configs/sync/decsync.nix
index c3f6511c2..9caefdd2d 100644
--- a/lass/2configs/sync/decsync.nix
+++ b/lass/2configs/sync/decsync.nix
@@ -1,7 +1,7 @@
 {
-  krebs.syncthing.folders.decsync = {
+  services.syncthing.declarative.folders.decsync = {
     path = "/home/lass/decsync";
-    peers = [ "mors" "blue" "green" "phone" ];
+    devices = [ "mors" "blue" "green" "phone" ];
   };
   krebs.permown."/home/lass/decsync" = {
     owner = "lass";
diff --git a/lass/2configs/sync/weechat.nix b/lass/2configs/sync/weechat.nix
index 30c7b262b..ccbfc75a1 100644
--- a/lass/2configs/sync/weechat.nix
+++ b/lass/2configs/sync/weechat.nix
@@ -1,5 +1,5 @@
 {
-  krebs.syncthing.folders."/home/lass/.weechat".peers = [ "blue" "green" "mors" ];
+  services.syncthing.declarative.folders."/home/lass/.weechat".devices = [ "blue" "green" "mors" ];
   krebs.permown."/home/lass/.weechat" = {
     owner = "lass";
     group = "syncthing";
diff --git a/lass/2configs/syncthing.nix b/lass/2configs/syncthing.nix
index d4df17b9a..5397c2ca6 100644
--- a/lass/2configs/syncthing.nix
+++ b/lass/2configs/syncthing.nix
@@ -7,18 +7,20 @@ in {
     enable = true;
     group = "syncthing";
     configDir = "/var/lib/syncthing";
+    declarative = {
+      key = toString <secrets/syncthing.key>;
+      cert = toString <secrets/syncthing.cert>;
+      devices = mk_peers all_peers;
+      folders."/home/lass/sync" = {
+        devices = attrNames (filterAttrs (n: v: n != "phone") own_peers);
+        # ignorePerms = false;
+      };
+    };
   };
   krebs.iptables.tables.filter.INPUT.rules = [
     { predicate = "-p tcp --dport 22000"; target = "ACCEPT";}
     { predicate = "-p udp --dport 21027"; target = "ACCEPT";}
   ];
-  krebs.syncthing = {
-    enable = true;
-    cert = toString <secrets/syncthing.cert>;
-    key = toString <secrets/syncthing.key>;
-    peers = mk_peers all_peers;
-    folders."/home/lass/sync".peers = attrNames (filterAttrs (n: v: n != "phone") own_peers);
-  };
 
   system.activationScripts.syncthing-home = ''
     ${pkgs.coreutils}/bin/chmod a+x /home/lass
diff --git a/lass/2configs/websites/domsen.nix b/lass/2configs/websites/domsen.nix
index 80ed12edc..bd113567f 100644
--- a/lass/2configs/websites/domsen.nix
+++ b/lass/2configs/websites/domsen.nix
@@ -270,14 +270,14 @@ in {
   };
 
   boot.kernel.sysctl."fs.inotify.max_user_watches" = "1048576";
-  krebs.syncthing.folders = {
+  services.syncthing.declarative.folders = {
     domsen-backups = {
       path = "/backups/domsen";
-      peers = [ "domsen-backup" ];
+      devices = [ "domsen-backup" ];
     };
     domsen-backup-srv-http = {
       path = "/srv/http";
-      peers = [ "domsen-backup" ];
+      devices = [ "domsen-backup" ];
     };
   };