diff --git a/Development/IncludeFile.hs b/Development/IncludeFile.hs
new file mode 100644
--- /dev/null
+++ b/Development/IncludeFile.hs
@@ -0,0 +1,91 @@
+
+-- | Inclusion of files in source code via Template Haskell.
+--
+--   When distributing executables, sometimes it is required to attach some other resources in
+--   files. Using 'includeFileInSource' you avoid this problem by including those files inside
+--   the executable at compile time.
+--
+-- = Example
+--
+--   A quick example. I want to include a small image (@foo.png@) in the executable. I would do:
+--
+-- > {-# LANGUAGE TemplateHaskell #-}
+-- >
+-- > import Development.IncludeFile
+-- >
+-- > $(includeFileInSource "foo.png" "myImage")
+-- >
+--
+--   This defines the @myImage@ value with type 'S.ByteString' and with the content of the file @foo.png@.
+--
+-- = Using 'includeFileInSource'
+--
+--   The following entities must be in scope when calling 'includeFileInSource':
+--
+-- * A @ByteString@ type.
+-- * A @Word8@ type, instance of the 'Num' class (at least with the 'fromInteger' method implemented).
+-- * A @pack :: [Word8] -> ByteString@ function.
+--
+--   This module re-export these for convenience, but you can use your own types (for example, using
+--   /lazy/ bytestrings instead of /strict/ bytestrings).
+--
+-- = Using lazy bytestrings
+--
+--   To use lazy bytestrings, instead of importing this full module, import it like this:
+--
+-- > import Data.ByteString.Lazy (ByteString,pack)
+-- > import Development.IncludeFile (includeFileInSource,Word8)
+--
+--   Needless to say, if you have already imported any of those entities, you don't have to do it again.
+--
+-- = Performance impact
+--
+--   Benchmarks confirm that it is /much/ faster to use an included bytestring than reading it from a file.
+--
+-- > benchmarking include-file
+-- > time                 1.814 ns   (1.799 ns .. 1.826 ns)
+-- >                      1.000 R²   (0.999 R² .. 1.000 R²)
+-- > mean                 1.808 ns   (1.797 ns .. 1.819 ns)
+-- > std dev              37.48 ps   (31.27 ps .. 46.78 ps)
+-- > 
+-- > benchmarking read-file
+-- > time                 4.869 μs   (4.798 μs .. 4.938 μs)
+-- >                      0.998 R²   (0.998 R² .. 0.999 R²)
+-- > mean                 4.911 μs   (4.857 μs .. 4.968 μs)
+-- > std dev              178.8 ns   (150.1 ns .. 212.5 ns)
+--
+-- = Large files
+--
+--   Do not use 'includeFileInSource' with large files. The limit between what /is/ and what is /not/ a large
+--   file remains uncertain.
+--
+module Development.IncludeFile (
+    -- * Including files
+    includeFileInSource
+    -- * Convenient re-exports
+  , B.ByteString
+  , Word8
+  , B.pack
+  ) where
+
+import qualified Data.ByteString as B
+import Data.Word (Word8)
+import Language.Haskell.TH
+
+-- | Define a value of type @ByteString@ (where @ByteString@ is whatever @ByteString@ type is in scope)
+--   with the content of a file.
+includeFileInSource :: FilePath -- ^ Path to file
+                    -> String -- ^ Haskell value name
+                    -> Q [Dec]
+includeFileInSource fp n = do
+  b <- runIO $ B.readFile fp
+  let ws = B.unpack b
+      wtype = ConT $ mkName "Word8"
+      btype = ConT $ mkName "ByteString"
+  return
+    [ SigD (mkName n) btype
+    , FunD (mkName n) [Clause [] (NormalB $
+         AppE (SigE (VarE $ mkName "pack") $ ArrowT `AppT` (ListT `AppT` wtype) `AppT` btype)
+           $ ListE $ fmap (LitE . IntegerL . fromIntegral) ws
+                                   ) []]
+      ]
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Daniel Díaz
+
+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 Daniel Díaz 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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,19 @@
+
+import Distribution.Simple
+import System.Random (randomRIO, randomIO)
+import qualified Data.ByteString as B
+import Control.Monad (replicateM)
+
+main :: IO ()
+main = do
+  defaultMainWithHooks $
+    simpleUserHooks
+      { preBuild = \_ _ -> do
+          putStr "Generating random file for testing..."
+          n <- randomRIO (10,1000)
+          ws <- replicateM n randomIO
+          let b = B.pack ws
+          B.writeFile "test/random" b
+          putStrLn " Done."
+          return (Nothing,[])
+        }
diff --git a/bench/Main.hs b/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/bench/Main.hs
@@ -0,0 +1,14 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+
+import Criterion.Main
+import Development.IncludeFile
+import qualified Data.ByteString as B
+
+$(includeFileInSource "test/random" "random")
+
+main :: IO ()
+main = defaultMain
+  [ bench "include-file" $ whnf (const random) (0 :: Int)
+  , bench "read-file"    $ whnfIO $ B.readFile "test/random"
+    ]
diff --git a/include-file.cabal b/include-file.cabal
new file mode 100644
--- /dev/null
+++ b/include-file.cabal
@@ -0,0 +1,46 @@
+name:                include-file
+version:             0.1.0.0
+synopsis:            Inclusion of files in executables at compile-time.
+description:         Inclusion of files in source code via Template Haskell.
+                     .
+                     When distributing executables, sometimes it is required
+                     to attach some other resources in files. Using this library
+                     (together with the TemplateHaskell extension) you avoid this
+                     problem by including those files inside the executable at
+                     compile time.
+license:             BSD3
+license-file:        LICENSE
+author:              Daniel Díaz
+maintainer:          dhelta.diaz@gmail.com
+category:            Development
+build-type:          Custom
+cabal-version:       >=1.10
+
+library
+  exposed-modules: Development.IncludeFile
+  build-depends: base == 4.*
+               , bytestring
+               , template-haskell
+  default-language: Haskell2010
+  ghc-options: -Wall
+
+test-suite include-file-test
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
+  hs-source-dirs: test
+  main-is: Main.hs
+  build-depends: base == 4.*
+               , include-file
+               , bytestring
+  ghc-options: -fforce-recomp
+
+benchmark include-file-bench
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
+  hs-source-dirs: bench
+  main-is: Main.hs
+  build-depends: base == 4.*
+               , include-file
+               , bytestring
+               , criterion
+  ghc-options: -fforce-recomp -O2 -Wall
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,20 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+
+import System.Exit (exitSuccess, exitFailure)
+import Development.IncludeFile
+import qualified Data.ByteString as B
+
+$(includeFileInSource "test/random" "test")
+
+main :: IO ()
+main = do
+  b <- B.readFile "test/random"
+  if b == test
+     then exitSuccess
+     else do putStrLn "Fail: inputs differ."
+             putStrLn "Original:"
+             print $ B.unpack b
+             putStrLn "Included:"
+             print $ B.unpack test
+             exitFailure
