diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+- 0.2.3
+    - Add support for indexed `optics`
+    - Only support GHC-8.0+
+
 - 0.2.2
     - Add `Data.HashSet.InsOrd`
 
diff --git a/insert-ordered-containers.cabal b/insert-ordered-containers.cabal
--- a/insert-ordered-containers.cabal
+++ b/insert-ordered-containers.cabal
@@ -1,5 +1,5 @@
 name:               insert-ordered-containers
-version:            0.2.2
+version:            0.2.3
 synopsis:
   Associative containers retaining insertion order for traversals.
 
@@ -17,16 +17,7 @@
 license-file:       LICENSE
 build-type:         Simple
 cabal-version:      >=1.10
-tested-with:
-  GHC==7.6.3,
-  GHC==7.8.4,
-  GHC==7.10.3,
-  GHC==8.0.1,
-  GHC==8.2.2,
-  GHC==8.4.4,
-  GHC==8.6.5,
-  GHC==8.8.1
-
+tested-with:        GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.1
 extra-source-files:
   CHANGELOG.md
   README.md
@@ -40,16 +31,18 @@
   hs-source-dirs:   src
   ghc-options:      -Wall
   build-depends:
-      aeson                 >=1.4.2.0  && <1.5
-    , base                  >=4.6      && <4.13
-    , base-compat           >=0.10.5   && <0.11
-    , hashable              >=1.2.6.1  && <1.4
-    , lens                  >=4.17     && <4.18
-    , semigroupoids         >=5.3.2    && <5.4
-    , semigroups            >=0.18.5   && <0.20
-    , text                  >=1.2.3.0  && <1.3
-    , transformers          >=0.3.0.0  && <0.6
-    , unordered-containers  >=0.2.8.0  && <0.3
+      aeson                 >=1.4.2.0 && <1.5
+    , base                  >=4.9     && <4.14
+    , base-compat           >=0.10.5  && <0.12
+    , hashable              >=1.2.6.1 && <1.4
+    , lens                  >=4.17    && <4.19
+    , optics-core           >=0.2     && <0.3
+    , optics-extra          >=0.2     && <0.3
+    , semigroupoids         >=5.3.2   && <5.4
+    , semigroups            >=0.18.5  && <0.20
+    , text                  >=1.2.3.0 && <1.3
+    , transformers          >=0.5.2.0 && <0.6
+    , unordered-containers  >=0.2.8.0 && <0.3
 
   exposed-modules:
     Data.HashMap.Strict.InsOrd
@@ -72,14 +65,11 @@
     , hashable
     , insert-ordered-containers
     , lens
+    , QuickCheck                 >=2.13.2   && <2.14
     , semigroupoids
     , semigroups
+    , tasty                      >=0.10.1.2 && <1.3
+    , tasty-quickcheck           >=0.8.3.2  && <0.11
     , text
     , transformers
     , unordered-containers
-    , base
-    , insert-ordered-containers
-    , tasty             >= 0.10.1.2 && <1.3
-    , tasty-quickcheck  >= 0.8.3.2  && <0.11
-    , QuickCheck        >=2.7.6     && <2.14
-
diff --git a/src/Data/HashMap/InsOrd/Internal.hs b/src/Data/HashMap/InsOrd/Internal.hs
--- a/src/Data/HashMap/InsOrd/Internal.hs
+++ b/src/Data/HashMap/InsOrd/Internal.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE GADTs #-}
 module Data.HashMap.InsOrd.Internal where
 
-import Prelude        ()
+import Prelude ()
 import Prelude.Compat hiding (filter, foldr, lookup, map, null)
 
 import Control.Applicative ((<**>))
diff --git a/src/Data/HashMap/Strict/InsOrd.hs b/src/Data/HashMap/Strict/InsOrd.hs
--- a/src/Data/HashMap/Strict/InsOrd.hs
+++ b/src/Data/HashMap/Strict/InsOrd.hs
@@ -77,11 +77,7 @@
     valid,
     ) where
 
-#ifndef MIN_VERSION_aeson
-#define MIN_VERSION_aeson(x,y,z) 0
-#endif
-
-import Prelude        ()
+import Prelude ()
 import Prelude.Compat hiding (filter, foldr, lookup, map, null)
 
 import           Control.Applicative             (Const (..))
@@ -98,21 +94,23 @@
 import           Data.Ord                        (comparing)
 import           Data.Semigroup                  (Semigroup (..))
 import           Text.ParserCombinators.ReadPrec (prec)
