diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@
 
 ### Windows
 
-Please see the [detailed Windows installation instructions](http://hackage.haskell.org/package/fltkhs/docs/Graphics-UI-FLTK-LowLevel-FLTKHS.html#g:8)
+Please see the [detailed Windows installation instructions](http://hackage.haskell.org/package/fltkhs/docs/Graphics-UI-FLTK-LowLevel-FLTKHS.html#g:8).
 
 Screenshots
 -----------
@@ -35,7 +35,7 @@
 
 [A table of widgets](images/widget-table-windows.png)
 
-[A complex tree](images/tree-complex-windows.png) Done completely using Fluid. Notice how tree nodes can be arbitrary widgets.
+[A complex tree](images/tree-complex-windows.png) done completely using Fluid. Notice how tree nodes can be arbitrary widgets.
 
 Demos
 -----
diff --git a/c-src/Makefile.in b/c-src/Makefile.in
--- a/c-src/Makefile.in
+++ b/c-src/Makefile.in
@@ -157,7 +157,7 @@
 	test -d $(LIBDIR) || mkdir $(LIBDIR)
 	@echo "*** Linking $@..."
 	(cd $(SHARED_OBJECT_FILES); \
-	$(CXX)  -Wno-attributes -Wall $(SONAME_FLAGS),$(LIBDIR)/$@ -o $(LIBDIR)/$@ $^ -L/usr/local/lib $(FLTKCONFIGCOMMAND));
+	$(CXX)  -Wno-attributes -Wall $(SONAME_FLAGS),$(LIBDIR)/$@ -o $(LIBDIR)/$@ $^ $(FLTKCONFIGCOMMAND) -L/usr/local/lib);
 clean:
 	test -d $(LIBDIR) && rm -rf $(LIBDIR)
 	test -d $(SHARED_OBJECT_FILES) && rm -rf $(SHARED_OBJECT_FILES)
diff --git a/fltkhs.cabal b/fltkhs.cabal
--- a/fltkhs.cabal
+++ b/fltkhs.cabal
@@ -1,5 +1,5 @@
 name : fltkhs
-version : 0.5.3.4
+version : 0.5.3.5
 synopsis : FLTK bindings
 description: Low level bindings for the FLTK GUI toolkit. For installation and quick start instruction please scroll all the way down to the README.
 license : MIT
@@ -30,9 +30,9 @@
 custom-setup
   setup-depends:
     base >= 4.5 && < 4.11,
-    Cabal < 1.25,
+    Cabal >= 1.24.1 && < 1.25,
     filepath,
-    directory
+    directory >= 1.2.3.0
 
 library
   if flag(opengl)
diff --git a/src/Graphics/UI/FLTK/LowLevel/FL.chs b/src/Graphics/UI/FLTK/LowLevel/FL.chs
--- a/src/Graphics/UI/FLTK/LowLevel/FL.chs
+++ b/src/Graphics/UI/FLTK/LowLevel/FL.chs
@@ -10,6 +10,7 @@
      selectionOwner,
      setSelectionOwner,
      run,
+     replRun,
      check,
      ready,
      option,
@@ -67,6 +68,7 @@
 #endif
      wait,
      setWait,
+     waitFor,
      readqueue,
      addTimeout,
      repeatTimeout,
@@ -203,6 +205,7 @@
 import qualified Data.Text as T
 import qualified Data.Text.Foreign as TF
 import qualified System.IO.Unsafe as Unsafe (unsafePerformIO)
+import Control.Exception(catch, throw, AsyncException(UserInterrupt))
 #c
  enum Option {
    OptionArrowFocus = OPTION_ARROW_FOCUS,
@@ -324,9 +327,11 @@
 isScheme sch = TF.withCStringLen sch $ \(str,_) -> {#call Fl_is_scheme as fl_is_scheme #} str >>= return . toBool
 {# fun Fl_wait as wait
        {  } -> `Int' #}
-{# fun Fl_set_wait as setWait
+{# fun Fl_set_wait as waitFor
        { `Double' } -> `Double' #}
 
+setWait :: Double -> IO Double
+setWait = waitFor
 {# fun Fl_scrollbar_size as scrollbarSize
        {  } -> `Int' #}
 {# fun Fl_set_scrollbar_size as setScrollbarSize
@@ -927,3 +932,23 @@
 setUseHighResGL use' = {#call Fl_set_use_high_res_GL as fl_set_use_high_res_GL #} (cFromBool use')
 #endif
 #endif
+
+
+-- | Use this function to run a GUI in GHCi.
+replRun :: IO ()
+replRun = do
+  flush
+  w <- firstWindow
+  case w of
+    Just w' ->
+      catch (waitFor 0 >> replRun)
+            (\e -> if (e == UserInterrupt)
+                   then do
+                     allToplevelWindows [] (Just w') >>= mapM_ deleteWidget
+                     flush
+                   else throw e)
+    Nothing -> return ()
+  where
+    allToplevelWindows :: [Ref Window] -> Maybe (Ref Window) -> IO [Ref Window]
+    allToplevelWindows ws (Just w) = nextWindow w >>= allToplevelWindows (w:ws)
+    allToplevelWindows ws Nothing = return ws
diff --git a/src/Graphics/UI/FLTK/LowLevel/FLTKHS.hs b/src/Graphics/UI/FLTK/LowLevel/FLTKHS.hs
--- a/src/Graphics/UI/FLTK/LowLevel/FLTKHS.hs
+++ b/src/Graphics/UI/FLTK/LowLevel/FLTKHS.hs
@@ -70,7 +70,7 @@
 
          -- * Running in the REPL
          --
-         -- $CabalREPLIssues
+         -- $REPL
 
          -- * Core Types
          module Graphics.UI.FLTK.LowLevel.Fl_Types,
@@ -1217,3 +1217,42 @@
 --           - LowLevel      -- Haskell bindings
 --   - scripts               -- various helper scripts (probably not interesting to anyone but myself)
 -- @
+
+-- $REPL
+-- Running GUIs in GHCi is fully supported. Using the <https://github.com/deech/fltkhs-hello-world hello world skeleton> as
+-- an example the following steps will run it in the REPL:
+--
+-- @
+-- > git clone http://github.com/deech/fltkhs-hello-world
+-- > cd fltkhs-hello-world
+-- > stack build --flag fltkhs:bundled
+-- > stack ghci --flag fltkhs:bundled fltkhs-hello-world:exe:fltkhs-hello-world
+-- [1 of 1] Compiling Main ...
+-- Ok, modules loaded: Main ...
+-- Loaded GHCi configuration ...
+-- Prelude Main> replMain
+-- @
+--
+-- Unfortunately since FLTKHS is hybrid Haskell/C++ there are limitations compared to
+-- running a plain 'ol Haskell library on the REPL:
+--
+--    1. The 'stack build ...' is an essential first step before running 'stack
+--       ghci ...'. The reason is it uses '-fobject-code' to link in all the C++
+--       libraries which must be built first.
+--    2. The use of 'replMain' instead of just ':main' as you might expect. This
+--       is because
+--
+--            (1) it allows closing the GUI to correctly return control to
+--                the REPL prompt and
+--            (2) typing 'Ctrl-C' also correctly hands control back to the REPL.
+--
+--       With just ':main' (1) works but (2) results in a "ghosted" UI where the
+--       GUI window is still visible but unable to accept any keyboard/mouse
+--       input. The reason for the ghosted GUI is that ':main' delegates to the
+--       FLTK C++ event loop which is unable to listen for user interrupts on
+--       the Haskell side and so has no of knowing that it should destroy
+--       itself.'replMain' emulates the event loop on the Haskell side allowing
+--       it to stop, clean up and return control when it 'catch'es a
+--       'UserInterrupt'. Thus the 'replMain' is slower than the optimized C++
+--       event loop but hopefully that's not too big an impediment for REPL
+--       work.
diff --git a/src/TestPrograms/Buttons.hs b/src/TestPrograms/Buttons.hs
--- a/src/TestPrograms/Buttons.hs
+++ b/src/TestPrograms/Buttons.hs
@@ -1,11 +1,11 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Main where
 
-import Graphics.UI.FLTK.LowLevel.FL
+import Graphics.UI.FLTK.LowLevel.FL as FL
 import Graphics.UI.FLTK.LowLevel.FLTKHS
 
-main :: IO ()
-main = do
+ui :: IO ()
+ui = do
      window <- windowNew
                 (Size (Width 320) (Height 170))
                 Nothing
@@ -34,5 +34,8 @@
            (Just "Fl_Check_Button")
      end window
      showWidget window
-     _ <- run
+     _ <- FL.run
      return ()
+
+main :: IO ()
+main = ui >> FL.flush
