diff --git a/horizon.dhall b/horizon.dhall
index b0ecef6ee56d09646b215a7ec9d669a97d780f39..9521b6b6b05c3ee268d7039afbbed9678e7cee88 100644
--- a/horizon.dhall
+++ b/horizon.dhall
@@ -26,7 +26,12 @@ let packages =
       , hxt-charproperties = H.callHackage "hxt-charproperties" "9.5.0.0"
       , hxt-regex-xmlschema = H.callHackage "hxt-regex-xmlschema" "9.2.0.7"
       , hxt-unicode = H.callHackage "hxt-unicode" "9.0.2.4"
+      , indexed-profunctors = H.callHackage "indexed-profunctors" "0.1.1"
       , linear = H.callHackage "linear" "1.22"
+      , optics = H.callHackage "optics" "0.4.2"
+      , optics-core = H.callHackage "optics-core" "0.4.1"
+      , optics-extra = H.callHackage "optics-extra" "0.4.2.1"
+      , optics-th = H.callHackage "optics-th" "0.4.1"
       , polyparse = H.callHackage "polyparse" "1.13"
       , polysemy = H.callHackage "polysemy" "1.9.1.0"
       , quiet = H.callHackage "quiet" "0.2"
diff --git a/horizon.lock b/horizon.lock
index 76e949070e24959e0ad0c1330355ae31d3fe544d..61866e9b96df538f6adc6bdfc501df4b864fdf22 100644
--- a/horizon.lock
+++ b/horizon.lock
@@ -90,10 +90,30 @@
   , mapValue =
       "0f704a54006d45142f4faf04c1f09ffbcb3c11931d0b14076b806a18e3146648"
   }
+, { mapKey = "indexed-profunctors"
+  , mapValue =
+      "1212d0c2f9c6d2777be410ca5832a05f036988e43982f44fb940109f5b71e320"
+  }
 , { mapKey = "linear"
   , mapValue =
       "edb8c9191d3d13df10761bb4a7a9de7761a87028f7694757f825e2365516abf9"
   }
