diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,9 @@
+# Revision history for rhine-gloss
+
+## 0.2.0.0  -- 2017-11-29
+
+* First version. Version numbers follow rhine.
+
+## 0.3.0.0  -- 2017-11-30
+
+* Added simple example.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2017, Manuel Bärenz
+
+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 Manuel Bärenz 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/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,20 @@
+{- | Example application for the @gloss@ wrapper. -}
+
+
+-- rhine-gloss
+import FRP.Rhine.Gloss
+
+
+-- | Calculate a gear wheel rotated by a certain angle.
+gears :: Float -> Picture
+gears angle = color green $ pictures
+  $ circleSolid 60
+  : map (rotate angle) [ rotate (45 * n) $ rectangleSolid 20 150 | n <- [0..3] ]
+
+-- | Rotate the gear with a constant angular velocity.
+mainSyncSF :: GlossSyncSF a
+mainSyncSF = timeInfoOf sinceStart >>> arr (* 50) >>> arr gears
+
+main :: IO ()
+main = flowGloss (InWindow "sonnen" (400, 400) (10, 10)) (greyN 0.3) 30
+     $ buildGlossRhine Just mainSyncSF
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/rhine-gloss.cabal b/rhine-gloss.cabal
new file mode 100644
--- /dev/null
+++ b/rhine-gloss.cabal
@@ -0,0 +1,34 @@
+-- Initial rhine-gloss.cabal generated by cabal init.  For further
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                rhine-gloss
+version:             0.3.0.0
+-- synopsis:
+description:         Wrapper to run reactive programs written in Rhine
+                     with Gloss as backend
+license:             BSD3
+license-file:        LICENSE
+author:              Manuel Bärenz
+maintainer:          programming@manuelbaerenz.de
+-- copyright:
+category:            FRP
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.18
+
+library
+  exposed-modules:     FRP.Rhine.Gloss
+  other-modules:       FRP.Rhine.Gloss.Internals
+  build-depends:       base  >= 4.7    && < 5
+                     , rhine == 0.3.*
+                     , dunai == 0.3.*
+                     , gloss == 1.11.*
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+
+executable rhine-gloss-gears
+  main-is:             Main.hs
+  ghc-options:         -threaded
+  build-depends:       base        >= 4.7    && < 5
+                     , rhine-gloss
+  default-language:    Haskell2010
diff --git a/src/FRP/Rhine/Gloss.hs b/src/FRP/Rhine/Gloss.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Rhine/Gloss.hs
@@ -0,0 +1,92 @@
+{- | Wrapper library to write Gloss applications in Rhine.
+@gloss@ acts as the backend here.
+
+A Rhine app with the Gloss backend must use the 'GlossClock',
+since the @gloss@ API only offers callbacks.
+In order to run such a reactive program, you have to use 'flowGloss'.
+-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE NamedFieldPuns   #-}
+{-# LANGUAGE RecordWildCards  #-}
+{-# LANGUAGE TypeFamilies     #-}
+module FRP.Rhine.Gloss
+  ( module FRP.Rhine.Gloss
+  , module X
+  )
+  where
+
+-- base
+import Data.Functor.Identity (Identity, runIdentity)
+
+import qualified Control.Arrow as X
+
+-- gloss
+import Graphics.Gloss.Interface.Pure.Game
+
+import qualified Graphics.Gloss as X
+
+-- rhine
+import FRP.Rhine
+import FRP.Rhine.Clock.Select
+import FRP.Rhine.Reactimation.Tick
+import FRP.Rhine.ResamplingBuffer.Collect
+import FRP.Rhine.ResamplingBuffer.KeepLast
+
+import qualified FRP.Rhine        as X
+import qualified FRP.Rhine.SyncSF as X
+
+-- rhine-gloss
+import FRP.Rhine.Gloss.Internals
+
+-- TODO Consider generalising to IO
+
+
+-- | The overall clock of a valid @rhine@ 'SF' that can be run by @gloss@.
+--   @a@ is the type of subevents that are selected.
+type GlossClock a
+  = SequentialClock Identity
+      (SelectClock GlossEventClock a)
+      GlossSimulationClock_
+
+-- | The type of a valid 'Rhine' that can be run by @gloss@.
+--   @a@ is the type of subevents that are selected.
+type GlossRhine a = Rhine Identity (GlossClock a) () Picture
+
+-- | The type of a 'SyncSF' that you have to implement to get a @gloss@ app.
+type GlossSyncSF a = SyncSF Identity GlossSimulationClock [a] Picture
+
+{- | For most applications, it is sufficient to implement
+a single synchronous signal function
+that is called with a list of all relevant events
+that occurred in the last tick.
+-}
+buildGlossRhine
+  :: (Event -> Maybe a) -- ^ The event selector
+  -> GlossSyncSF a      -- ^ The 'SyncSF' representing the game loop.
+  -> GlossRhine a
+buildGlossRhine select syncsfSim
+  =   timeInfoOf tag @@  SelectClock { mainClock = GlossEventClock, .. }
+  >-- collect -@- glossSchedule
+  --> withProperSimClock syncsfSim @@ GlossSimulationClock_
+
+-- | The main function that will start the @gloss@ backend and run the 'SF'.
+flowGloss
+  :: Display      -- ^ Display mode (e.g. 'InWindow' or 'FullScreen').
+  -> Color        -- ^ Background color.
+  -> Int          -- ^ Number of simulation steps per second of real time.
+  -> GlossRhine a -- ^ The @gloss@-compatible 'Rhine'.
+  -> IO ()
+flowGloss display color n Rhine {..}
+  = play display color n world getPic handleEvent simStep
+  where
+    graphicsBuffer
+      :: ResamplingBuffer Identity
+           GlossSimulationClock_ GlossGraphicsClock
+           Picture               Picture
+    graphicsBuffer = keepLast Blank
+    world = createTickable (trivialResamplingBuffer clock) sf graphicsBuffer ()
+    getPic Tickable { buffer2 } = fst $ runIdentity $ get buffer2 $ TimeInfo () () () ()
+    handleEvent event tickable = case select (sequentialCl1 clock) event of
+      Just a  -> runIdentity $ tick tickable () $ Left a -- Event is relevant
+      Nothing -> tickable -- Event is irrelevant, state doesn't change
+    simStep diff tickable = runIdentity $ tick tickable () $ Right diff
diff --git a/src/FRP/Rhine/Gloss/Internals.hs b/src/FRP/Rhine/Gloss/Internals.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Rhine/Gloss/Internals.hs
@@ -0,0 +1,89 @@
+{- | Internals for 'FRP.Rhine.Gloss'.
+You probably won't need this module.
+-}
+{-# LANGUAGE Arrows                #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE NamedFieldPuns        #-}
+{-# LANGUAGE RecordWildCards       #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module FRP.Rhine.Gloss.Internals where
+
+-- base
+import qualified Control.Category as Category
+import Data.Functor.Identity (Identity)
+
+-- dunai
+import Control.Monad.Trans.MSF.Reader (readerS, runReaderS)
+
+-- gloss
+import Graphics.Gloss.Interface.Pure.Game
+
+-- rhine
+import FRP.Rhine
+import FRP.Rhine.Clock.Select
+
+
+-- * Clocks
+
+-- | The error message that gets thrown when you try to start a @gloss@ app with 'flow'.
+errMsg :: String
+errMsg =  "You cannot start gloss apps with FRP.Rhine.flow. "
+       ++ "Use FRP.Rhine.Gloss.flowGloss instead."
+
+-- | The clock that ticks whenever a @gloss@ event occurs.
+data GlossEventClock = GlossEventClock
+
+instance Clock m GlossEventClock where
+  type TimeDomainOf GlossEventClock = ()
+  type Tag          GlossEventClock = Event
+  startClock _ = error errMsg
+
+-- | The clock that ticks for every @gloss@ simulation step,
+--   but only shows the time delta in the tag.
+--   Usually, you don't need this clock, but rather 'GlossSimulationClock'.
+data GlossSimulationClock_ = GlossSimulationClock_
+
+instance Clock m GlossSimulationClock_ where
+  type TimeDomainOf GlossSimulationClock_ = ()
+  type Tag          GlossSimulationClock_ = Float
+  startClock _ = error errMsg
+
+-- | The clock that ticks for every @gloss@ simulation step.
+--   Use 'withProperSimClock' to transform to 'GlossSimulationClock_'.
+data GlossSimulationClock = GlossSimulationClock
+
+instance Clock m GlossSimulationClock where
+  type TimeDomainOf GlossSimulationClock = Float
+  type Tag          GlossSimulationClock = ()
+  startClock _ = error errMsg
+
+-- | To use all features of the 'SyncSF' framework,
+--   write your synchronous stream function on the 'GlossSimulationClock'
+--   and then use this function to transform it.
+withProperSimClock
+  :: Monad m
+  => SyncSF m GlossSimulationClock  a b
+  -> SyncSF m GlossSimulationClock_ a b
+withProperSimClock syncsf = readerS
+  $ (intermingle *** Category.id) >>> runReaderS syncsf
+  where
+    intermingle :: Monad m => MSF m (TimeInfo GlossSimulationClock_) (TimeInfo GlossSimulationClock)
+    intermingle = proc TimeInfo {tag} -> do
+      let sinceTick = tag
+      absolute <- sumS -< sinceTick
+      let sinceStart = absolute
+      returnA          -< TimeInfo { tag = (), .. }
+
+-- | The clock that ticks for every @gloss@ graphics output.
+data GlossGraphicsClock = GlossGraphicsClock
+
+instance Clock m GlossGraphicsClock where
+  type TimeDomainOf GlossGraphicsClock = ()
+  type Tag          GlossGraphicsClock = ()
+  startClock _ = error errMsg
+
+-- | A schedule you can't actually use, for internal purposes.
+glossSchedule :: Schedule Identity (SelectClock GlossEventClock a) GlossSimulationClock_
+glossSchedule = error errMsg
