diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2017
+
+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,1 @@
+# servant-side-loaded
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/servant-zeppelin.cabal b/servant-zeppelin.cabal
new file mode 100644
--- /dev/null
+++ b/servant-zeppelin.cabal
@@ -0,0 +1,37 @@
+name:                servant-zeppelin
+version:             0.1.0.0
+homepage:            https://github.com/martyall/servant-zeppelin#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Martin Allen, Ben Weitzman
+maintainer:          martin[dot]allen26[at]gmail.com
+copyright:           2017 Martin Allen, Ben Weitzman
+synopsis:            Types and definitions of servant-zeppelin combinators.
+category:            Web
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Servant.Zeppelin
+                     , Servant.Zeppelin.Internal.Types
+  build-depends:       base >= 4.7 && < 5
+                     , singletons
+  default-language:    Haskell2010
+  default-extensions:  GADTs
+                     , KindSignatures
+                     , FlexibleInstances
+                     , PolyKinds
+                     , DataKinds
+                     , TypeOperators
+                     , TypeFamilies
+                     , TypeInType
+                     , MultiParamTypeClasses
+                     , ConstraintKinds
+                     , FunctionalDependencies
+                     , StandaloneDeriving
+
+source-repository head
+  type:     git
+  location: https://github.com/martyall/servant-zeppelin
diff --git a/src/Servant/Zeppelin.hs b/src/Servant/Zeppelin.hs
new file mode 100644
--- /dev/null
+++ b/src/Servant/Zeppelin.hs
@@ -0,0 +1,8 @@
+module Servant.Zeppelin where
+
+import           Data.Kind
+
+-- | Combinator to indicate the availablity of side loaded data.
+--
+-- > "albums" :> Get '[JSON] Album :> SideLoad '[Person, [Photo]]
+data SideLoad (fs :: [*])
diff --git a/src/Servant/Zeppelin/Internal/Types.hs b/src/Servant/Zeppelin/Internal/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Servant/Zeppelin/Internal/Types.hs
@@ -0,0 +1,118 @@
+{-# LANGUAGE UndecidableInstances    #-}
+{-# LANGUAGE UndecidableSuperClasses #-}
+
+module Servant.Zeppelin.Internal.Types
+  ( DependencyList(..)
+  , NamedDependency(..)
+  , SideLoaded(..)
+  , Inflatable(..)
+  , HasDependencies(..)
+  , AllSatisfy(..)
+  , Inflatable'
+  , Full'
+  ) where
+
+import           Data.Functor.Identity   (Identity)
+import           Data.Kind
+import           Data.Singletons.Prelude
+
+--------------------------------------------------------------------------------
+-- Dependency Lists
+--------------------------------------------------------------------------------
+
+-- | 'DependencyList' @m bs fs@ is a type representing a heterogeneous list parameterized
+-- by @bs@ , which can be transformed into a hetergeneous list of type @fs@ in the context
+-- provided by @m@.
+data DependencyList :: (* -> *) -> [*] -> [*] -> * where
+  NilDeps :: DependencyList m '[] '[]
+  (:&:) :: b -> DependencyList m bs fs -> DependencyList m (b:bs) (f:fs)
+
+infixr 5 :&:
+
+instance AllSatisfy bs Show' => Show (DependencyList m bs fs) where
+  show NilDeps    = "NilDeps"
+  show (b :&: bs) = show b ++ " :&: " ++ show bs
+
+instance AllSatisfy bs Eq' => Eq (DependencyList m bs fs) where
+  NilDeps == NilDeps = True
+  (b :&: bs) == (b' :&: bs') = b == b' && bs == bs'
+
+-- | Labels for the objects created in the dependency mapping. Necessary for JSON instances.
+--
+-- > type instance NamedDependency Person = "person"
+-- > type instance NamedDependency [Photo] = "photos"
+--
+type family NamedDependency a :: Symbol
+
+-- | 'SideLoaded' @a deps@ represents a type @a@ with an hlist of its inflated dependencies.
+data SideLoaded a (deps :: [*]) = SideLoaded a (DependencyList Identity deps deps)
+
+deriving instance (Show a, Show (DependencyList Identity deps deps)) => Show (SideLoaded a deps)
+deriving instance (Eq a, Eq (DependencyList Identity deps deps)) => Eq (SideLoaded a deps)
+
+-- | Inflatable represents a type 'b' which can be expanded inside of a context 'm'.
+--
+-- > type PGMonad = ReaderT Connection (ExceptT QueryError IO)
+-- >
+-- > instance Inflatable PGMonad PersonId where
+-- >   type Full PGMonad PersonId = Person
+-- >   inflator = getPersonById
+
+class Inflatable m base where
+  type Full m base :: *
+  inflator :: base -> m (Full m base)
+
+-- | Anything can be expanded into itself in the trivial context.
+instance Inflatable Identity base where
+  type Full Identity base = base
+  inflator = return
+
+--------------------------------------------------------------------------------
+-- HasDepedencies
+--------------------------------------------------------------------------------
+
+-- | Indicate that a type has dependencies, and supply the uninflated values.
+--
+-- > data Album =
+-- >   Album { albumId     :: AlbumId
+-- >         , albumArtist :: PersonId
+-- >         , albumPhotos :: [PhotoId]
+-- >         , albumTitle  :: Text
+-- >         }
+-- >
+-- > instance HasDependencies PGMonad Album '[Person, [PhotoId]] where
+-- >   getDependencies album = albumArtist album :&: albumPhotos album :&: NilDeps
+
+class AllSatisfy bs (Inflatable' m) => HasDependencies m a bs | a -> bs, bs -> m where
+  getDependencies :: a -> DependencyList m bs (Map (Full' m) bs)
+
+--------------------------------------------------------------------------------
+-- Type Families
+--------------------------------------------------------------------------------
+
+-- | All subjects must satisfy the test constraint.
+type family AllSatisfy (subjects :: [k]) (test :: (k ~> Constraint)) :: Constraint where
+  AllSatisfy '[] test = ()
+  AllSatisfy (subj : rest) test = (Apply test subj, AllSatisfy rest test)
+
+-- | Parially applied 'Inflatable' constraint.
+data Inflatable' :: m -> (base ~> Constraint) where
+  Inflatable' :: Inflatable' m base
+
+type instance Apply (Inflatable' m) base = Inflatable m base
+
+-- | Defunctionalized 'Full' type family to be used with 'Map'.
+data Full' :: m -> (base ~> *) where
+  Full' :: Full' m base
+
+type instance Apply (Full' m) base = Full m base
+
+data Eq' :: b ~> Constraint where
+  Eq' :: Eq' b
+
+type instance Apply Eq' b = Eq b
+
+data Show' :: b ~> Constraint where
+  Show' :: Show' b
+
+type instance Apply Show' b = Show b
