diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright konsumlamm (c) 2019
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of konsumlamm nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# extended-containers-lens
+
+[`lens`](https://hackage.haskell.org/package/lens) instances for [`extended-containers`](https://hackage.haskell.org/package/extended-containers).
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/extended-containers-lens.cabal b/extended-containers-lens.cabal
new file mode 100644
--- /dev/null
+++ b/extended-containers-lens.cabal
@@ -0,0 +1,40 @@
+name:                extended-containers-lens
+version:             0.1.0.0
+synopsis:            lens instances for extended-containers
+description:
+  This package contains orphan instances of lens classes for the container types from extended-containers.
+homepage:            https://github.com/konsumlamm/extended-containers-lens#readme
+bug-reports:         https://github.com/konsumlamm/extended-containers-lens/issues
+license:             BSD3
+license-file:        LICENSE
+author:              konsumlamm
+maintainer:          konsumlamm@gmail.com
+copyright:           2019 konsumlamm
+category:            Data Structures, Lenses
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >= 1.10
+tested-with:
+  GHC == 8.0.1,
+  GHC == 8.0.2,
+  GHC == 8.2.2,
+  GHC == 8.4.3,
+  GHC == 8.4.4,
+  GHC == 8.6.3,
+  GHC == 8.6.4,
+  GHC == 8.6.5,
+  GHC == 8.8.2,
+  GHC == 8.8.3
+
+library
+  hs-source-dirs:      src
+  exposed-modules:
+    Data.AMT.Lens
+    Data.Heap.Lens
+    Data.PrioHeap.Lens
+  ghc-options:         -Wall -Wno-orphans
+  build-depends:
+    base                >= 4.7 && < 5,
+    extended-containers >= 0.1 && < 0.2,
+    lens                >= 4.14 && < 5
+  default-language:    Haskell2010
diff --git a/src/Data/AMT/Lens.hs b/src/Data/AMT/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/AMT/Lens.hs
@@ -0,0 +1,90 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.AMT.Lens
+    ( vectorOf
+    ) where
+
+import Data.Foldable (toList)
+
+import Control.Lens.At (Ixed(..), Index, IxValue)
+import Control.Lens.Combinators (Getting, views)
+import Control.Lens.Cons (Cons(..), Snoc(..))
+import Control.Lens.Each (Each(..))
+import Control.Lens.Empty (AsEmpty(..))
+import Control.Lens.Indexed
+import Control.Lens.Iso (Reversing(..), iso)
+import Control.Lens.Operators ((<&>))
+import Control.Lens.Prism (nearly, prism)
+import Control.Lens.Traversal (traversed)
+import Control.Lens.Type (Getter, Fold, Traversal, Lens, Iso)
+import Control.Lens.Wrapped
+
+import qualified Data.AMT as V
+import Data.AMT (Vector)
+
+type instance Index (Vector a) = Int
+type instance IxValue (Vector a) = a
+
+instance Ixed (Vector a) where
+    ix i f v = case V.lookup i v of
+        Nothing -> pure v
+        Just x -> f x <&> \y -> V.update i y v
+
+instance Cons (Vector a) (Vector b) a b where
+    _Cons = prism (uncurry (V.<|)) $ \v -> case V.viewl v of
+        Nothing -> Left V.empty
+        Just x -> Right x
+
+instance Snoc (Vector a) (Vector b) a b where
+    _Snoc = prism (uncurry (V.|>)) $ \v -> case V.viewr v of
+        Nothing -> Left V.empty
+        Just x -> Right x
+
+instance Each (Vector a) (Vector b) a b where
+    each = traversed
+    {-# INLINE each #-}
+
+instance AsEmpty (Vector a) where
+    _Empty = nearly V.empty null
+
+instance FunctorWithIndex Int Vector where
+    imap = V.mapWithIndex
+    {-# INLINE imap #-}
+
+instance FoldableWithIndex Int Vector where
+    ifoldMap = V.foldMapWithIndex
+    {-# INLINE ifoldMap #-}
+
+    ifoldr = V.foldrWithIndex
+    {-# INLINE ifoldr #-}
+
+    ifoldl f = V.foldlWithIndex (flip f)
+    {-# INLINE ifoldl #-}
+
+    ifoldr' = V.foldrWithIndex'
+    {-# INLINE ifoldr' #-}
+
+    ifoldl' f = V.foldlWithIndex' (flip f)
+    {-# INLINE ifoldl' #-}
+
+
+instance TraversableWithIndex Int Vector where
+    itraverse = V.traverseWithIndex
+    {-# INLINE itraverse #-}
+
+instance Reversing (Vector a) where
+    reversing = V.fromList . reverse . toList
+
+instance Wrapped (Vector a) where
+    type Unwrapped (Vector a) = [a]
+
+    _Wrapped' = iso toList V.fromList
+    {-# INLINE _Wrapped' #-}
+
+instance (t ~ Vector a') => Rewrapped (Vector a) t
+
+-- | Construct a 'Vector' from a 'Getter', 'Fold', 'Traversal', 'Lens' or 'Iso'.
+vectorOf :: Getting (Vector a) s a -> s -> Vector a
+vectorOf l = views l V.singleton
diff --git a/src/Data/Heap/Lens.hs b/src/Data/Heap/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Heap/Lens.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.Heap.Lens
+    ( heapOf
+    ) where
+
+import Data.Foldable (toList)
+
+import Control.Lens.Combinators (Getting, views)
+import Control.Lens.Empty (AsEmpty(..))
+import Control.Lens.Iso (iso)
+import Control.Lens.Prism (nearly)
+import Control.Lens.Type (Getter, Fold, Traversal, Lens, Iso)
+import Control.Lens.Wrapped
+
+import qualified Data.Heap as H
+import Data.Heap (Heap)
+
+instance AsEmpty (Heap a) where
+    _Empty = nearly H.empty null
+
+instance Ord a => Wrapped (Heap a) where
+    type Unwrapped (Heap a) = [a]
+
+    _Wrapped' = iso toList H.fromList
+    {-# INLINE _Wrapped' #-}
+
+-- | Use @'wrapping' 'H.fromList'@. Unwrapping returns some permutation of the list.
+instance (t ~ Heap a', Ord a) => Rewrapped (Heap a) t
+
+-- | Construct a 'Heap' from a 'Getter', 'Fold', 'Traversal', 'Lens' or 'Iso'.
+heapOf :: Getting (Heap a) s a -> s -> Heap a
+heapOf l = views l H.singleton
diff --git a/src/Data/PrioHeap/Lens.hs b/src/Data/PrioHeap/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/PrioHeap/Lens.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Data.PrioHeap.Lens
+    ( prioHeapOf
+    ) where
+
+import Data.Ord (Down(..))
+
+import Control.Lens.Combinators (IndexedGetting, iviews)
+import Control.Lens.Each (Each(..))
+import Control.Lens.Empty (AsEmpty(..))
+import Control.Lens.Indexed
+import Control.Lens.Iso (iso)
+import Control.Lens.Operators ((<&>))
+import Control.Lens.Prism (nearly)
+import Control.Lens.Traversal
+import Control.Lens.Type (IndexedGetter, IndexedFold, IndexedTraversal, IndexedLens)
+import Control.Lens.Wrapped
+
+import qualified Data.PrioHeap as H
+import Data.PrioHeap (PrioHeap)
+
+instance (c ~ d) => Each (PrioHeap c a) (PrioHeap d b) a b where
+    each = traversed
+    {-# INLINE each #-}
+
+instance AsEmpty (PrioHeap k a) where
+    _Empty = nearly H.empty null
+
+instance FunctorWithIndex k (PrioHeap k) where
+    imap = H.mapWithKey
+    {-# INLINE imap #-}
+
+instance FoldableWithIndex k (PrioHeap k) where
+    ifoldMap = H.foldMapWithKey
+    {-# INLINE ifoldMap #-}
+
+    ifoldr = H.foldrWithKey
+    {-# INLINE ifoldr #-}
+
+    ifoldl f = H.foldlWithKey (flip f)
+    {-# INLINE ifoldl #-}
+
+    ifoldr' = H.foldrWithKey'
+    {-# INLINE ifoldr' #-}
+
+    ifoldl' f = H.foldlWithKey' (flip f)
+    {-# INLINE ifoldl' #-}
+
+
+instance TraversableWithIndex k (PrioHeap k) where
+    itraverse = H.traverseWithKey
+    {-# INLINE itraverse #-}
+
+instance Ord k => TraverseMin k (PrioHeap k) where
+    traverseMin f heap = case H.lookupMin heap of
+        Nothing -> pure heap
+        Just (key, x) -> indexed f key x <&> \y -> H.adjustMin (const y) heap
+
+-- TODO: TraverseMax instance for PrioHeap (Down k)?
+instance Ord k => TraverseMax k (PrioHeap (Down k)) where
+    traverseMax f heap = case H.lookupMin heap of
+        Nothing -> pure heap
+        Just (Down key, x) -> indexed f key x <&> \y -> H.adjustMin (const y) heap
+
+instance Ord k => Wrapped (PrioHeap k a) where
+    type Unwrapped (PrioHeap k a) = [(k, a)]
+
+    _Wrapped' = iso H.toList H.fromList
+    {-# INLINE _Wrapped' #-}
+
+-- | Use @'wrapping' 'H.fromList'@. Unwrapping returns some permutation of the list.
+instance (t ~ PrioHeap k' a', Ord k) => Rewrapped (PrioHeap k a) t
+
+-- | Construct a PrioHeap from a 'IndexedGetter', 'IndexedFold', 'IndexedTraversal' or 'IndexedLens'.
+prioHeapOf :: IndexedGetting k (PrioHeap k a) s a -> s -> PrioHeap k a
+prioHeapOf l = iviews l H.singleton