+, { mapKey = "optics"
+  , mapValue =
+      "6f0526b6ddc61746262cb635b40c53bffc6779d040de8eeab794e18304028361"
+  }
+, { mapKey = "optics-core"
+  , mapValue =
+      "aedd636be7c56024aaac37faf05aadb40003d1c45836a8553ab58d89a5546c9f"
+  }
+, { mapKey = "optics-extra"
+  , mapValue =
+      "45283127b7d0ea2744a9ee4087c6c63380414e79945b97272f0096e9141e8141"
+  }
+, { mapKey = "optics-th"
+  , mapValue =
+      "e65b287afd4ad424aa567767678b83e160fe1b1d0a1614c8d8f7fbc453944052"
+  }
 , { mapKey = "polyparse"
   , mapValue =
       "2cac3d1ba9be7501de571a085512834798adc0d76aea9ba65bfa460fa5cf9e09"
diff --git a/overlay.nix b/overlay.nix
index f05416fda84c361d001e41e9977a573e4bdf41f4..33e3cb921b40bdc27b857396c271a03068c1148f 100644
--- a/overlay.nix
+++ b/overlay.nix
@@ -47,8 +47,18 @@ final: prev: with pkgs.haskell.lib; {
 
   hxt-unicode = final.callPackage (./pkgs/hxt-unicode.nix) { };
 
+  indexed-profunctors = final.callPackage (./pkgs/indexed-profunctors.nix) { };
+
   linear = final.callPackage (./pkgs/linear.nix) { };
 
+  optics = final.callPackage (./pkgs/optics.nix) { };
+
+  optics-core = final.callPackage (./pkgs/optics-core.nix) { };
+
+  optics-extra = final.callPackage (./pkgs/optics-extra.nix) { };
+
+  optics-th = final.callPackage (./pkgs/optics-th.nix) { };
+
   polyparse = final.callPackage (./pkgs/polyparse.nix) { };
 
   polysemy = final.callPackage (./pkgs/polysemy.nix) { };
diff --git a/pkgs/indexed-profunctors.nix b/pkgs/indexed-profunctors.nix
new file mode 100644
index 0000000000000000000000000000000000000000..81663a5a4e489d7296d3ff7b2b89012d46834793
--- /dev/null
+++ b/pkgs/indexed-profunctors.nix
@@ -0,0 +1,20 @@
+{ mkDerivation, base, lib }:
+mkDerivation {
+  pname = "indexed-profunctors";
+  version = "0.1.1";
+  sha256 = "5aba418a92a4f75efc626de7c0e4d88ed57033e0de0f2743ce6d9c9ef7626cb1";
+  isLibrary = true;
+  isExecutable = false;
+  enableSeparateDataOutput = false;
+  libraryHaskellDepends = [ base ];
+  enableLibraryProfiling = true;
+  enableExecutableProfiling = true;
+  doHaddock = false;
+  jailbreak = true;
+  doCheck = false;
+  doBenchmark = false;
+  hyperlinkSource = false;
+  description = "Utilities for indexed profunctors";
+  license = lib.licenses.bsd3;
+  broken = false;
+}
\ No newline at end of file
diff --git a/pkgs/optics-core.nix b/pkgs/optics-core.nix
new file mode 100644
index 0000000000000000000000000000000000000000..de60b096407d78f468e111eff1b3da8aa9b4978c
--- /dev/null
+++ b/pkgs/optics-core.nix
@@ -0,0 +1,27 @@
+{ mkDerivation, array, base, containers, indexed-profunctors
+, indexed-traversable, lib, transformers
+}:
+mkDerivation {
+  pname = "optics-core";
+  version = "0.4.1";
+  sha256 = "ca64e215f31719482a9449b5d56fbd589367e639d2b1869f7965a3970442949a";
+  revision = "1";
+  editedCabalFile = "0sqwlbl6x0197bpkq7jvn9j5iwyr54z8qwmxbij6qlwjyfld2qxi";
+  isLibrary = true;
+  isExecutable = false;
+  enableSeparateDataOutput = false;
+  libraryHaskellDepends = [
+    array base containers indexed-profunctors indexed-traversable
+    transformers
+  ];
+  enableLibraryProfiling = true;
+  enableExecutableProfiling = true;
+  doHaddock = false;
+  jailbreak = true;
+  doCheck = false;
+  doBenchmark = false;
+  hyperlinkSource = false;
+  description = "Optics as an abstract interface: core definitions";
+  license = lib.licenses.bsd3;
+  broken = false;
+}
\ No newline at end of file
diff --git a/pkgs/optics-extra.nix b/pkgs/optics-extra.nix
new file mode 100644
index 0000000000000000000000000000000000000000..2337ee9916420edad4fa7b094229686eff6b49d7
--- /dev/null
+++ b/pkgs/optics-extra.nix
@@ -0,0 +1,29 @@
+{ mkDerivation, array, base, bytestring, containers, hashable
+, indexed-profunctors, indexed-traversable-instances, lib, mtl
+, optics-core, text, transformers, unordered-containers, vector
+}:
+mkDerivation {
+  pname = "optics-extra";
+  version = "0.4.2.1";
+  sha256 = "7e23a7a325e3448354614d3d958279c9ac2fdd0831ceee2808830e7a962fca41";
+  revision = "1";
+  editedCabalFile = "0bpr1bkb7mmww028n8ikwa0qhdl7ybxpb9s887dlp3dvxr5iq8nq";
+  isLibrary = true;
+  isExecutable = false;
+  enableSeparateDataOutput = false;
+  libraryHaskellDepends = [
+    array base bytestring containers hashable indexed-profunctors
+    indexed-traversable-instances mtl optics-core text transformers
+    unordered-containers vector
+  ];
+  enableLibraryProfiling = true;
+  enableExecutableProfiling = true;
+  doHaddock = false;
+  jailbreak = true;
+  doCheck = false;
+  doBenchmark = false;
+  hyperlinkSource = false;
+  description = "Extra utilities and instances for optics-core";
+  license = lib.licenses.bsd3;
+  broken = false;
+}
\ No newline at end of file
diff --git a/pkgs/optics-th.nix b/pkgs/optics-th.nix
new file mode 100644
index 0000000000000000000000000000000000000000..08bf7c2a6a9184637731e7f4d2ffe6dc093e1158
--- /dev/null
+++ b/pkgs/optics-th.nix
@@ -0,0 +1,28 @@
+{ mkDerivation, base, containers, lib, mtl, optics-core, tagged
+, template-haskell, th-abstraction, transformers
+}:
+mkDerivation {
+  pname = "optics-th";
+  version = "0.4.1";
+  sha256 = "d73857b79dcd8f7c7e70fa4727f134145b62902e8d3e448f8b25c38a9da4fd17";
+  revision = "4";
+  editedCabalFile = "0l9kafjxrqnkqqb2mdwc6rjhhyp7j5mabaxzmgq6fzl8cr9qbjfk";
+  isLibrary = true;
+  isExecutable = false;
+  enableSeparateDataOutput = false;
+  libraryHaskellDepends = [
+    base containers mtl optics-core template-haskell th-abstraction
+    transformers
+  ];
+  testHaskellDepends = [ base optics-core tagged ];
+  enableLibraryProfiling = true;
+  enableExecutableProfiling = true;
+  doHaddock = false;
+  jailbreak = true;
+  doCheck = false;
+  doBenchmark = false;
+  hyperlinkSource = false;
+  description = "Optics construction using TemplateHaskell";
+  license = lib.licenses.bsd3;
+  broken = false;
+}
\ No newline at end of file
diff --git a/pkgs/optics.nix b/pkgs/optics.nix
new file mode 100644
index 0000000000000000000000000000000000000000..35cea72775dc98a5a1d87dff5d77ed00a60188b4
--- /dev/null
+++ b/pkgs/optics.nix
@@ -0,0 +1,37 @@
+{ mkDerivation, QuickCheck, array, base, bytestring, containers
+, indexed-profunctors, inspection-testing, lens, lib, mtl
+, optics-core, optics-extra, optics-th, random, tasty, tasty-bench
+, tasty-hunit, tasty-quickcheck, template-haskell, transformers
+, unordered-containers, vector
+}:
+mkDerivation {
+  pname = "optics";
+  version = "0.4.2";
+  sha256 = "ebe7553704d3491f02777dc6f02a2cf170d4b87ce5265139ce759314460533c7";
+  isLibrary = true;
+  isExecutable = false;
+  enableSeparateDataOutput = false;
+  libraryHaskellDepends = [
+    array base containers mtl optics-core optics-extra optics-th
+    transformers
+  ];
+  testHaskellDepends = [
+    base containers indexed-profunctors inspection-testing mtl
+    optics-core QuickCheck random tasty tasty-hunit tasty-quickcheck
+    template-haskell
+  ];
+  benchmarkHaskellDepends = [
+    base bytestring containers lens tasty-bench transformers
+    unordered-containers vector
+  ];
+  enableLibraryProfiling = true;
+  enableExecutableProfiling = true;
+  doHaddock = false;
+  jailbreak = true;
+  doCheck = false;
+  doBenchmark = false;
+  hyperlinkSource = false;
+  description = "Optics as an abstract interface";
+  license = lib.licenses.bsd3;
+  broken = false;
+}
\ No newline at end of file