diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+# Changelog for opticus-prime
+
+## Unreleased changes
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2020
+
+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 Author name here 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,21 @@
+# Trek
+
+Provides a generic monadic interface for diving through and updating arbitrary structures.
+
+It takes inspiration from:
+
+* [jq](https://stedolan.github.io/jq/manual/)
+* [meander](https://github.com/noprompt/meander)
+* [XQuery](https://en.wikipedia.org/wiki/XQuery)
+
+## Elevator Pitch
+
+Trek allows you to dive down into nested structures while keeping handles on relevant bits as you go.
+
+You can then transform the structure, collect results, etc.
+
+Trek implicitly handles the idea of missing or multiple values for you, meaning you can write your collections or transformations declaratively.
+
+## `trek-lens`
+
+There's an extension to trek: `trek-lens` which I highly recommend using. It provides the `focusing` combinator which gives Trek a LOT more power. Trek is meant to be used alongside optics.
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/src/Trek.hs b/src/Trek.hs
new file mode 100644
--- /dev/null
+++ b/src/Trek.hs
@@ -0,0 +1,143 @@
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE DerivingVia #-}
+module Trek
+    (
+
+    -- * Types
+    TrekT(..)
+    , Trek
+
+    -- * Combinators
+    , select
+    , selectEach
+    , iter
+    , collect
+    , mount
+    , mountEach
+    , with
+    , withEach
+
+    -- * Running Trek
+    , evalTrek
+    , evalTrekT
+    , execTrek
+    , execTrekT
+    , runTrek
+    , runTrekT
+
+    -- * Re-Exports
+    , get
+    , gets
+    , put
+    , modify
+    , ask
+    , asks
+    ) where
+
+import Control.Applicative
+import Control.Monad.Fail
+import Control.Monad.Identity
+import Control.Monad.Logic
+import Control.Monad.Reader
+import Control.Monad.State
+import Data.Foldable
+import Data.Functor.Identity
+import Data.Monoid
+
+-- | Pure Trek Monad
+type Trek s a = TrekT s Identity a
+
+-- | The Trek Monad Transformer.
+-- Implements both MonadReader and MonadState.
+newtype TrekT s m a = TrekT (LogicT (StateT s m) a)
+  deriving newtype (Functor, Applicative, Monad, MonadState s, Alternative, MonadFail)
+  deriving (Semigroup, Monoid) via Ap (LogicT (StateT s m)) a
+
+instance MonadTrans (TrekT s) where
+  lift m = TrekT (lift . lift $ m)
+
+instance (Monad m) => MonadReader s (TrekT s m) where
+  ask = get
+  local f m = do
+      s <- get
+      modify f
+      a <- m
+      put s
+      pure a
+
+
+-- | Get a value from your state
+select :: Monad m => (s -> a) -> TrekT s m a
+select getter = gets getter
+
+-- | Iterate over several values from your state. An alias for @'select' >=> 'iter'@
+selectEach :: (Monad m, Foldable f) => (s -> f a) -> TrekT s m a
+selectEach getter = select getter >>= iter
+
+-- | Iterate over each of the provided values one at a time.
+iter :: Foldable f => f a -> TrekT s m a
+iter = asum . fmap pure . toList
+
+-- | Run a full 'TrekT' block collecting all results into a list
+collect :: Monad m => TrekT s m a -> TrekT s m [a]
+collect trek = do
+    s <- get
+    lift . fmap fst $ runTrekT trek s
+
+-- | Run a 'TrekT' block over a portion of state. All state changes from the block are
+-- discarded.
+mount :: Monad m => (t -> s) -> TrekT s m a -> TrekT t m a
+mount f trek = do
+    s <- select f
+    with s trek
+
+-- | Like 'mount' but focuses each of a list of values one at a time.
+-- All state changes from the block are discarded.
+mountEach :: (Monad m, Foldable f) => (t -> f s) -> TrekT s m a -> TrekT t m a
+mountEach f trek = do
+    s <- selectEach f
+    with s trek
+
+-- | Run a 'TrekT' block over a piece of state.
+-- All state changes from the block are discarded.
+with :: Monad m => s -> TrekT s m a -> TrekT t m a
+with s = mount (const s)
+
+-- | Like 'with' but focuses each of a list of values one at a time.
+-- All state changes from the block are discarded.
+withEach :: (Monad m, Foldable f) => f s -> TrekT s m a -> TrekT t m a
+withEach xs trek =
+    iter xs >>= flip with trek
+
+-- | Evaluate the results of a 'Trek'.
+evalTrek :: Trek s a -> s -> [a]
+evalTrek t s = runIdentity $ evalTrekT t s
+
+-- | Evaluate the results of a 'TrekT'.
+evalTrekT :: Monad m => TrekT s m a -> s -> m [a]
+evalTrekT t s = fst <$> runTrekT t s
+
+-- | Return the altered state after running a 'Trek'.
+execTrek :: Trek s a -> s -> s
+execTrek t s = runIdentity $ execTrekT t s
+
+-- | Return the altered state after running a 'TrekT'.
+execTrekT :: Monad m => TrekT s m a -> s -> m s
+execTrekT t s = snd <$> runTrekT t s
+
+-- | Run a 'Trek'
+runTrek :: Trek s a -> s -> ([a], s)
+runTrek t s = runIdentity $ runTrekT t s
+
+-- | Run a 'TrekT'
+runTrekT :: Monad m => TrekT s m a -> s -> m ([a], s)
+runTrekT (TrekT m) s = flip runStateT s $ observeAllT m
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
diff --git a/trek.cabal b/trek.cabal
new file mode 100644
--- /dev/null
+++ b/trek.cabal
@@ -0,0 +1,54 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.33.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 6c8c0450d245d5ee31c6c3de323a2d8755a133416129451b6f29266dded9f7d9
+
+name:           trek
+version:        0.0.1.0
+description:    Please see the README on GitHub at <https://github.com/githubuser/trek#readme>
+homepage:       https://github.com/githubuser/trek#readme
+bug-reports:    https://github.com/githubuser/trek/issues
+author:         Author name here
+maintainer:     example@example.com
+copyright:      2020 Author name here
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+source-repository head
+  type: git
+  location: https://github.com/githubuser/trek
+
+library
+  exposed-modules:
+      Trek
+  other-modules:
+      Paths_trek
+  hs-source-dirs:
+      src
+  build-depends:
+      base >=4.7 && <5
+    , logict
+    , mtl
+  default-language: Haskell2010
+
+test-suite trek-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_trek
+  hs-source-dirs:
+      test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      base >=4.7 && <5
+    , logict
+    , mtl
+    , trek
+  default-language: Haskell2010
