diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
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/hydrogen-version.cabal b/hydrogen-version.cabal
new file mode 100644
--- /dev/null
+++ b/hydrogen-version.cabal
@@ -0,0 +1,27 @@
+name:                 hydrogen-version
+version:              1.0
+homepage:             https://github.com/scravy/hydrogen-version
+synopsis:             Hydrogen Syntax
+license:              BSD3
+license-file:         LICENSE
+extra-source-files:   CHANGELOG.md
+author:               Julian Fleischer
+maintainer:           julfleischer@paypal.com
+category:             Language
+build-type:           Simple
+cabal-version:        >=1.14
+
+source-repository head
+    type:             git
+    location:         https://github.com/scravy/hydrogen-version
+
+library
+  exposed-modules:    Hydrogen.Version
+  build-depends:      base ==4.*
+  hs-source-dirs:     src
+  ghc-options:        -Wall
+  default-language:   Haskell2010
+  default-extensions:  CPP
+                       , FlexibleContexts
+                       , FlexibleInstances
+
diff --git a/src/Hydrogen/Version.hs b/src/Hydrogen/Version.hs
new file mode 100644
--- /dev/null
+++ b/src/Hydrogen/Version.hs
@@ -0,0 +1,64 @@
+module Hydrogen.Version (
+    Version
+  , mkVersion
+  , refineVersion
+  , majorVersion
+  , minorVersion
+  , patchVersion
+  , tailVersion
+  ) where
+
+import Prelude
+
+import Data.List (intersperse)
+import Data.Char (isDigit)
+
+newtype Version = Version [Integer]
+
+instance Eq Version where
+    v1 == v2 = compare v1 v2 == EQ
+
+instance Ord Version where
+    compare (Version v1) (Version v2) = case (v1, v2) of
+        ([], []) -> EQ
+        (xs, []) -> if all (== 0) xs then EQ else GT
+        ([], ys) -> if all (== 0) ys then EQ else LT
+        (x : xs, y : ys) | x == y -> compare (Version xs) (Version ys)
+        (x : _, y : _) -> compare x y
+
+instance Show Version where
+    show (Version v) = concat (intersperse "." (map show v))
+
+instance Read Version where
+    readsPrec _ xs = case span isDigit xs of
+        ([], _) -> []
+        (vs, []) -> result vs ""
+        (vs, '.' : rs) -> case reads (tail rs) of
+            [(Version vs', rs')] -> [(Version (read vs : vs'), rs')]
+            _ -> result vs rs
+        (vs, rs) -> result vs rs
+      where
+        result vs rs = [(Version [read vs], rs)]
+
+majorVersion, minorVersion, patchVersion :: Version -> Integer
+
+majorVersion (Version (v : _)) = v
+majorVersion _ = 0
+
+minorVersion (Version (_ : v : _)) = v
+minorVersion _ = 0
+
+patchVersion (Version (_ : _ : v : _)) = v
+patchVersion _ = 0
+
+tailVersion :: Version -> [Integer]
+
+tailVersion (Version (_ : _ : _ : vs)) = vs
+tailVersion _ = []
+
+mkVersion :: Integer -> Integer -> Integer -> Version
+mkVersion a b c = Version [a, b, c]
+
+refineVersion :: Version -> Integer -> Version
+refineVersion (Version v) i = Version (v ++ [i])
+
