diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) Keegan McAllister 2010
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. 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.
+3. Neither the name of the author nor the names of his 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 AUTHORS 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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,4 @@
+#! /usr/bin/runhaskell
+
+import Distribution.Simple
+main = defaultMain
diff --git a/Text/JSONb/Path.hs b/Text/JSONb/Path.hs
new file mode 100644
--- /dev/null
+++ b/Text/JSONb/Path.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE
+    PatternGuards #-}
+-- | Extract substructures from JSON structures by following a path.
+module Text.JSONb.Path(
+  -- * Building selectors
+    Selector
+  , key
+  , idx
+
+  -- * Building paths
+  , Path(..)
+
+  -- * Using paths
+  , get
+  , getOne) where
+
+import Data.Maybe
+import qualified Data.Trie            as T
+import qualified Text.JSONb           as J
+import qualified Data.ByteString      as B
+import qualified Data.ByteString.UTF8 as U8
+
+-- | Selects an element from a collection. Abstract.
+data Selector
+  = Key B.ByteString
+  | Idx Int
+
+-- | Select from an @Object@ by key.
+key :: String -> Selector
+key = Key . U8.fromString
+
+-- | Select from an @Array@ by index.
+idx :: Int -> Selector
+idx = Idx
+
+infixr 7 :=>
+
+-- | A @'Path'@ is used to traverse a @JSON@ structure and yield
+-- zero or more substructures.
+data Path
+  = Fail               -- ^ Yield nothing.
+  | Yield              -- ^ Yield this structure.
+  | Selector :=> Path  -- ^ Select an element and continue on some path.
+  | All Path           -- ^ Follow a path for each @Array@ element.
+
+  | Compute (J.JSON -> Path) -- ^ Choose a path programmatically.
+
+-- | Follow a path to get all matching substructures.
+get :: Path -> J.JSON -> [J.JSON]
+
+get Fail  _ = []
+get Yield x = [x]
+
+get (Key k :=> p) (J.Object t) | Just x <- T.lookup k t = get p x
+get (Key _ :=> _) _ = []
+
+get (Idx i :=> p) (J.Array xs) | (_, (y:_)) <- splitAt i xs = get p y
+get (Idx _ :=> _) _ = []
+
+get (All p) (J.Array xs) = concatMap (get p) xs
+get (All _) _ = []
+
+get (Compute f) j = get (f j) j
+
+-- | Follow a path to get the first matching substructure.
+getOne :: Path -> J.JSON -> Maybe J.JSON
+getOne p = listToMaybe . get p
diff --git a/jspath.cabal b/jspath.cabal
new file mode 100644
--- /dev/null
+++ b/jspath.cabal
@@ -0,0 +1,26 @@
+name:                jspath
+version:             0.1
+license:             BSD3
+license-file:        LICENSE
+synopsis:            Extract substructures from JSON by following a path.
+category:            Text
+author:              Keegan McAllister <mcallister.keegan@gmail.com>
+maintainer:          Keegan McAllister <mcallister.keegan@gmail.com>
+build-type:          Simple
+cabal-version:       >=1.2
+description:
+  Use this library to extract substructures from JSON structures by following a
+  path.  Path components can select elements by key or index, map over arrays,
+  or invoke user-specified functions.  Works with JSONb types.
+  .
+  Suggestions and patches are welcome.
+
+library
+  exposed-modules:   Text.JSONb.Path
+  ghc-options:       -Wall
+  build-depends:
+      base            >= 3 && < 5
+    , JSONb           >= 1.0
+    , utf8-string     >= 0.3
+    , bytestring      >= 0.9
+    , bytestring-trie >= 0.1.4
