diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2012 Dennis Felsing
+
+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 AUTHORS ``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,3 @@
+module Main where
+import Distribution.Simple
+main = defaultMain
diff --git a/ghc-datasize.cabal b/ghc-datasize.cabal
new file mode 100644
--- /dev/null
+++ b/ghc-datasize.cabal
@@ -0,0 +1,30 @@
+name:               ghc-datasize
+version:            0.1
+license:            BSD3
+license-file:       LICENSE
+category:           GHC, Debug, Development
+cabal-version:      >= 1.10
+build-type:         Custom
+author:             Dennis Felsing <dennis@felsin9.de>
+maintainer:         Dennis Felsing <dennis@felsin9.de>
+homepage:           http://felsin9.de/nnis/ghc-datasize
+copyright:          Dennis Felsing 2012
+synopsis:           Determine the size of data structures in GHC's memory
+description:        ghc-datasize is a tool to determine the size of data
+                    structures in GHC's memory. Determining the size of
+                    recursive data structures is supported. All sizes are in
+                    Bytes.
+
+tested-with: GHC == 7.4.2, GHC == 7.6.1
+
+Library
+  Exposed-modules: GHC.DataSize
+  Default-Language: Haskell2010
+  Build-depends: base == 4.*,
+                 ghc-heap-view >= 0.3.0.3
+  Hs-source-dirs: src/
+  Ghc-options: -Wall
+
+source-repository head
+    type:     git
+    location: git://r0q.ath.cx/ghc-datasize
diff --git a/src/GHC/DataSize.hs b/src/GHC/DataSize.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/DataSize.hs
@@ -0,0 +1,58 @@
+{- |
+   Module      : GHC.DataSize
+   Copyright   : (c) Dennis Felsing
+   License     : 3-Clause BSD-style
+   Maintainer  : dennis@felsin9.de
+ -}
+module GHC.DataSize (
+  closureSize,
+  recursiveSize
+  )
+  where
+
+import GHC.HeapView hiding (size)
+
+import GHC.Constants (wORD_SIZE)
+
+import Control.Monad
+
+import System.Mem
+
+-- Inspired by Simon Marlow:
+-- https://ghcmutterings.wordpress.com/2009/02/12/53/
+
+-- | Calculate size of GHC objects in Bytes. Note that an object may not be
+--   evaluated yet and only the size of the initial closure is returned.
+closureSize :: Num b => a -> IO b
+closureSize x = do
+  (_,y,_) <- getClosureRaw x
+  return . fromIntegral $ length y * wORD_SIZE
+
+-- | Calculate the recursive size of GHC objects in Bytes. Note that the actual
+--   size in memory is calculated, so shared values are only counted once.
+--
+--   Call with
+--   @
+--    recursiveSize $! 2
+--   @
+--   to force evaluation to WHNF before calculating the size.
+--
+--   Call with
+--   @
+--    recursiveSize $!! \"foobar\"
+--   @
+--   ($!! from Control.DeepSeq) to force full evaluation before calulating the size.
+--
+--   A garbage collection is performed before the size is calculated, because
+--   the garbage collector would make heap walks difficult.
+recursiveSize :: Num b => a -> IO b
+recursiveSize x = do
+  performGC
+  liftM snd $ go ([], 0) $ asBox x
+  where go (vs, acc) b@(Box y)
+          | b `elem` vs = return (vs, acc)
+          | otherwise   = do
+             size    <- closureSize y
+             closure <- getClosureData y
+             --putStrLn $ (show b) ++ " | " ++ (show closure)
+             foldM go (b : vs, acc + size) $ allPtrs closure
