diff --git a/configurations/nos/modules/comics/default.nix b/configurations/nos/modules/comics/default.nix
new file mode 100644
index 00000000..1dd37ece
--- /dev/null
+++ b/configurations/nos/modules/comics/default.nix
@@ -0,0 +1,9 @@
+{...}: {
+  imports = [
+    ./komga
+
+    # TODO: setup JDownloader2 webui?
+    # TODO: Not sure if this one is needed
+    # ./mylar3
+  ];
+}
diff --git a/configurations/nos/modules/comics/komga/default.nix b/configurations/nos/modules/comics/komga/default.nix
new file mode 100644
index 00000000..311589ed
--- /dev/null
+++ b/configurations/nos/modules/comics/komga/default.nix
@@ -0,0 +1,100 @@
+{
+  config,
+  lib,
+  mainUser,
+  pkgs,
+  ...
+}: let
+  inherit (lib) concatStringsSep getExe;
+  inherit (config.sops) secrets;
+
+  cfg = config.services.komga;
+in {
+  services.komga = {
+    enable = true;
+
+    user = mainUser;
+    group = mainUser;
+
+    settings = {
+      server.port = 7080;
+    };
+  };
+
+  # use with this https://github.com/Snd-R/komf-userscript
+  systemd.services.komf = let
+    stateDir = "/var/lib/komf";
+
+    komfConf = pkgs.writers.writeJSON "application.yml" {
+      komga = {
+        baseUri = "http://nos:${toString cfg.settings.server.port}";
+        metadataUpdate.default = {
+          libraryType = "COMIC";
+          overrideExistingCovers = false;
+          overrideComicInfo = true;
+          postProcessing = {
+            seriesTitle = true;
+            orderBooks = true;
+          };
+        };
+      };
+      database.file = "${stateDir}/database.sqlite";
+      metadataProviders.defaultProviders.comicVine = {
+        priority = 1;
+        enabled = true;
+      };
+    };
+  in {
+    wantedBy = ["multi-user.target"];
+    wants = ["network-online.target"];
+    after = ["network-online.target" "komga.service"];
+
+    preStart = ''
+      ln -sf ${komfConf} ${stateDir}/application.yml
+    '';
+
+    serviceConfig = {
+      User = cfg.user;
+      Group = cfg.group;
+
+      EnvironmentFile = secrets.komf.path;
+
+      Type = "simple";
+      Restart = "on-failure";
+      ExecStart = concatStringsSep " " [
+        (getExe pkgs.selfPackages.komf)
+        stateDir
+      ];
+
+      StateDirectory = "komf";
+
+      # Hardening from komga service
+      RemoveIPC = true;
+      NoNewPrivileges = true;
+      CapabilityBoundingSet = "";
+      SystemCallFilter = ["@system-service"];
+      ProtectSystem = "full";
+      PrivateTmp = true;
+      ProtectProc = "invisible";
+      ProtectClock = true;
+      ProcSubset = "pid";
+      PrivateUsers = true;
+      PrivateDevices = true;
+      ProtectHostname = true;
+      ProtectKernelTunables = true;
+      RestrictAddressFamilies = [
+        "AF_INET"
+        "AF_INET6"
+        "AF_NETLINK"
+      ];
+      LockPersonality = true;
+      RestrictNamespaces = true;
+      ProtectKernelLogs = true;
+      ProtectControlGroups = true;
+      ProtectKernelModules = true;
+      SystemCallArchitectures = "native";
+      RestrictSUIDSGID = true;
+      RestrictRealtime = true;
+    };
+  };
+}
diff --git a/configurations/nos/modules/comics/mylar3/default.nix b/configurations/nos/modules/comics/mylar3/default.nix
new file mode 100644
index 00000000..2887db4f
--- /dev/null
+++ b/configurations/nos/modules/comics/mylar3/default.nix
@@ -0,0 +1,28 @@
+{
+  config,
+  mainUser,
+  pkgs,
+  ...
+}: {
+  virtualisation.docker.compose."mylar3".services."mylar3" = {
+    image = pkgs.callPackage ./images/mylar3.nix pkgs;
+    restart = "always";
+
+    environment = {
+      PUID = toString config.users.users.${mainUser}.uid;
+      PGID = toString config.users.users.${mainUser}.uid;
+      TZ = "America/New_York";
+    };
+
+    ports = [
+      "8090:8090"
+    ];
+
+    volumes = [
+      "/var/lib/mylar3:/config"
+      "/data/comics:/comics"
+      "/data/downloads/comics:/downloads"
+      "/data/downloads/watch-comics:/watch"
+    ];
+  };
+}
diff --git a/configurations/nos/modules/comics/mylar3/images/mylar3.nix b/configurations/nos/modules/comics/mylar3/images/mylar3.nix
new file mode 100644
index 00000000..50b6b068
--- /dev/null
+++ b/configurations/nos/modules/comics/mylar3/images/mylar3.nix
@@ -0,0 +1,8 @@
+pkgs:
+pkgs.dockerTools.pullImage rec {
+  imageName = "ghcr.io/linuxserver/mylar3";
+  imageDigest = "sha256:124eb1d44d7683fa05fe586b8b6eb04311f2cf96891a1107adba47c74a774b1e";
+  hash = "sha256-R3LUytujJNJcakTRW/3i8I+VVfiOJZKWvsNtLoqyfsE=";
+  finalImageName = imageName;
+  finalImageTag = "0.8.2";
+}
diff --git a/configurations/nos/modules/default.nix b/configurations/nos/modules/default.nix
index 4e0bd8c6..c664e478 100644
--- a/configurations/nos/modules/default.nix
+++ b/configurations/nos/modules/default.nix
@@ -1,5 +1,6 @@
 {...}: {
   imports = [
+    ./comics
     ./docker
     ./homepage
     ./jellyfin
diff --git a/flake.lock b/flake.lock
index 246914ac..1ce3c71f 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1718,11 +1718,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1742154705,
-        "narHash": "sha256-ZvnmJYSxKrmAXmS2UWja1MgXQ1I09FXtNzx8JjiQHSU=",
+        "lastModified": 1742356976,
+        "narHash": "sha256-+wOAk2qoKEibLR26QrMihl5enkijZu42cuBaHaGrBWk=",
         "ref": "refs/heads/main",
-        "rev": "628f5e52bc860cf039e291778cf8e86785a57d78",
-        "revCount": 94,
+        "rev": "a840d582efb9a11bd74439a536e8dbfe089977fb",
+        "revCount": 95,
         "type": "git",
         "url": "ssh://git@git.nelim.org/matt1432/nixos-secrets"
       },
diff --git a/packages/default.nix b/packages/default.nix
index febbd668..a65a411a 100644
--- a/packages/default.nix
+++ b/packages/default.nix
@@ -19,6 +19,8 @@
 
     jmusicbot = final.callPackage ./jmusicbot {};
 
+    komf = final.callPackage ./komf {};
+
     libratbag = final.callPackage ./libratbag {
       inherit (inputs) libratbag-src;
     };
diff --git a/packages/komf/default.nix b/packages/komf/default.nix
new file mode 100644
index 00000000..ce105ae9
--- /dev/null
+++ b/packages/komf/default.nix
@@ -0,0 +1,49 @@
+{
+  lib,
+  stdenv,
+  fetchurl,
+  makeWrapper,
+  jre,
+  ...
+}: let
+  pname = "komf";
+  version = "1.3.0";
+in
+  stdenv.mkDerivation {
+    inherit pname version;
+
+    src = fetchurl {
+      url = "https://github.com/Snd-R/${pname}/releases/download/${version}/${pname}-${version}.jar";
+      hash = "sha256-6TR6NQnms/iqieRUSniEk2iLaQo/1mC1e1OWe8skNf8=";
+      name = "${pname}-${version}.jar";
+    };
+
+    nativeBuildInputs = [makeWrapper];
+    buildInputs = [
+      jre
+    ];
+
+    dontUnpack = true;
+
+    installPhase = ''
+      runHook preInstall
+
+      mkdir -p "$prefix/bin"
+
+      makeWrapper ${jre}/bin/java $out/bin/${pname} \
+        --add-flags "-jar $src" \
+        --prefix PATH : "$PATH"
+
+      runHook postInstall
+    '';
+
+    meta = {
+      mainProgram = pname;
+      license = lib.licenses.mit;
+      homepage = "https://github.com/Snd-R/komf";
+      sourceProvenance = with lib.sourceTypes; [binaryBytecode];
+      description = ''
+        komf is a tool that fetches metadata and thumbnails for your digital comic book library.
+      '';
+    };
+  }