diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,20 @@
+# Changelog
+
+All notable changes to `effectful-opaleye` will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Haskell Package Versioning Policy](https://pvp.haskell.org).
+
+## [Unreleased]
+
+## [0.1.0.0] - 22.07.2025
+
+### Added
+
+- First edition of the package, ready for feedback.
+- 100% documentation coverage.
+- Reasonably detailed READMEs.
+- CI that builds and tests the packages for each version of GHC in the `tested-with` field.
+
+[unreleased]: https://github.com/fpringle/effectful-postgresql/compare/v0.1.0.0...HEAD
+[0.1.0.0]: https://github.com/fpringle/effectful-postgresql/releases/tag/v0.1.0.0
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2025, Frederick Pringle
+
+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 Frederick Pringle 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,49 @@
+# effectful-opaleye
+
+This package provides an `effectful` effect for [Opaleye](https://hackage.haskell.org/package/opaleye) operations.
+
+It combines the very safe, high-level syntax of Opaleye, with the `WithConnection` abstraction of [effectful-postgresql](https://github.com/fpringle/effectful-postgresql/blob/main/effectful-postgresql#readme).
+
+## Effectful functions
+
+In the `Opaleye` effect we can perform the 4 main operations permitted by Opaleye: query, insert, delete, and update.
+
+```haskell
+{-# LANGUAGE Arrows #-}
+import Control.Arrow
+import Effectful.Opaleye as EO
+import qualified Opaleye as O
+
+insertAndList :: (EO.Opaleye :> es) => Eff es [User]
+insertAndList = do
+  EO.runInsert $ O.Insert userTable [User {firstName = "Nuala"}] O.rCount Nothing
+
+  EO.runDelete $ O.Delete userTable isAdmin O.rCount
+
+  EO.runUpdate $ O.Update userTable (\user -> user {updatedAt = O.now}) isAdmin O.rCount
+
+  EO.runSelect $ proc () -> do
+    user <- O.selectTable userTable -< ()
+    O.restrict -< firstName user `O.in_` (O.toFields <$> ["Anna", "Boris", "Carla"])
+    returnA -< user
+```
+
+## Interpreters
+
+To run the `Opaleye` effect we can use the `WithConnection` effect from [effectful-postgresql](https://github.com/fpringle/effectful-postgresql/blob/main/effectful-postgresql#readme):
+
+```haskell
+import Effectful.PostgreSQL as EP
+import Effectful.Opaleye as EO
+
+doOpaleyeStuff :: (WithConnection :> es) => Eff es [User]
+doOpaleyeStuff = EO.runOpaleyeWithConnection insertAndList
+```
+
+The `WithConnection` effect can then be dispatched using one of its [interpreters](https://github.com/fpringle/effectful-postgresql/blob/main/effectful-postgresql#interpreters).
+Or, to skip that entirely, we can just use `runOpaleyeConnection`:
+
+```haskell
+doOpaleyeStuff :: PSQL.Connection -> Eff es [User]
+doOpaleyeStuff conn = EO.runOpaleyeConnection conn insertAndList
+```
diff --git a/effectful-opaleye.cabal b/effectful-opaleye.cabal
new file mode 100644
--- /dev/null
+++ b/effectful-opaleye.cabal
@@ -0,0 +1,65 @@
+cabal-version:      3.0
+name:               effectful-opaleye
+version:            0.1.0.0
+synopsis:
+  effectful support for high-level PostgreSQL operations via Opaleye.
+description:
+  See the README for an overview, or the documentation in 'Effectful.Opaleye'.
+license:            BSD-3-Clause
+license-file:       LICENSE
+author:             Frederick Pringle
+maintainer:         frederick.pringle@fpringle.com
+copyright:          Copyright(c) Frederick Pringle 2025
+homepage:           https://github.com/fpringle/effectful-postgresql
+build-type:         Simple
+category:           Database
+extra-doc-files:    README.md
+                    CHANGELOG.md
+
+tested-with:
+    GHC == 8.8.4
+  , GHC == 8.10.7
+  , GHC == 9.0.2
+  , GHC == 9.2.4
+  , GHC == 9.2.8
+  , GHC == 9.4.2
+  , GHC == 9.4.5
+  , GHC == 9.6.1
+  , GHC == 9.6.7
+  , GHC == 9.8.2
+  , GHC == 9.10.2
+
+common warnings
+  ghc-options: -Wall -Wno-unused-do-bind -Wunused-packages
+
+common deps
+  build-depends:
+    , base >= 4 && < 5
+    , effectful-core >= 2.3 && < 2.6
+    , effectful-th >= 1.0.0.1 && < 1.0.1
+    , opaleye >= 0.9 && < 0.11
+    , product-profunctors >= 0.9 && < 0.12
+    , effectful-postgresql >= 0.1 && < 0.2
+    , postgresql-simple >= 0.7 && < 0.8
+
+common extensions
+  default-extensions:
+    DataKinds
+    FlexibleContexts
+    GADTs
+    LambdaCase
+    ScopedTypeVariables
+    TypeApplications
+    TypeFamilies
+    TypeOperators
+
+library
+  import:
+      warnings
+    , deps
+    , extensions
+  exposed-modules:
+      Effectful.Opaleye
+  -- other-extensions:
+  hs-source-dirs:   src
+  default-language: Haskell2010
diff --git a/src/Effectful/Opaleye.hs b/src/Effectful/Opaleye.hs
new file mode 100644
--- /dev/null
+++ b/src/Effectful/Opaleye.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module Effectful.Opaleye
+  ( -- * Effect
+    Opaleye (..)
+
+    -- * Effectful functions
+
+    -- ** Select
+  , runSelect
+  , runSelectI
+  , runSelectExplicit
+
+    -- ** Select-fold
+  , runSelectFold
+  , runSelectFoldExplicit
+
+    -- ** Insert
+  , runInsert
+
+    -- ** Delete
+  , runDelete
+
+    -- ** Update
+  , runUpdate
+
+    -- * Interpreters
+  , runOpaleyeWithConnection
+  , runOpaleyeConnection
+  )
+where
+
+import Data.Profunctor.Product.Default
+import qualified Database.PostgreSQL.Simple as PSQL
+import Effectful
+import Effectful.Dispatch.Dynamic
+import qualified Effectful.PostgreSQL.Connection as Conn
+import Effectful.TH
+import qualified Opaleye as O
+import qualified Opaleye.Internal.Inferrable as O
+
+-- | A dynamic effect to perform @opaleye@ operations.
+data Opaleye :: Effect where
+  -- | Lifted 'O.RunSelectExplicit'.
+  RunSelectExplicit :: O.FromFields fields haskells -> O.Select fields -> Opaleye m [haskells]
+  -- | Lifted 'O.RunSelectFoldExplicit'.
+  RunSelectFoldExplicit ::
+    O.FromFields fields haskells ->
+    O.Select fields ->
+    b ->
+    (b -> haskells -> m b) ->
+    Opaleye m b
+  -- | Lifted 'O.RunInsert'.
+  RunInsert :: O.Insert haskells -> Opaleye m haskells
+  -- | Lifted 'O.RunDelete'.
+  RunDelete :: O.Delete haskells -> Opaleye m haskells
+  -- | Lifted 'O.RunUpdate'.
+  RunUpdate :: O.Update haskells -> Opaleye m haskells
+
+makeEffect ''Opaleye
+
+-- | Lifted 'O.runSelect'.
+runSelect ::
+  (HasCallStack, Opaleye :> es, Default O.FromFields fields haskells) =>
+  O.Select fields ->
+  Eff es [haskells]
+runSelect = runSelectExplicit def
+
+-- | Lifted 'O.runSelectFold'.
+runSelectFold ::
+  (HasCallStack, Opaleye :> es, Default O.FromFields fields haskells) =>
+  O.Select fields ->
+  b ->
+  (b -> haskells -> Eff es b) ->
+  Eff es b
+runSelectFold = runSelectFoldExplicit def
+
+-- | Lifted 'O.runSelectI'.
+runSelectI ::
+  (HasCallStack, Opaleye :> es, Default (O.Inferrable O.FromFields) fields haskells) =>
+  O.Select fields ->
+  Eff es [haskells]
+runSelectI = runSelectExplicit (O.runInferrable def)
+
+{- | Interpret the 'Opaleye' effect using 'Conn.WithConnection' from
+[effectful-postgresql](https://hackage.haskell.org/package/effectful-postgresql).
+
+If you don't want to use 'Conn.WithConnection', see 'runOpaleyeConnection'.
+-}
+runOpaleyeWithConnection ::
+  (HasCallStack, Conn.WithConnection :> es, IOE :> es) =>
+  Eff (Opaleye : es) a ->
+  Eff es a
+runOpaleyeWithConnection = interpret $ \env -> \case
+  RunSelectExplicit ff sel -> Conn.withConnection $ \conn -> liftIO $ O.runSelectExplicit ff conn sel
+  RunSelectFoldExplicit ff sel initial foldFn ->
+    Conn.withConnection $ \conn ->
+      localSeqUnliftIO env $ \unlift ->
+        liftIO $ O.runSelectFoldExplicit ff conn sel initial (\acc new -> unlift $ foldFn acc new)
+  RunInsert sel -> Conn.withConnection $ \conn -> liftIO $ O.runInsert conn sel
+  RunDelete sel -> Conn.withConnection $ \conn -> liftIO $ O.runDelete conn sel
+  RunUpdate sel -> Conn.withConnection $ \conn -> liftIO $ O.runUpdate conn sel
+
+-- | Interpret the 'Opaleye' effect by simply supplying a 'PSQL.Connection'
+runOpaleyeConnection ::
+  (HasCallStack, IOE :> es) =>
+  PSQL.Connection ->
+  Eff (Opaleye : es) a ->
+  Eff es a
+runOpaleyeConnection conn = interpret $ \env -> \case
+  RunSelectExplicit ff sel -> liftIO $ O.runSelectExplicit ff conn sel
+  RunSelectFoldExplicit ff sel initial foldFn ->
+    localSeqUnliftIO env $ \unlift ->
+      liftIO $ O.runSelectFoldExplicit ff conn sel initial (\acc new -> unlift $ foldFn acc new)
+  RunInsert sel -> liftIO $ O.runInsert conn sel
+  RunDelete sel -> liftIO $ O.runDelete conn sel
+  RunUpdate sel -> liftIO $ O.runUpdate conn sel
