diff --git a/Data/Hashable/Generic.hs b/Data/Hashable/Generic.hs
new file mode 100644
--- /dev/null
+++ b/Data/Hashable/Generic.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE TypeOperators, FlexibleContexts, BangPatterns #-}
+-- | Stability:   stable
+--   Portability: GHC
+--
+--   NOTE: This module exports the Hashable class for convenience. If this
+--         becomes a problem, just use a qualified import.
+module Data.Hashable.Generic ( gHashWithSalt
+                             , Hashable(..)
+                             ) where
+
+import Data.Hashable
+import GHC.Generics
+
+-- | "GHC.Generics"-based 'hashWithSalt' implementation
+--
+-- This provides a generic `hashWithSalt` implementation for one type at a
+-- time. If the type of the value 'gHashWithSalt' is asked to hash
+-- contains values of other types, those types have to provide
+-- 'Hashable' instances. This also means that recursive types can only
+-- be used with 'gHashWithSalt' if a 'Hashable' instance has been defined
+-- as well (see examples below).
+--
+-- The typical usage for 'gHashWithSalt' is for reducing boilerplate code
+-- when defining 'Hashable' instances for ordinary algebraic
+-- datatypes. See the code below for some simple usage examples:
+--
+-- > {-# LANGUAGE DeriveGeneric #-}
+-- >
+-- > import Data.Hashable
+-- > import Data.Hashable.Generic ( gHashWithSalt )
+-- > import GHC.Generics
+-- >
+-- > -- simple record
+-- > data Foo = Foo AccountId Name Address
+-- >          deriving Generic
+-- >
+-- > type Address      = [String]
+-- > type Name         = String
+-- > newtype AccountId = AccountId Int
+-- >
+-- > instance Hashable AccountId
+-- > instance Hashable Foo where hashWithSalt = gHashWithSalt
+-- >
+-- > -- recursive list-like type
+-- > data N = Z | S N deriving Generic
+-- >
+-- > instance Hashable N where hashWithSalt = gHashWithSalt
+-- >
+-- > -- parametric and recursive type
+-- > data Bar a = Bar0 | Bar1 a | Bar2 (Bar a)
+-- >            deriving Generic
+-- >
+-- > instance Hashable a => Hashable (Bar a) where hashWithSalt = gHashWithSalt
+--
+-- Note: The 'GHashable' type-class showing up in the type-signature is
+--       used internally and not exported on purpose currently
+gHashWithSalt :: (Generic a, GHashable (Rep a)) => Int -> a -> Int
+gHashWithSalt salt x = gHashWithSalt_ salt $ from x
+{-# INLINE gHashWithSalt #-}
+
+-- | Hidden internal type class.
+class GHashable f where
+    gHashWithSalt_ :: Int -> f a -> Int
+
+instance GHashable U1 where
+    gHashWithSalt_ !salt U1 = hashWithSalt salt ()
+    {-# INLINE gHashWithSalt_ #-}
+
+instance Hashable a => GHashable (K1 i a) where
+    gHashWithSalt_ !salt = hashWithSalt salt . unK1
+    {-# INLINE gHashWithSalt_ #-}
+
+instance GHashable a => GHashable (M1 i c a) where
+    gHashWithSalt_ !salt = gHashWithSalt_ salt . unM1
+    {-# INLINE gHashWithSalt_ #-}
+
+instance (GHashable a, GHashable b) => GHashable (a :*: b) where
+    gHashWithSalt_ !salt (x :*: y) = gHashWithSalt_ (gHashWithSalt_ salt x) y
+    {-# INLINE gHashWithSalt_ #-}
+
+-- This instance is suboptimal (with the salt+1 hackery). Is there a better way
+-- to be doing this so that both choices can be unique?
+instance (GHashable a, GHashable b) => GHashable (a :+: b) where
+    gHashWithSalt_ !salt (L1 x) = gHashWithSalt_ salt     x
+    gHashWithSalt_ !salt (R1 x) = gHashWithSalt_ (salt+1) x
+    {-# INLINE gHashWithSalt_ #-}
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2012, Clark Gaebel
+
+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 Clark Gaebel 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/hashable-generics.cabal b/hashable-generics.cabal
new file mode 100644
--- /dev/null
+++ b/hashable-generics.cabal
@@ -0,0 +1,41 @@
+name:                hashable-generics
+version:             1.1
+synopsis:            Automatically generates Hashable instances with GHC.Generics.
+description:
+    This package provides a "GHC.Generics"-based 'Data.Hashable.Generic.gHashWithSalt'
+    function which can be used for providing a 'gHashWithSalt' implementation.
+    See the documentation for the 'gHashWithSalt' function in the
+    "Data.Hashable.Generic" module to get start.
+    .
+    This package is heavily inspired by deepseq-generics, which you may also find
+    useful.
+homepage:            https//github.com/wowus/hashable-generics
+license:             BSD3
+license-file:        LICENSE
+author:              Clark Gaebel
+copyright:           2012, Clark Gaebel
+maintainer:          cgaebel@uwaterloo.ca
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.8
+tested-with:         GHC >=7.6
+
+source-repository head
+    type: git
+    location: https://github.com/wowus/hashable-generics.git
+
+library
+    exposed-modules:     Data.Hashable.Generic
+    build-depends:       base >=4.5 && <4.7
+                       , hashable ==1.1.*
+
+test-suite tests
+    type: exitcode-stdio-1.0
+    main-is: Suite.hs
+    hs-source-dirs: test
+    build-depends:       base
+                       , hashable
+                       , test-framework
+                       , test-framework-quickcheck2
+                       , QuickCheck
+                       , hashable-generics
diff --git a/test/Suite.hs b/test/Suite.hs
new file mode 100644
--- /dev/null
+++ b/test/Suite.hs
@@ -0,0 +1,114 @@
+{-# LANGUAGE DeriveGeneric, GeneralizedNewtypeDeriving, BangPatterns #-}
+{-# OPTIONS_GHC -Wall #-}
+module Main where
+
+import Control.Applicative
+import Test.Framework
+import Test.Framework.Providers.QuickCheck2
+import Test.QuickCheck
+
+import Data.Hashable.Generic
+
+import GHC.Generics
+
+main :: IO ()
+main = defaultMain tests
+
+tests :: [Test]
+tests = [ testGroup "Documentation"
+            [ testProperty "Simple Record" simpleRecord
+            , testProperty "Recursive Type" recursiveType
+            , testProperty "Parametric and Recursive Type" paraRecursive
+            ]
+        ]
+
+data FooA = FooA AccountId Name Address
+    deriving (Generic, Show)
+
+instance Arbitrary FooA where
+    arbitrary = FooA <$> arbitrary
+                     <*> arbitrary
+                     <*> arbitrary
+
+data FooB = FooB AccountId Name Address
+
+type Address = [String]
+type Name = String
+
+newtype AccountId = AccountId Int
+    deriving (Hashable, Show)
+
+instance Arbitrary AccountId where
+    arbitrary = AccountId <$> arbitrary
+
+instance Hashable FooA where
+    hashWithSalt = gHashWithSalt
+
+instance Hashable FooB where
+    hashWithSalt salt (FooB ac n ad) = hashWithSalt
+                                        (hashWithSalt
+                                          (hashWithSalt salt ac)
+                                          n)
+                                        ad
+
+aToB :: FooA -> FooB
+aToB (FooA ac n ad) = FooB ac n ad
+
+simpleRecord :: FooA -> Bool
+simpleRecord a = let b = aToB a
+                  in hash a == hash b
+
+data NA = ZA | SA NA
+    deriving (Generic, Show)
+
+data NB = ZB | SB NB
+
+instance Hashable NA where
+    hashWithSalt = gHashWithSalt
+
+instance Hashable NB where
+    hashWithSalt !salt ZB      = hashWithSalt salt ()
+    hashWithSalt !salt (SB xs) = hashWithSalt (salt+1) xs
+
+instance Arbitrary NA where
+    arbitrary = lst2A <$> arbitrary
+
+lst2A :: [()] -> NA
+lst2A [] = ZA
+lst2A (_:xs) = SA $ lst2A xs
+
+na2nb :: NA -> NB
+na2nb ZA = ZB
+na2nb (SA x) = SB $ na2nb x
+
+recursiveType :: NA -> Bool
+recursiveType a = let b = na2nb a
+                   in hash a == hash b
+
+data BarA a = BarA0 | BarA1 a | BarA2 (BarA a)
+    deriving (Generic, Show)
+
+data BarB a = BarB0 | BarB1 a | BarB2 (BarB a)
+
+instance Arbitrary a => Arbitrary (BarA a) where
+    arbitrary = oneof [ return BarA0
+                      , BarA1 <$> arbitrary
+                      , BarA2 <$> arbitrary
+                      ]
+
+instance Hashable a => Hashable (BarA a) where
+    hashWithSalt = gHashWithSalt
+
+instance Hashable a => Hashable (BarB a) where
+    hashWithSalt !salt BarB0 = hashWithSalt salt ()
+    hashWithSalt !salt (BarB1 x) = hashWithSalt (salt+1) x
+    hashWithSalt !salt (BarB2 x) = hashWithSalt (salt+2) x
+
+barA2B :: BarA a -> BarB a
+barA2B BarA0 = BarB0
+barA2B (BarA1 x) = BarB1 x
+barA2B (BarA2 x) = BarB2 $ barA2B x
+
+paraRecursive :: BarA Int -> Bool
+paraRecursive a = let b = barA2B a
+                   in hash a == hash b
