diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for Gleam
+
+## 0.1.0.0  -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/Gleam.cabal b/Gleam.cabal
new file mode 100644
--- /dev/null
+++ b/Gleam.cabal
@@ -0,0 +1,36 @@
+name:                Gleam
+version:             0.1.0.0
+cabal-version:       >=1.10
+license:             BSD3
+license-file:        LICENSE
+author:              bennye@tcd.ie
+maintainer:          bennye@tcd.ie
+category:            Graphics
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+description:         
+  Gleam is a graphics library written in Haskell that uses the web-browser as a display. 
+  Gleam is inspired by the Picture datatype from gloss Gloss and uses Threepenny-gui as its back-end local webserver.
+
+synopsis:            HTML Canvas graphics, animations and simulations.
+
+source-repository head
+  type:         git
+  location:     https://github.com/Ebin-Benny/Gleam.git
+
+library
+  exposed-modules:    Gleam
+
+  -- Other library packages from which modules are imported.
+  build-depends:       base             >=4.9 && <4.10
+                       ,mtl             >= 2.2.2 && < 2.3
+                       ,split           >= 0.2.3 && < 0.3
+                       ,threepenny-gui  >= 0.8.3 && < 0.9
+
+
+  -- Directories containing source files.
+  hs-source-dirs:      src
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+  
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2020, bennye@tcd.ie
+
+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 ebinmoolan@gmail.com 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/src/Gleam.hs b/src/Gleam.hs
new file mode 100644
--- /dev/null
+++ b/src/Gleam.hs
@@ -0,0 +1,126 @@
+{-# OPTIONS_HADDOCK prune #-}
+
+module Gleam
+  ( play
+  , playMultiple
+  , module Picture
+  , module InputEvent
+  , module Color
+  , module Settings
+  )
+where
+
+import qualified Graphics.UI.Threepenny        as UI
+import           Graphics.UI.Threepenny.Core
+import           Control.Monad
+import           Data.IORef
+import           Control.Monad.Trans            ( liftIO )
+import           Picture
+import           Animate
+import           InputEvent
+import           Handler
+import           Utility
+import           Color
+import           Settings
+
+config = defaultConfig { jsStatic = Just "./images" }
+
+-- | Run a simulation in a window. You decide how the model is represented, how to convert the model to a picture and how to update the model. This function does the rest. The simulation can be seen on `127.0.0.1:8023`
+play
+  :: GleamConfig                    -- ^ Canvas size.
+  -> model                          -- ^ Initial model for the simulation.
+  -> (model -> Picture)             -- ^ Function to generate a picture from a model.
+  -> (model -> model)               -- ^ Function to update the state of the simulation.
+  -> (InputEvent -> model -> model) -- ^ Function to handle input events.
+  -> IO ()
+play gleamconfig initialModel draw update handler =
+  startGUI config $ setup gleamconfig initialModel draw update handler
+
+-- | Run multiple simulations in a window. You decide how each model is represented, how to convert each model to a picture and how to update the model. This function does the rest. The simulations can be seen on `127.0.0.1:8023`
+playMultiple :: [Simulation] -> IO ()
+playMultiple simulations = startGUI config $ setupMultiple simulations
+
+setup
+  :: GleamConfig                    -- ^ Canvas size.
+  -> model                          -- ^ Initial model for the simulation.
+  -> (model -> Picture)             -- ^ Function to generate a picture from a model.
+  -> (model -> model)               -- ^ Function to update the state of the simulation.
+  -> (InputEvent -> model -> model) -- ^ Function to handle input events.
+  -> Window
+  -> UI ()
+setup gleamconfig initialModel draw update handler window = do
+  return window # set title "ThreePennyGloss"
+
+  canvas <-
+    UI.canvas
+    # set UI.width  (width gleamconfig)
+    # set UI.height (height gleamconfig)
+    # set UI.style  [("background", "#bbb")]
+
+  canvas # setAttribute "tabindex" "1"
+
+  getBody window #+ [element canvas]
+
+  currentState    <- liftIO $ newIORef initialModel
+
+  currentMousePos <- liftIO $ newIORef (0.0, 0.0)
+
+  handleEvents gleamconfig currentState currentMousePos (handler) canvas
+
+  animate currentState (update) (draw) canvas
+
+  return ()
+
+setupMultiple :: [Simulation] -> Window -> UI ()
+setupMultiple simulations window = do
+  return window # set title "ThreePennyGloss"
+  simulate simulations window
+  return ()
+
+simulate :: [Simulation] -> Window -> UI ()
+simulate ([]) _ = do
+  return ()
+simulate ((Simulation simConfig simInitialModel simDraw simUpdate simHandler simTitle) : simulations) window
+  = do
+    return ()
+    canvas <-
+      UI.canvas
+      # set UI.width  (width simConfig)
+      # set UI.height (height simConfig)
+      # set UI.style  [("background", "#bbb")]
+
+    canvas # setAttribute "tabindex" "1"
+
+    text          <- UI.p # set UI.text simTitle
+    playButton    <- UI.button # set UI.class_ "play"
+    restartButton <- UI.button # set UI.class_ "restart"
+
+    buttonDiv     <- UI.div # set UI.children [playButton, restartButton] # set
+      UI.class_
+      "buttons"
+
+    getBody window #+ [element text, element buttonDiv, element canvas]
+
+    currentState    <- liftIO $ newIORef simInitialModel
+
+    currentMousePos <- liftIO $ newIORef (0.0, 0.0)
+
+    currentPause    <- liftIO $ newIORef False
+
+    on UI.click playButton $ \_ -> do
+      pause <- liftIO $ readIORef currentPause
+      liftIO $ writeIORef currentPause (not pause)
+
+    on UI.click restartButton $ \_ -> do
+      liftIO $ writeIORef currentState simInitialModel
+
+    handleEventsMultiple simConfig
+                         currentState
+                         currentMousePos
+                         currentPause
+                         (simHandler)
+                         canvas
+
+    animateMultiple currentState currentPause (simUpdate) (simDraw) canvas
+
+    simulate simulations window
