diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 866dc01cfb32ab67678619928601f5839935a702..4dc5a7f0244e6ad6c7d3ddf4a31ee54639697044 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,15 +5,15 @@ stages:
   - test
 
 .rust_template: &rust_template
+  tags:
+    - nix
   before_script:
     - export CARGO_HOME="$CI_PROJECT_DIR/cargo"
-    - rustup --version
-    - rustc --version
-    - cargo --version
+    - nix develop -c rustc --version
+    - nix develop -c cargo --version
 
 rust-nightly:
   stage: build
-  image: rustlang/rust:nightly
   needs: []
   cache:
     key: "$CI_COMMIT_REF_SLUG"
@@ -22,11 +22,10 @@ rust-nightly:
       - target/
   <<: *rust_template
   script:
-    - cargo build --verbose
+    - nix develop -c cargo build --verbose
 
 rust-nightly-test:
   stage: test
-  image: rustlang/rust:nightly
   needs:
     - rust-nightly
   cache:
@@ -37,11 +36,10 @@ rust-nightly-test:
     policy: pull
   <<: *rust_template
   script:
-    - cargo test --verbose -j 1
+    - nix develop -c cargo test --verbose -j 1
 
 rust-nightly-fmt:
   stage: format
-  image: rustlang/rust:nightly
   needs: []
   cache:
     key: "$CI_COMMIT_REF_SLUG"
@@ -51,11 +49,10 @@ rust-nightly-fmt:
     policy: pull
   <<: *rust_template
   script:
-    - cargo fmt --all --verbose -- --check
+    - nix develop -c cargo fmt --all --verbose -- --check
 
 rust-nightly-clippy:
   stage: lint
-  image: rustlang/rust:nightly
   needs:
     - rust-nightly
   cache:
@@ -65,11 +62,10 @@ rust-nightly-clippy:
       - target/
   <<: *rust_template
   script:
-    - cargo clippy --all --tests --verbose -- -D warnings
+    - nix develop -c cargo clippy --all --tests --verbose -- -D warnings
 
 pages:
   stage: build
-  image: rustlang/rust:nightly
   needs:
     - rust-nightly
   cache:
@@ -80,10 +76,10 @@ pages:
     policy: pull
   <<: *rust_template
   script:
-    - cargo doc --no-deps
+    - nix develop -c cargo doc --no-deps
     - rm -rf public
     - mkdir public
     - cp -R target/doc/* public
   artifacts:
     paths:
-    - public
\ No newline at end of file
+    - public
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000000000000000000000000000000000000..ae7a77438b2f94d327b7ecf946d4d6d2128273a7
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,94 @@
+{
+  "nodes": {
+    "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
+      "locked": {
+        "lastModified": 1731533236,
+        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "naersk": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      },
+      "locked": {
+        "lastModified": 1736429655,
+        "narHash": "sha256-BwMekRuVlSB9C0QgwKMICiJ5EVbLGjfe4qyueyNQyGI=",
+        "owner": "nix-community",
+        "repo": "naersk",
+        "rev": "0621e47bd95542b8e1ce2ee2d65d6a1f887a13ce",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "naersk",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1737370608,
+        "narHash": "sha256-hFA6SmioeqvGW/XvZa9bxniAeulksCOcj3kokdNT/YE=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "300081d0cc72df578b02d914df941b8ec62240e6",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1737299813,
+        "narHash": "sha256-Qw2PwmkXDK8sPQ5YQ/y/icbQ+TYgbxfjhgnkNJyT1X8=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "107d5ef05c0b1119749e381451389eded30fb0d5",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-24.11",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-utils": "flake-utils",
+        "naersk": "naersk",
+        "nixpkgs": "nixpkgs_2"
+      }
+    },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000000000000000000000000000000000000..c299be4c8f30f00c8b538a9fd0f77a402a7c782c
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,45 @@
+{
+  inputs = {
+    flake-utils.url = "github:numtide/flake-utils";
+    naersk.url = "github:nix-community/naersk";
+    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
+  };
+
+  outputs = {
+    self,
+    flake-utils,
+    naersk,
+    nixpkgs,
+  }:
+    flake-utils.lib.eachDefaultSystem (
+      system: let
+        pkgs = (import nixpkgs) {
+          inherit system;
+        };
+
+        naersk' = pkgs.callPackage naersk {};
+      in {
+        defaultPackage = naersk'.buildPackage {
+          src = ./.;
+          buildInputs = with pkgs; [];
+          nativeBuildInputs = with pkgs; [ pkg-config ];
+        };
+
+        devShell = pkgs.mkShell {
+          buildInputs = with pkgs; [];
+          nativeBuildInputs = with pkgs; [
+            rustc
+            cargo
+            rustfmt
+            rust-analyzer
+            pkg-config
+            clippy
+            cargo-tarpaulin
+          ];
+        };
+
+        formatter = nixpkgs.legacyPackages.${system}.alejandra;
+      }
+    );
+}
+
diff --git a/src/thread/manager.rs b/src/thread/manager.rs
index 1b744473d1a045a2e54e160912202669616c3cb4..10b6815a391be278bcfa8ba3067f940651991dfe 100644
--- a/src/thread/manager.rs
+++ b/src/thread/manager.rs
@@ -135,8 +135,8 @@ impl ThreadManager {
             })
             .collect();
 
-        #[allow(clippy::clone_double_ref)]
-        let monitor_for_monitor_thread = self.monitor.clone();
+        #[allow(suspicious_double_ref_op)]
+        let monitor_for_monitor_thread = self.monitor;
         let monitor_join_handle = std::thread::spawn(move || {
             let watch_result = monitor_for_monitor_thread.watch(Some(&watched_thread_ids));
 
diff --git a/src/thread/monitor.rs b/src/thread/monitor.rs
index c2cf0d614eb14a031f8786837d12d5039f34e72a..cc9eb568729241296fd70659cd98b9ac9b67b0bc 100644
--- a/src/thread/monitor.rs
+++ b/src/thread/monitor.rs
@@ -77,18 +77,15 @@ impl ThreadMonitor {
         panic::set_hook(Box::new(move |panic_info| {
             match self.state.lock() {
                 Ok(mut state) => {
-                    match &state.watched {
-                        Some(watched) => {
-                            let current_thread = thread::current();
+                    if let Some(watched) = &state.watched {
+                        let current_thread = thread::current();
 
-                            // Only notify if the thread ID is being watched.
-                            if watched.contains(&current_thread.id()) {
-                                state.panicked.insert(current_thread.id(), current_thread);
+                        // Only notify if the thread ID is being watched.
+                        if watched.contains(&current_thread.id()) {
+                            state.panicked.insert(current_thread.id(), current_thread);
 
-                                self.condvar.notify_all();
-                            }
+                            self.condvar.notify_all();
                         }
-                        None => {}
                     }
                 }
                 Err(_) => log::error!("Unable to update map of panicked threads."),