diff --git a/Data/NF.hs b/Data/NF.hs
new file mode 100644
--- /dev/null
+++ b/Data/NF.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+#endif
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.NF
+-- Copyright   :  (c) Stanford University 2015
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  ezyang@cs.stanford.edu
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- This module provides a data type, 'NF', representing data which has
+-- been evaluated to \"Normal Form\".  This is a useful type discipline
+-- for many situations when normal form data is necessary, e.g. when
+-- transmitting data to other threads over channels.  If a library
+-- that you are using has the following type:
+--
+-- @
+-- strictWriteChan :: 'NFData' a => 'Control.Concurrent.Chan' a -> a -> 'IO' ()
+-- @
+--
+-- you can specialize it to the following type in order to avoid the
+-- cost of repeatedly 'deepseq'ing a value when it is not necessary:
+--
+-- @
+-- strictWriteChan_ :: 'Control.Concurrent.Chan' ('NF' a) -> 'NF' a -> 'IO' ()
+-- strictWriteChan_ = strictWriteChan
+-- @
+--
+-- You should also consider providing APIs which only accept 'NF'
+-- values, to prevent users from accidentally 'deepseq'ing.
+module Data.NF (
+    NF,
+    makeNF, getNF,
+  ) where
+
+import Control.DeepSeq
+import Data.NF.Internal
+
+-- | Creates a value of type 'NF'.  The first time the result is
+-- evaluated to whnf, the value will be 'rnf'ed.  To avoid this
+-- 'rnf', see 'UnsafeNF'.
+makeNF :: NFData a => a -> NF a
+makeNF x = x `deepseq` UnsafeNF x
+
+-- | Retrieves @a@ from a value of type @'NF' a@; this value
+-- is guaranteed to be in normal form.
+getNF :: NF a -> a
+getNF (UnsafeNF a) = a
diff --git a/Data/NF/Internal.hs b/Data/NF/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Data/NF/Internal.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+#endif
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.NF.Internal
+-- Copyright   :  (c) Stanford University 2015
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  ezyang@cs.stanford.edu
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- This module provides the constructor for the type 'NF', allowing
+-- you to create values of type 'NF' without any runtime overhead
+-- if you fulfill a proof obligation that the value is already in
+-- normal form.
+module Data.NF.Internal(NF(..)) where
+
+import Control.DeepSeq
+
+-- | 'NF' is an abstract data type representing data which has been
+-- evaluated to normal form.  Specifically, if a value of type @'NF' a@
+-- is in weak head normal form, then it is in reduced normal form;
+-- alternatively, it is only necessary to 'seq' an @'NF' a@ to assure that
+-- it is fully evaluated.
+newtype NF a
+    -- | For @'UnsafeNF' x@ to preserve the 'NF' invariant, you must
+    -- show that @'UnsafeNF' x == 'deepseq' x ('UnsafeNF' x)@.
+    = UnsafeNF a
+
+instance NFData (NF a) where
+    rnf x = x `seq` ()
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2015, Edward Z. Yang
+
+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 Edward Z. Yang 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/nf.cabal b/nf.cabal
new file mode 100644
--- /dev/null
+++ b/nf.cabal
@@ -0,0 +1,22 @@
+name:                nf
+version:             1.0.0.0
+synopsis:            NF data type to statically enforce normal form 
+description:         This package provides a data type NF representing
+                     data which has been evaluated to normal form.  This
+                     is a useful type discipline for many situations when
+                     normal form data is necessary, e.g. when transmitting
+                     data to other threads over channels.
+homepage:            https://github.com/ezyang/nf
+license:             BSD3
+license-file:        LICENSE
+author:              Edward Z. Yang
+maintainer:          ezyang@cs.stanford.edu
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.NF, Data.NF.Internal
+  other-extensions:    Safe, CPP
+  build-depends:       base >= 2 && <= 4, deepseq
+  default-language:    Haskell2010