-import           Text.Read                       (Lexeme (..), Read (..), lexP,
-                                                  parens, readListPrecDefault)
+import           Text.Read
+                 (Lexeme (..), Read (..), lexP, parens, readListPrecDefault)
 
-import Control.Lens                     (At (..), FoldableWithIndex (..),
-                                         FunctorWithIndex (..), Index, Iso, IxValue,
-                                         Ixed (..), TraversableWithIndex (..),
-                                         Traversal, iso, (<&>), _1, _2)
+import Control.Lens
+       (At (..), FoldableWithIndex (..), FunctorWithIndex (..), Index, Iso,
+       IxValue, Ixed (..), TraversableWithIndex (..), Traversal, iso, (<&>),
+       _1, _2)
 import Control.Monad.Trans.State.Strict (State, runState, state)
 
+import qualified Control.Lens as Lens
+import qualified Optics.At    as Optics
+import qualified Optics.Core  as Optics
+
 import           Data.HashMap.Strict (HashMap)
 import qualified Data.HashMap.Strict as HashMap
 
-#if MIN_VERSION_base(4,7,0)
 import qualified GHC.Exts as Exts
-#endif
 
 import Data.HashMap.InsOrd.Internal
 
@@ -184,11 +182,9 @@
     -- length = length . getInsOrdHashMap
     foldMap f = foldMap (f . snd) . toList
 
-#if MIN_VERSION_base(4,8,0)
     null = null
     toList = elems
     length = size
-#endif
 
 instance Traversable (InsOrdHashMap k) where
     traverse f m = traverseWithKey (\_ -> f) m
@@ -206,12 +202,10 @@
     hashWithSalt salt (InsOrdHashMap _ m) =
         hashWithSalt salt m
 
-#if MIN_VERSION_base(4,7,0)
 instance (Eq k, Hashable k) => Exts.IsList (InsOrdHashMap k v) where
     type Item (InsOrdHashMap k v) = (k, v)
     fromList = fromList
     toList   = toList
-#endif
 
 -------------------------------------------------------------------------------
 -- Aeson
@@ -246,11 +240,21 @@
 type instance IxValue (InsOrdHashMap k v) = v
 
 instance (Eq k, Hashable k) => Ixed (InsOrdHashMap k v) where
