diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Changelog
+
+`fused-effects-optics` uses [PVP Versioning][1].
+The changelog is available [on GitHub][2].
+
+## 0.0.1.0
+
+* Initially created.
+
+[1]: https://pvp.haskell.org
+[2]: https://github.com/fused-effects/fused-effects-optics/releases
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2020, Patrick Thomson
+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 the copyright holder nor the names of its
+  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 HOLDER 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,11 @@
+# fused-effects-optics
+
+[![Hackage](https://img.shields.io/hackage/v/fused-effects-optics.svg)](https://hackage.haskell.org/package/fused-effects-optics)
+[![BSD3 license](https://img.shields.io/badge/license-BSD3-blue.svg)](LICENSE)
+[![Build Status](https://action-badges.now.sh/fused-effects/fused-effects-optics)](https://github.com/fused-effects/fused-effects-optics/actions)
+
+This package provides an interface to the [`optics`](https://github.com/well-typed/optics) library compatible with [`fused-effects`](https://github.com/robrix/fused-effects). The combinators provided by `optics-extra` for operating in monadic contexts—`gview`, `use`, `.=`, &c.—rely on `mtl` for `MonadState` and `MonadReader`, which is not applicable to `Reader` and `State` effects.
+
+## License
+
+BSD3, like `fused-effects`.
diff --git a/fused-effects-optics.cabal b/fused-effects-optics.cabal
new file mode 100644
--- /dev/null
+++ b/fused-effects-optics.cabal
@@ -0,0 +1,44 @@
+cabal-version:       2.2
+name:                fused-effects-optics
+version:             0.1.0.0
+synopsis:            Bridge between the optics and fused-effects ecosystems.
+description:         Provides combinators for the optics-based manipulation of state and context types provided by the fused-effects library, similar to those provided by optics-extra for mtl-based monad transformers.
+homepage:            https://github.com/fused-effects/fused-effects-optics
+bug-reports:         https://github.com/fused-effects/fused-effects-optics/issues
+license:             BSD-3-Clause
+license-file:        LICENSE
+author:              Patrick Thomson
+maintainer:          patrick.william.thomson@gmail.com
+copyright:           2020 Patrick Thomson
+category:            Control
+build-type:          Simple
+extra-doc-files:     README.md
+                   , CHANGELOG.md
+tested-with:         GHC == 8.8.3
+                     GHC == 8.10.1
+
+source-repository head
+  type:                git
+  location:            https://github.com/fused-effects/fused-effects-optics.git
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Control.Effect.Optics
+
+
+  build-depends:       base >= 4.12 && < 4.15
+                     , fused-effects >= 1 && < 1.2
+                     , optics-core >= 0.3
+
+  ghc-options:         -Wall
+                       -Wincomplete-uni-patterns
+                       -Wincomplete-record-updates
+                       -Wcompat
+                       -Widentities
+                       -Wredundant-constraints
+                       -fhide-source-paths
+                       -Wmissing-export-lists
+                       -Wpartial-fields
+                       -Wmissing-deriving-strategies
+
+  default-language:    Haskell2010
diff --git a/src/Control/Effect/Optics.hs b/src/Control/Effect/Optics.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Effect/Optics.hs
@@ -0,0 +1,160 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+
+module Control.Effect.Optics
+  ( -- * Reader operations
+    eview,
+    eviews,
+    -- * State operations
+    use,
+    uses,
+    preuse,
+    assign,
+    modifying,
+    -- * Infix operators
+    (.=),
+    (?=),
+    (%=),
+  )
+where
+
+import Control.Effect.Reader as Reader
+import Control.Effect.State as State
+import Optics.Core
+
+-- | View the target of a 'Lens', 'Iso', or 'Getter' in the current context.
+--
+-- This function is prefixed so as not to collide with 'Optics.Core.view'.
+--
+eview ::
+  forall r a m sig k is.
+  ( Is k A_Getter,
+    Has (Reader.Reader r) sig m
+  ) =>
+  Optic' k is r a ->
+  m a
+eview l = Reader.asks (view l)
+{-# INLINE eview #-}
+
+-- | Apply a function to the target of a 'Lens', 'Iso', or 'Getter' in the current context.
+eviews ::
+  forall r a b m sig k is.
+  ( Is k A_Getter,
+    Has (Reader.Reader r) sig m
+  ) =>
+  Optic' k is r a ->
+  (a -> b) ->
+  m b
+eviews l f = Reader.asks (f . view l)
+{-# INLINE eviews #-}
+
+-- | Use the target of a 'Lens', 'Iso', or 'Getter' in the current state.
+use ::
+  forall s a m sig k is.
+  ( Is k A_Getter,
+    Has (State.State s) sig m
+  ) =>
+  Optic' k is s a ->
+  m a
+use l = State.gets (view l)
+{-# INLINE use #-}
+
+-- | Apply a function to the target of a 'Lens', 'Iso', or 'Getter' in the current state.
+uses ::
+  forall s a b m sig k is.
+  ( Is k A_Getter,
+    Has (State.State s) sig m
+  ) =>
+  Optic' k is s a ->
+  (a -> b) ->
+  m b
+uses l f = State.gets (f . view l)
+{-# INLINE uses #-}
+
+-- | Use the target of a 'AffineTraversal' or 'AffineFold' in the current state.
+preuse ::
+  forall s a m sig k is.
+  ( Is k An_AffineFold,
+    Has (State.State s) sig m
+  ) =>
+  Optic' k is s a ->
+  m (Maybe a)
+preuse l = State.gets (preview l)
+{-# INLINE preuse #-}
+
+-- | Replace the target(s) of an Optic in our monadic state with a new value, irrespective of the old.
+-- The action and the optic operation are applied strictly.
+--
+-- This is aprefix form of '.='.
+assign ::
+  forall s a b m sig k is.
+  ( Is k A_Setter,
+    Has (State.State s) sig m
+  ) =>
+  Optic k is s s a b ->
+  b ->
+  m ()
+assign l x = State.modify (set' l x)
+{-# INLINE assign #-}
+
+-- | Map over the target(s) of an 'Optic' in our monadic state.
+-- The action and the optic operation are applied strictly.
+modifying ::
+  ( Is k A_Setter,
+    Has (State.State s) sig m
+  ) =>
+  Optic k is s s a b ->
+  (a -> b) ->
+  m ()
+modifying l x = State.modify (over' l x)
+{-# INLINE modifying #-}
+
+-- * Operators
+
+infix 4 .=
+
+infix 4 ?=
+
+infix 4 %=
+
+-- | Replace the target(s) of an Optic in our monadic state with a new value, irrespective of the old.
+-- The action and the optic operation are applied strictly.
+--
+-- This is an infix form of 'assign'.
+(.=) ::
+  forall s a b m sig k is.
+  ( Is k A_Setter,
+    Has (State.State s) sig m
+  ) =>
+  Optic k is s s a b ->
+  b ->
+  m ()
+(.=) = assign
+{-# INLINE (.=) #-}
+
+-- | Replace the target(s) of an Optic in our monadic state with 'Just' a new value, irrespective of the old.
+-- The action and the optic operation are applied strictly.
+(?=) ::
+  forall s a b m sig k is.
+  ( Is k A_Setter,
+    Has (State.State s) sig m
+  ) =>
+  Optic k is s s a (Maybe b) ->
+  b ->
+  m ()
+l ?= a = State.modify (set l (Just a))
+{-# INLINE (?=) #-}
+
+-- | Map over the target(s) of an 'Optic' in our monadic state.
+-- The action and the optic operation are applied strictly.
+(%=) ::
+  ( Is k A_Setter,
+    Has (State.State s) sig m
+  ) =>
+  Optic k is s s a b ->
+  (a -> b) ->
+  m ()
+(%=) = modifying
+{-# INLINE (%=) #-}
