diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2017
+
+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 Author name here 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+[![Hackage](https://img.shields.io/hackage/v/disposable.svg)](https://hackage.haskell.org/package/disposable)
+[![Build Status](https://secure.travis-ci.org/louispan/disposable.png?branch=master)](http://travis-ci.org/louispan/disposable)
+
+SomeDisposable aloows storing different resource releasing actions togther in a container.
+This library is useful for queueing up GHCJS.Foreign.Callback together to be released after a new rendering frame.
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/disposable.cabal b/disposable.cabal
new file mode 100644
--- /dev/null
+++ b/disposable.cabal
@@ -0,0 +1,29 @@
+name:                disposable
+version:             0.1.0.0
+synopsis:            Allows storing different resource-releasing actions together.
+description:         SomeDisposable aloows storing different resource releasing actions togther in a container.
+                     This library is useful for queueing up GHCJS.Foreign.Callback together to be released
+                     after a new rendering frame.
+homepage:            https://github.com/louispan/disposable#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Louis Pan
+maintainer:          louis@pan.me
+copyright:           2017 Louis Pan
+category:            Control
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Control.Disposable
+  build-depends:       base >= 4.7 && < 5
+                     , dlist >= 0.8 && < 0.9
+  default-language:    Haskell2010
+  if impl(ghcjs)
+      build-depends: ghcjs-base
+
+source-repository head
+  type:     git
+  location: https://github.com/githubuser/disposable
diff --git a/src/Control/Disposable.hs b/src/Control/Disposable.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Disposable.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Control.Disposable where
+
+import qualified Data.DList as D
+import Data.Foldable
+import Data.Semigroup
+import qualified GHC.Generics as G
+
+#ifdef __GHCJS__
+import qualified GHCJS.Foreign.Callback as J
+#endif
+
+-- | A 'Disposable' is something with some resources to release
+class Disposable a where
+    dispose :: a -> IO ()
+
+#ifdef __GHCJS__
+instance Disposable (J.Callback a) where
+    dispose = J.releaseCallback
+#endif
+
+-- | Allows storing 'Disposable's in a heterogenous container
+data SomeDisposable where
+    Dispose :: forall a. Disposable a => a -> SomeDisposable
+    DisposeList :: forall a. Disposable a => [a] -> SomeDisposable
+
+instance Disposable SomeDisposable where
+    dispose (Dispose a) = dispose a
+    dispose (DisposeList as) = traverse_ dispose as
+
+-- | Allow generic deriving instances of things that can be made into 'SomeDisposable'
+-- If a data type derives from Generic, and only contain instances of Disposable,
+-- then it can be made an instance of 'Disposing'.
+-- data Callbacks { ... } deriving Generic
+-- instance Disposing Callbacks
+class Disposing a where
+  disposing :: a -> SomeDisposable
+  default disposing :: (G.Generic a, GDisposing (G.Rep a)) => a -> SomeDisposable
+  disposing x = DisposeList . D.toList . gDisposing $ G.from x
+
+-- | Generics instance basically traverses the data tree
+-- and expects the values to be all instances of 'Disposable'
+class GDisposing f where
+    gDisposing :: f p -> D.DList SomeDisposable
+
+instance GDisposing G.U1 where
+  gDisposing G.U1 = mempty
+
+instance (GDisposing f, GDisposing g) => GDisposing (f G.:+: g) where
+  gDisposing (G.L1 x) = gDisposing x
+  gDisposing (G.R1 x) = gDisposing x
+
+instance (GDisposing f, GDisposing g) => GDisposing (f G.:*: g) where
+  gDisposing (x G.:*: y) = (gDisposing x) <> (gDisposing y)
+
+instance (Disposable c) => GDisposing (G.K1 i c) where
+  gDisposing (G.K1 x) = D.singleton $ Dispose x
+
+instance (GDisposing f) => GDisposing (G.M1 i t f) where
+  gDisposing (G.M1 x) = gDisposing x
