diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+;; Copyright (c) 2013 Phil Hargett
+
+;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;; of this software and associated documentation files (the "Software"), to deal
+;; in the Software without restriction, including without limitation the rights
+;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;; copies of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+
+;; The above copyright notice and this permission notice shall be included in
+;; all copies or substantial portions of the Software.
+
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+;; THE SOFTWARE.
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/src/Data/UID.hs b/src/Data/UID.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/UID.hs
@@ -0,0 +1,103 @@
+{- |
+A 'UID' is a unique identifier, generated from "Data.UUID.V4". 
+
+These identifiers are designed for easy presentation as Base32, using "Codec.Binary.Base32", and
+for transport in a JSON format using "Data.Aeson".
+
+The primary constructor, 'newUID', runs in the 'IO' monad, primarily because of its
+use of a random number generator during construction. If all you need is a unique string,
+then 'newUIDString' is just a wrapper that creates a new UID and then invokes 'toBase32' on it.
+
+-}
+
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Data.UID (
+  UID,
+  newUID,
+  newUIDString,
+  fromBase32,
+  toBase32) 
+       where
+
+import Codec.Binary.Base32 as B32
+
+import Control.Applicative (pure)
+import Control.Exception
+
+import Data.Aeson
+import qualified Data.ByteString.Lazy as BL
+import Data.Char (toLower,toUpper)
+import Data.Maybe
+import Data.Serialize
+import Data.Text (pack,unpack)
+import Data.Typeable
+import Data.UUID
+import Data.UUID.V4
+
+{- |
+A new, randomly generated identifier
+-}
+data UID = UID UUID deriving (Eq,Typeable)
+
+instance Serialize UID where
+  put (UID uuid) = do 
+    put $ toByteString uuid
+    
+  get = do
+    bs <- getByteString 16 -- size of UUID representation
+    return $ UID $ fromJust $ fromByteString $ BL.fromStrict bs
+    
+{- |
+Convert the 'UID' into a base32 'String' representation'.
+-}
+toBase32 :: UID -> String
+toBase32 (UID uuid) = let encoding = B32.encode $ BL.unpack $ toByteString uuid
+                          except c = c /= '='
+                          in map toLower $ filter except encoding 
+
+data InvalidUIDException = InvalidUIDException String deriving (Show,Typeable)
+
+instance Exception InvalidUIDException
+
+{- |
+Convert a base32 'String' representation of the 'UID' back into a UID instance.
+-}
+fromBase32 :: String -> UID
+fromBase32 s = let extended = map toUpper $ s ++ (replicate paddingSize '=')
+                   paddingSize = if (length s) < 32 then (32 - (length s)) else 0
+                   decoded = B32.decode $ extended
+                   bs = fromByteString $ BL.pack $ 
+                        if (isJust decoded)
+                        then fromJust decoded
+                        else (throw $ InvalidUIDException s)
+               in UID $ 
+                  if (isJust bs)
+                  then fromJust bs
+                  else throw $ InvalidUIDException s
+
+instance Show UID where    
+  show u = "UID " ++ toBase32 u
+  
+instance ToJSON UID where  
+  toJSON u = String $  pack $ toBase32 u
+  
+instance FromJSON UID where  
+  parseJSON = withText "Base32" $ pure . fromBase32 . unpack
+
+{- |
+Construct a new unique identifier.
+-}
+newUID :: IO UID
+newUID = do
+  uuid <- nextRandom
+  return $ UID uuid
+  
+  
+{- |  
+Construct a new identifier and immediately convert to its base32 representation using 'toBase32'
+-}
+newUIDString :: IO String  
+newUIDString = do
+  uid <- newUID
+  return $ toBase32 uid
diff --git a/uid.cabal b/uid.cabal
new file mode 100644
--- /dev/null
+++ b/uid.cabal
@@ -0,0 +1,30 @@
+-- Initial uid.cabal generated by cabal init.  For further documentation, 
+-- see http://haskell.org/cabal/users-guide/
+
+name:                uid
+version:             0.1.0.0
+synopsis:            Simple unique identifier datatype, serializable and encodable as base32
+description:          A simple unique identiier, serializable to binary and JSON, and since
+                      base32 is a primary encoding, renders in URLs without any further encoding.
+homepage:            http://github.com/hargettp/uid
+license:             MIT
+license-file:        LICENSE
+author:              Phil Hargett
+maintainer:          phil@haphazardhouse.net
+-- copyright:           
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.8
+
+library
+  exposed-modules:     Data.UID
+  -- other-modules:       
+  build-depends:       base >=4 && < 5,
+                       aeson,
+                       bytestring,
+                       cereal,
+                       dataenc,
+                       text,
+                       uuid
+
+  hs-source-dirs:      src
