diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2019, Henning Thielemann
+
+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 Henning Thielemann 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,8 @@
+#!/usr/bin/env runghc
+
+> module Main where
+
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/src/Data/Enum/Storable.hs b/src/Data/Enum/Storable.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Enum/Storable.hs
@@ -0,0 +1,54 @@
+module Data.Enum.Storable (
+   T,
+   fromPlain, toPlain,
+   ) where
+
+import Foreign.Storable (Storable, poke, peek, sizeOf, alignment)
+import Foreign.Ptr (Ptr, castPtr)
+
+import Data.Functor ((<$>))
+
+import Prelude2010
+import Prelude ()
+
+
+newtype T w e = Cons e
+   deriving (Eq, Ord)
+
+
+instance (Show e) => Show (T w e) where
+   showsPrec p (Cons e) =
+      showParen (p>=10) $ showString "Enum.fromPlain " . showsPrec 11 e
+
+instance (Bounded e) => Bounded (T w e) where
+   minBound = Cons minBound
+   maxBound = Cons maxBound
+
+instance (Enum e) => Enum (T w e) where
+   fromEnum (Cons e) = fromEnum e
+   toEnum = Cons . toEnum
+   succ (Cons e) = Cons $ succ e
+   pred (Cons e) = Cons $ pred e
+   enumFrom (Cons e) = map Cons $ enumFrom e
+   enumFromThen (Cons e0) (Cons e1) = map Cons $ enumFromThen e0 e1
+   enumFromTo (Cons e0) (Cons e1) = map Cons $ enumFromTo e0 e1
+   enumFromThenTo (Cons e0) (Cons e1) (Cons e2) =
+      map Cons $ enumFromThenTo e0 e1 e2
+
+enumPtr :: Ptr (T w e) -> Ptr w
+enumPtr = castPtr
+
+zero :: (Num w) => T w e -> w
+zero _ = 0
+
+instance (Storable w, Integral w, Enum e) => Storable (T w e) where
+   sizeOf = sizeOf . zero
+   alignment = alignment . zero
+   peek ptr = Cons . toEnum . fromIntegral <$> peek (enumPtr ptr)
+   poke ptr (Cons e) = poke (enumPtr ptr) (fromIntegral $ fromEnum e)
+
+fromPlain :: a -> T w a
+fromPlain = Cons
+
+toPlain :: T w a -> a
+toPlain (Cons a) = a
diff --git a/storable-enum.cabal b/storable-enum.cabal
new file mode 100644
--- /dev/null
+++ b/storable-enum.cabal
@@ -0,0 +1,47 @@
+Name:                storable-enum
+Version:             0.0
+Synopsis:            Wrapper that makes any Enum type Storable
+Description:
+  In foreign function interfaces you will often want to use enumeration types
+  but defining 'Storable' instances is cumbersome.
+  This package provides the type @Enum.Storable.T w e@,
+  where e.g. @Enum.Storable.T Word8 Ordering@
+  means that values of type 'Ordering' are stored in a 'Word8'.
+  The 'Storable' methods store the numeric values of the enumeration elements
+  as obtained by 'fromEnum'.
+  E.g. 'EQ' is stored as @1@.
+  The type itself stores a Haskell enumeration element,
+  such that GHC can apply all of its optimizations for enumerations.
+  It is not checked, whether the storage type @w@ is large enough
+  to hold all admissible numeric values of @e@.
+  It is also not checked, whether the storage type @w@ supports negative values
+  whenever the enumeration of @e@ contains ones.
+  .
+  See the @bool8@ package for the special case of a 'Bool' stored in a 'Word8'.
+License:             BSD3
+License-File:        LICENSE
+Author:              Henning Thielemann
+Maintainer:          haskell@henning-thielemann.de
+Category:            Foreign
+Stability:           Stable
+Build-Type:          Simple
+Cabal-Version:       1.12
+Tested-With:         GHC==7.4.2, GHC==8.6.5
+
+Source-Repository this
+  Tag:         0.0
+  Type:        darcs
+  Location:    http://hub.darcs.net/thielema/storable-enum
+
+Source-Repository head
+  Type:        darcs
+  Location:    http://hub.darcs.net/thielema/storable-enum
+
+Library
+  Exposed-Modules:     Data.Enum.Storable
+  Build-Depends:
+    prelude-compat >=0.0 && <0.0.1,
+    base >=3 && <5
+  Hs-Source-Dirs:      src
+  Default-Language:    Haskell98
+  GHC-Options:         -Wall
