diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2012, John Lato
+
+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 John Lato 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,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/chronograph.cabal b/chronograph.cabal
new file mode 100644
--- /dev/null
+++ b/chronograph.cabal
@@ -0,0 +1,42 @@
+-- Initial chronograph.cabal generated by cabal init.  For further
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                chronograph
+version:             0.1.0.0
+synopsis:            measure timings of data evaluation
+description:         The 'Chronograph' data structure adds a measure field
+                     to an existing Haskell expression.  This field will be the
+                     time necessary to evaluate the expression using an
+                     arbitrary evaluation strategy (WHNF by default).
+                     .
+                     Chronograph preserves laziness, so that the work of
+                     performing the evaluation is only done after the result is
+                     demanded.
+                     .
+                     If you want to benchmark your program, you should look to
+                     other packages like Criterion that perform statistical
+                     analysis of your results so you can determine how reliable
+                     they are.  Chronograph just takes measurements, leaving
+                     the interpretation entirely to you.
+license:             BSD3
+license-file:        LICENSE
+author:              John Lato
+maintainer:          jwlato@gmail.com
+copyright:           John W. Lato, 2012
+category:            Testing
+build-type:          Simple
+cabal-version:       >=1.8
+
+extra-source-files:  examples/Chrono.hs
+
+library
+  exposed-modules:     Data.Chronograph
+  build-depends:       base >=4.5 && < 5.0,
+                       ghc-prim >=0.2 && < 0.4,
+                       deepseq ==1.3.*,
+                       time ==1.4.*
+  hs-source-dirs:      src
+
+source-repository head
+  type: git
+  location: https://github.com/JohnLato/chronograph
diff --git a/examples/Chrono.hs b/examples/Chrono.hs
new file mode 100644
--- /dev/null
+++ b/examples/Chrono.hs
@@ -0,0 +1,35 @@
+-- | A simple example of how to use Chronograph.  We want to count the lines in
+-- a file, and measure how long it takes.
+
+module Main where
+
+import Control.Applicative
+import System.Environment
+import Data.Chronograph
+
+import Text.Printf
+
+main :: IO ()
+main = do
+    args <- getArgs
+    putStrLn "pure Chronograph"
+    mapM_ procFile args
+    putStrLn "IO Chronograph"
+    mapM_ procIO args
+
+procFile :: FilePath -> IO ()
+procFile fp = do
+    doc <- readFile fp
+    let wc = length $ lines doc
+    putStrLn $ formatOutput fp (chrono wc)
+    
+formatOutput :: FilePath -> Chronograph Int -> String
+formatOutput fp chr = printf "%s :: %d, %s" fp (val chr) (show $ measure chr)
+
+fileLinesIO :: FilePath -> IO Int
+fileLinesIO fp = length . lines <$> readFile fp
+
+procIO :: FilePath -> IO ()
+procIO fp = do
+  wc <- chronoIO $ fileLinesIO fp
+  putStrLn $ formatOutput fp wc
diff --git a/src/Data/Chronograph.hs b/src/Data/Chronograph.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Chronograph.hs
@@ -0,0 +1,123 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE NamedFieldPuns #-}
+
+ -- |
+ -- Measure data and IO evaluation time in a lightweight manner.
+ --
+ -- A 'Chronograph a' has two parts, the value 'a' and the measurement of
+ -- evaluation time.  A Chronograph is lazy, so 'a' is only evaluted on demand.
+ --
+ -- This example counts the lines in a number of files, and records the
+ -- evaluation time taken for each one.
+ --
+ -- >  import System.Environment
+ -- >  import Control.Applicative
+ -- >  import Data.Chronograph
+ -- >
+ -- >  import Text.Printf
+ -- >
+ -- >  formatOutput :: FilePath -> Chronograph Int -> String
+ -- >  formatOutput fp chr = printf "%s :: %d, %s" fp (val chr) (show $ measure chr)
+ -- >
+ -- >  procFile :: FilePath -> IO ()
+ -- >  procFile fp = do
+ -- >      doc <- readFile fp
+ -- >      let wc = length $ lines doc
+ -- >      putStrLn $ formatOutput fp (chrono wc)
+ --
+ -- 'chrono' creates a chronograph that evaluates its input as far as 'seq' would.
+ -- In this case the input 'wc' is an Int, so 'chrono' fully evaluates it.
+ -- deepseq-style evaluation is performed by 'chronoNF', and custom evaluation
+ -- strategies can be implemented with 'chronoBy'.
+ --
+ -- although 'wc' is a pure value, IO is lazily performed in its evalution.
+ -- This IO cost is included in 'chrono's measurement.
+ --
+ -- You can explicitly include timings of IO actions as well:
+ --
+ -- >  fileLinesIO :: FilePath -> IO Int
+ -- >  fileLinesIO fp = length . lines <$> readFile fp
+ -- >
+ -- >  procIO :: FilePath -> IO ()
+ -- >  procIO fp = do
+ -- >    wc <- chronoIO $ fileLinesIO fp
+ -- >    putStrLn $ formatOutput fp wc
+ --
+ -- >  main :: IO ()
+ -- >  main = do
+ -- >      args <- getArgs
+ -- >      putStrLn "pure Chronograph"
+ -- >      mapM_ procFile args
+ -- >      putStrLn "IO Chronograph"
+ -- >      mapM_ procIO args
+ --
+module Data.Chronograph (
+  Chronograph (..)
+-- * chrono pure stuff
+, chrono
+, chronoNF
+, chronoBy
+-- * chrono IO stuff
+, chronoJustIO
+, chronoIO
+, chronoNFIO
+, chronoIOBy
+) where
+
+import Control.DeepSeq
+import Data.Time (NominalDiffTime, getCurrentTime, diffUTCTime)
+import GHC.Generics
+import System.IO.Unsafe (unsafePerformIO)
+
+data Chronograph a = Chronograph
+    { val :: a
+    , measure :: NominalDiffTime
+    } deriving (Show, Generic)
+
+----------------------------------------------------------
+-- chrono pure functions
+
+-- | Add a 'Chronograph' to measure evaluation to weak head normal form.
+chrono :: a -> Chronograph a
+chrono = chronoBy (`seq` ())
+
+-- | Add a 'Chronograph' to measure evaluation to normal form.
+chronoNF :: NFData a => a -> Chronograph a
+chronoNF = chronoBy rnf
+
+-- | Add a 'Chronograph' to measure evalution time with the provided strategy.
+chronoBy :: (a -> ()) -> a -> Chronograph a
+chronoBy eval x =
+    let measure = unsafePerformIO $ do
+                    t0 <- getCurrentTime
+                    t1 <- eval x `seq` getCurrentTime
+                    return (t1 `diffUTCTime` t0)
+    in Chronograph {val = measure `seq` x, measure }
+
+----------------------------------------------------------
+-- chrono IO computations
+
+-- | Add a 'Chronograph' to measure IO time (no additional evaluation is
+-- performed, although the IO action itself may perform some evaluation)
+chronoJustIO :: IO a -> IO (Chronograph a)
+chronoJustIO = chronoIOBy (const ())
+
+-- | Add a 'Chronograph' to measure time of IO and evaluation to weak head
+-- normal form.
+chronoIO :: IO a -> IO (Chronograph a)
+chronoIO = chronoIOBy (`seq` ())
+
+-- | Add a 'Chronograph' to measure time of IO and evaluation to normal form.
+chronoNFIO :: NFData a => IO a -> IO (Chronograph a)
+chronoNFIO = chronoIOBy rnf
+
+-- | Add a 'Chronograph' to measure time of IO and evaluation with the
+-- provided strategy.
+chronoIOBy :: (a -> ()) -> IO a -> IO (Chronograph a)
+chronoIOBy eval mx = do
+    t0 <- getCurrentTime
+    val  <- mx
+    t1 <- eval val `seq` getCurrentTime
+    let measure = t1 `diffUTCTime` t0
+
+    return $ Chronograph {val, measure}