-    ix k f m = case lookup k m of
-         Just v  -> f v <&> \v' -> insert k v' m
-         Nothing -> pure m
+    ix k f m = ixImpl k pure f m
     {-# INLINABLE ix #-}
 
+ixImpl
+  :: (Eq k, Hashable k, Functor f)
+  => k
+  -> (InsOrdHashMap k v -> f (InsOrdHashMap k v))
+  -> (v -> f v)
+  -> InsOrdHashMap k v
+  -> f (InsOrdHashMap k v)
+ixImpl k point f m = case lookup k m of
+    Just v  -> f v <&> \v' -> insert k v' m
+    Nothing -> point m
+{-# INLINE ixImpl #-}
+
 instance (Eq k, Hashable k) => At (InsOrdHashMap k a) where
     at k f m = f mv <&> \r -> case r of
         Nothing -> maybe m (const (delete k m)) mv
@@ -271,6 +275,28 @@
 
 unorderedTraversal :: Traversal (InsOrdHashMap k a) (InsOrdHashMap k b) a b
 unorderedTraversal = hashMap . traverse
+
+-------------------------------------------------------------------------------
+-- Optics
+-------------------------------------------------------------------------------
+
+type instance Optics.Index (InsOrdHashMap k v) = k
+type instance Optics.IxValue (InsOrdHashMap k v) = v
+
+instance (Eq k, Hashable k) => Optics.Ixed (InsOrdHashMap k v) where
+    ix k = Optics.atraversalVL $ \point f m -> ixImpl k point f m
+    {-# INLINE ix #-}
+
+instance (Eq k, Hashable k) => Optics.At (InsOrdHashMap k a) where
+    at k = Optics.lensVL $ \f m -> Lens.at k f m
+    {-# INLINE at #-}
+
+instance (Eq k, Hashable k) => Optics.FunctorWithIndex k (InsOrdHashMap k) where
+    imap = mapWithKey
+instance (Eq k, Hashable k) => Optics.FoldableWithIndex k (InsOrdHashMap k) where
+    ifoldMap = foldMapWithKey
+instance (Eq k, Hashable k) => Optics.TraversableWithIndex k (InsOrdHashMap k) where
+    itraverse = traverseWithKey
 
 -------------------------------------------------------------------------------
 -- Construction
diff --git a/src/Data/HashSet/InsOrd.hs b/src/Data/HashSet/InsOrd.hs
--- a/src/Data/HashSet/InsOrd.hs
+++ b/src/Data/HashSet/InsOrd.hs
@@ -46,33 +46,32 @@
 import Prelude ()
 import Prelude.Compat hiding (filter, foldr, lookup, map, null)
 
-import           Control.Arrow                   (first)
-import           Data.Aeson
-import           Data.Data                       (Data, Typeable)
-import           Data.Hashable                   (Hashable (..))
-import           Data.List                       (nub, sortBy)
-import           Data.Ord                        (comparing)
-import           Data.Semigroup                  (Semigroup (..))
-import           Text.ParserCombinators.ReadPrec (prec)
-import           Text.Read
-                 (Lexeme (..), Read (..), lexP, parens, readListPrecDefault)
+import Control.Arrow                   (first)
+import Data.Aeson
+import Data.Data                       (Data, Typeable)
+import Data.Hashable                   (Hashable (..))
+import Data.List                       (nub, sortBy)
+import Data.Ord                        (comparing)
+import Data.Semigroup                  (Semigroup (..))
+import Text.ParserCombinators.ReadPrec (prec)
+import Text.Read
+       (Lexeme (..), Read (..), lexP, parens, readListPrecDefault)
 
 import Control.Lens
        (At (..), Contains (..), Index, Iso', IxValue, Ixed (..), iso, (<&>))
 import Control.Monad.Trans.State.Strict (State, runState, state)
 
+import qualified Control.Lens as Lens
+import qualified Optics.At    as Optics
+import qualified Optics.Core  as Optics
+
 import           Data.HashMap.Strict (HashMap)
 import qualified Data.HashMap.Strict as HashMap
 import           Data.HashSet        (HashSet)
 import qualified Data.HashSet        as HashSet
 
-#if MIN_VERSION_base(4,7,0)
 import qualified GHC.Exts as Exts
-#endif
-
-#if MIN_VERSION_base(4,8,0)
 import qualified Data.Foldable
-#endif
 
 import Data.HashMap.InsOrd.Internal
 
@@ -115,23 +114,19 @@
     -- length = length . getInsOrdHashSet
     foldMap f = foldMap f . toList
 
-#if MIN_VERSION_base(4,8,0)
     null = null
     toList = toList
     length = size
-#endif
 
 -- | @'hashWithSalt' salt . 'toHashSet' = 'hashWithSalt' salt@.
 instance Hashable k => Hashable (InsOrdHashSet k) where
     hashWithSalt salt (InsOrdHashSet _ m) =
         hashWithSalt salt m
 
-#if MIN_VERSION_base(4,7,0)
 instance (Eq k, Hashable k) => Exts.IsList (InsOrdHashSet k) where
     type Item (InsOrdHashSet k) = k
     fromList = fromList
     toList   = toList
-#endif
 
 -------------------------------------------------------------------------------
 -- Aeson
@@ -170,6 +165,26 @@
 -- | This is a slight lie, as roundtrip doesn't preserve ordering.
 hashSet :: Iso' (InsOrdHashSet a) (HashSet a)
 hashSet = iso toHashSet fromHashSet
+
+-------------------------------------------------------------------------------
+-- Optics
+-------------------------------------------------------------------------------
+
+type instance Optics.Index (InsOrdHashSet a) = a
+type instance Optics.IxValue (InsOrdHashSet a) = ()
+
+instance (Eq k, Hashable k) => Optics.Ixed (InsOrdHashSet k) where
+    ix k = Optics.atraversalVL $ \point f (InsOrdHashSet i m) ->
+      InsOrdHashSet i <$> Optics.toAtraversalVL (Optics.ix k) point (\j -> j <$ f ()) m
+    {-# INLINE ix #-}
+
+instance (Eq k, Hashable k) => Optics.At (InsOrdHashSet k) where
+    at k = Optics.lensVL $ \f m -> Lens.at k f m
+    {-# INLINE at #-}
+
+instance (Eq a, Hashable a) => Optics.Contains (InsOrdHashSet a) where
+    contains k = Optics.lensVL $ \f s -> Lens.contains k f s
+    {-# INLINE contains #-}
 
 -------------------------------------------------------------------------------
 -- Construction
