diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -14,16 +14,8 @@
 
 ## Installation
 
-The package can be compiled with [stack](https://haskellstack.org/)
-using the shipped `stack.yaml` as follows:
-
-```Shell
-$ stack install
-```
-
-The build process has mostly been tested using stack, but it should
-also work using [cabal-install](https://www.haskell.org/cabal/) or
-other standard `Cabal`-based package managers.
+reflex-gi-gtk is a regular cabal library and can be added to your project by
+listing `reflex-gi-gtk` in your project's `build-depends`.
 
 ## Quick start
 
@@ -76,7 +68,7 @@
 You can also start obtaining reactive inputs from widget signals:
 
 ```Haskell
-  text1 <- dynamicOnSignal "" input1 #changed $ \fire -> labelGetText input1 >>= fire
+  text1 <- dynamicOnSignal "" input1 #changed $ \fire -> entryGetText input1 >>= fire
   text2 <- dynamicOnAttribute input2 #text
 ```
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,9 @@
+# 0.2.0.1
+
+* Add support for GHC 9.6.
+
+* Update Reflex version to 0.9.
+
 # 0.2.0.0
 
 * Initial release
diff --git a/example/Main.hs b/example/Main.hs
--- a/example/Main.hs
+++ b/example/Main.hs
@@ -2,8 +2,6 @@
 {-# LANGUAGE TypeFamilies #-}
 module Main where
 
-import Control.Applicative (liftA2)
-import Control.Monad (join)
 import qualified Data.Map.Lazy as M
 import qualified Data.List.NonEmpty as NE
 import qualified Data.Text as T
@@ -18,6 +16,7 @@
               , mergeList
               , performEvent_
               , switch
+              , joinDynThroughMap
               )
 import Reflex.GI.Gtk ( ReactiveAttrOp((:==))
                      , MonadReflexGtk
@@ -91,7 +90,7 @@
                                      , M.fromList . map (,Nothing) . NE.toList <$> delete
                                      ]
             inputWidgets <-
-              listHoldWithKey (M.singleton 0 ()) inputWidgetUpdates $ \k () -> do
+              listHoldWithKey (M.singleton 0 ()) inputWidgetUpdates $ \k () ->
               (\(widget, text, delete') -> (widget, text, k <$ delete')) <$> stringInput
 
             let delete = switch $ mergeList . map (\(_, _, d) -> d) . M.elems
@@ -100,11 +99,11 @@
           sinkBoxUniform inputBox (M.map (\(w, _, _) -> w) <$> inputWidgets)
             False False 0 Gtk.PackTypeStart
 
-          outputWidgets <- list (M.map (\(_, t, _) -> t) <$> inputWidgets) 
-            $ \textBB -> do
-            let textB = join textBB
+          let inputTexts = joinDynThroughMap (M.map (\(_, t, _) -> t) <$> inputWidgets)
+
+          outputWidgets <- list inputTexts $ \textDyn -> do
             label <- runGtk $ Gtk.labelNew Nothing
-            sink label [#label :== textB]
+            sink label [#label :== textDyn]
             #show label
             pure label
           sinkBoxUniform outputBox outputWidgets True True 10 Gtk.PackTypeStart
diff --git a/reflex-gi-gtk.cabal b/reflex-gi-gtk.cabal
--- a/reflex-gi-gtk.cabal
+++ b/reflex-gi-gtk.cabal
@@ -1,5 +1,5 @@
 name:                reflex-gi-gtk
-version:             0.2.0.0
+version:             0.2.0.1
 synopsis:            Helper functions to use reflex with gi-gtk
 description:
   This package provides a a reflex host and helper
@@ -36,23 +36,23 @@
                      , Reflex.GI.Gtk.Run.Class
                      , Reflex.GI.Gtk.Widget.Ord
   build-depends:       async ^>= 2.2.2
-                     , base ^>= 4.13
+                     , base >= 4.13 && < 5
                      , containers ^>= 0.6.2
                      , dependent-sum ^>= 0.7.1
                      , exception-transformers ^>= 0.4
                      , gi-gdk ^>= 3.0
                      , gi-glib ^>= 2.0
                      , gi-gtk ^>= 3.0
-                     , haskell-gi-base ^>= 0.24
-                     , mtl ^>= 2.2.2
+                     , haskell-gi-base >= 0.24 && < 0.27
+                     , mtl ^>= 2.2.2 || ^>= 2.3
                      , primitive ^>= 0.7
-                     , ref-tf ^>= 0.4
-                     , reflex ^>= 0.8
-                     , semialign ^>= 1.1
+                     , ref-tf ^>= 0.4 || ^>= 0.5
+                     , reflex ^>= 0.8 || ^>= 0.9
+                     , semialign >= 1.1 && < 1.4
                      , stm ^>= 2.5
-                     , text ^>= 1.2.4
-                     , these ^>= 1.1.1
-                     , witherable ^>= 0.3.5
+                     , text >= 1.2.4 && < 2.1
+                     , these ^>= 1.1.1 || ^>= 1.2
+                     , witherable ^>= 0.3.5 || ^>= 0.4
   default-language:    Haskell2010
 
 executable reflex-gi-gtk-example
@@ -60,15 +60,16 @@
   main-is:             Main.hs
   default-language:    Haskell2010
   build-depends:       reflex-gi-gtk
-                     , base ^>= 4.13
+                     , base >= 4.13 && < 5
                      , containers ^>= 0.6.2
                      , dependent-sum ^>= 0.7.1
                      , gi-gtk ^>= 3.0
-                     , haskell-gi-base ^>= 0.24.5
-                     , mtl ^>= 2.2.2
+                     , haskell-gi-base >= 0.24.5 && < 0.27
+                     , mtl ^>= 2.2.2 || ^>= 2.3
                      , patch ^>= 0.0
-                     , reflex ^>= 0.8
-                     , text ^>= 1.2.4
+                     , reflex ^>= 0.9
+                     , text >= 1.2.4 && < 2.1
+  ghc-options:         -threaded
 
 source-repository head
   type:     git
diff --git a/src/Reflex/GI/Gtk/Host.hs b/src/Reflex/GI/Gtk/Host.hs
--- a/src/Reflex/GI/Gtk/Host.hs
+++ b/src/Reflex/GI/Gtk/Host.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE RankNTypes, FlexibleContexts, OverloadedLabels, RecursiveDo #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving, FlexibleInstances, PolyKinds #-}
 {-# LANGUAGE MultiParamTypeClasses, UndecidableInstances, GADTs, ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
 
 {-|
 Description : Execute monadic actions with access to reactive operators on GTK
@@ -45,6 +46,7 @@
                           , (==>)
                           )
 import Data.Function (fix)
+import Data.Kind (Type)
 import Data.GI.Base.Signals (disconnectSignalHandler)
 import Data.Int (Int32)
 import Data.Maybe (catMaybes)
@@ -110,7 +112,7 @@
 -- Your probably want to look at 'ReflexGtk', as it is the only
 -- specialization of this type that can be executed using
 -- 'runReflexGtk'.
-newtype ReflexGtkT (t :: *) (m :: k) a = ReflexGtkT
+newtype ReflexGtkT (t :: Type) (m :: k) a = ReflexGtkT
   { unReflexGtkT :: PostBuildT t (TriggerEventT t (RunGtkT (PerformEventT t m))) a
   }
   deriving (Functor, Applicative, Monad, MonadFix)
@@ -225,7 +227,7 @@
                        fmap (==> x) <$> readRef (unEventTriggerRef triggerRef)
                    ) invocations
         _ <- fireCommand triggers $ pure ()
-        liftIO $ mapM_ (\(_ :=> (TriggerInvocation _ done)) -> done) invocations
+        liftIO $ mapM_ (\(_ :=> TriggerInvocation _ done) -> done) invocations
         loop
     pure ()
 
diff --git a/src/Reflex/GI/Gtk/Input.hs b/src/Reflex/GI/Gtk/Input.hs
--- a/src/Reflex/GI/Gtk/Input.hs
+++ b/src/Reflex/GI/Gtk/Input.hs
@@ -3,6 +3,7 @@
 -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
 
 {-# LANGUAGE ConstraintKinds, GADTs, FlexibleContexts, MultiParamTypeClasses #-}
+{-# LANGUAGE TypeOperators #-}
 
 {-|
 Description : Obtain reactive inputs from GLib signals
diff --git a/src/Reflex/GI/Gtk/Output.hs b/src/Reflex/GI/Gtk/Output.hs
--- a/src/Reflex/GI/Gtk/Output.hs
+++ b/src/Reflex/GI/Gtk/Output.hs
@@ -3,7 +3,7 @@
 -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
 
 {-# LANGUAGE RankNTypes, KindSignatures, DataKinds, ConstraintKinds, FlexibleContexts, GADTs #-}
-{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies, FlexibleInstances, TypeOperators #-}
 
 {-|
 Description : Output reactive values to attributes of GTK widgets
@@ -46,8 +46,8 @@
 import Data.GI.Base.Overloading ( HasAttributeList
                                 , ResolveAttribute
                                 )
-import Data.Witherable (catMaybes)
 import GHC.TypeLits (Symbol)
+import Witherable (catMaybes)
 import Reflex ( Dynamic
               , Event
               , PerformEvent
diff --git a/src/Reflex/GI/Gtk/Run/Base.hs b/src/Reflex/GI/Gtk/Run/Base.hs
--- a/src/Reflex/GI/Gtk/Run/Base.hs
+++ b/src/Reflex/GI/Gtk/Run/Base.hs
@@ -37,6 +37,7 @@
                          , try
                          )
 import Control.Monad ( join
+                     , unless
                      , void
                      )
 import Control.Monad.Exception (MonadException)
@@ -132,9 +133,9 @@
   performEvent_ = RunGtkT . performEvent_ . fmap unGtkT
 
 instance (MonadIO m) => MonadRunGtk (RunGtkT m) where
-  runGtk a = askRunGtk >>= liftIO . ($a)
-  runGtk_ a = askRunGtk_ >>= liftIO . ($a)
-  runGtkPromise a = askRunGtkPromise >>= liftIO . fmap liftIO . ($a)
+  runGtk a = askRunGtk >>= liftIO . ($ a)
+  runGtk_ a = askRunGtk_ >>= liftIO . ($ a)
+  runGtkPromise a = askRunGtkPromise >>= liftIO . fmap liftIO . ($ a)
 
 askRunGtk :: (Monad m) => RunGtkT m (IO a -> IO a)
 askRunGtk = (join .) <$> askRunGtkPromise
@@ -173,9 +174,7 @@
       fireAsynchronously x $ atomically $ writeTVar firedTVar True
       let waitCompleted = do
             hasFired <- readTVar firedTVar
-            if hasFired
-              then pure ()
-              else retry
+            unless hasFired retry
       iAmGtkThread <- isThreadMe gtkThread'
       fix $ \loop -> join $ atomically $
         (pure () <$ waitCompleted)
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,27 +1,10 @@
-resolver: lts-16.27
+resolver: lts-22.12
 
 packages:
   - .
 
 extra-deps:
-  - reflex-0.8.0.0
-  - constraints-extras-0.3.0.2
-  - dependent-map-0.4.0.0
-  - dependent-sum-0.7.1.0
-  - monoidal-containers-0.6.0.1
-  - patch-0.0.3.2
-  - prim-uniq-0.2
-  - ref-tf-0.4.0.2
-  - witherable-0.3.5
-  - haskell-gi-base-0.24.5
-  - haskell-gi-0.24.7
-  - gi-pango-1.0.23
-  - gi-harfbuzz-0.0.3
-  - gi-gtk-3.0.36
-  - gi-gobject-2.0.25
-  - gi-glib-2.0.24
-  - gi-gio-2.0.27
-  - gi-gdkpixbuf-2.0.24
-  - gi-gdk-3.0.23
-  - gi-cairo-1.0.24
-  - gi-atk-2.0.22
+  - reflex-0.9.3.0
+  - patch-0.0.8.2
+  - constraints-0.13.4
+  - primitive-0.7.4.0
diff --git a/stack.yaml.lock b/stack.yaml.lock
--- a/stack.yaml.lock
+++ b/stack.yaml.lock
@@ -5,155 +5,36 @@
 
 packages:
 - completed:
-    hackage: reflex-0.8.0.0@sha256:e50de03568818072e2811211431ffe9811aeed69f3b24104b1dafb1b6fd0a525,11942
-    pantry-tree:
-      size: 4587
-      sha256: 41a690372195eecda7bc9631a3724bc8a60a47a765e5c4e7a7ef8bdaf6a6eae9
-  original:
-    hackage: reflex-0.8.0.0
-- completed:
-    hackage: constraints-extras-0.3.0.2@sha256:013b8d0392582c6ca068e226718a4fe8be8e22321cc0634f6115505bf377ad26,1853
-    pantry-tree:
-      size: 594
-      sha256: 3ce1012bfb02e4d7def9df19ce80b8cd2b472c691b25b181d9960638673fecd1
-  original:
-    hackage: constraints-extras-0.3.0.2
-- completed:
-    hackage: dependent-map-0.4.0.0@sha256:ca2b131046f4340a1c35d138c5a003fe4a5be96b14efc26291ed35fd08c62221,1657
-    pantry-tree:
-      size: 551
-      sha256: 5defa30010904d2ad05a036f3eaf83793506717c93cbeb599f40db1a3632cfc5
-  original:
-    hackage: dependent-map-0.4.0.0
-- completed:
-    hackage: dependent-sum-0.7.1.0@sha256:5599aa89637db434431b1dd3fa7c34bc3d565ee44f0519bfbc877be1927c2531,2068
-    pantry-tree:
-      size: 290
-      sha256: 9cbfb32b5a8a782b7a1c941803fd517633cb699159b851c1d82267a9e9391b50
-  original:
-    hackage: dependent-sum-0.7.1.0
-- completed:
-    hackage: monoidal-containers-0.6.0.1@sha256:ffdfae0fde7a08e9e314667a78d86454d2d23137d85f226ec6e757c190fb28ad,2583
-    pantry-tree:
-      size: 569
-      sha256: 61d5a73cb768aa4d59db7365418a2fc1bb24b8c3e53ca496372656b6ba4d31ab
-  original:
-    hackage: monoidal-containers-0.6.0.1
-- completed:
-    hackage: patch-0.0.3.2@sha256:b4d3a60db88a04030392a06076defb9fe310a79577df7ff63ea2bb0298817b8d,2452
-    pantry-tree:
-      size: 977
-      sha256: b9ab71b93cdff84a75c9d251513b4d64a9fea5b89526ecbec60eb9ae04521478
-  original:
-    hackage: patch-0.0.3.2
-- completed:
-    hackage: prim-uniq-0.2@sha256:7bfd8a729812bf212610b63459b76a086ecd5ce48f48d785c288e082d055d47b,1403
-    pantry-tree:
-      size: 464
-      sha256: aa27fb2f22141bd9bb474091f811badd9c71c52a1504fb81834aeb28cecff626
-  original:
-    hackage: prim-uniq-0.2
-- completed:
-    hackage: ref-tf-0.4.0.2@sha256:69de3550250e0cd69f45d080359cb314a9487c915024349c75b78732bbee9332,1134
-    pantry-tree:
-      size: 211
-      sha256: fc5a4a35b4c782a33f452c1dc66ffa8ddbf321e2db369bd8823c796f0d4d8c7f
-  original:
-    hackage: ref-tf-0.4.0.2
-- completed:
-    hackage: witherable-0.3.5@sha256:6590a15735b50ac14dcc138d4265ff1585d5f3e9d3047d5ebc5abf4cd5f50084,1476
-    pantry-tree:
-      size: 271
-      sha256: b99f21dbac28da031eb7c787fbffbe5e77e0aee42b64b5dda082470e907d5ab5
-  original:
-    hackage: witherable-0.3.5
-- completed:
-    hackage: haskell-gi-base-0.24.5@sha256:f289ee14d99bc91daaf15a72533def379e1f5c6e51e9eff0d67e57912816ce74,2435
-    pantry-tree:
-      size: 1937
-      sha256: ddb1858a395755bb14438f39718df2f95042f492a55b6dc0f9343435f758613c
-  original:
-    hackage: haskell-gi-base-0.24.5
-- completed:
-    hackage: haskell-gi-0.24.7@sha256:d1cf3e64589c9c366228f8fe89d2d48207b3ca11b48966ef976fedfa679a819b,5241
-    pantry-tree:
-      size: 4348
-      sha256: c6db02339d61f70cfb687c7786c4441b9fa2658ce4b4aac19395f2e939ed8f1b
-  original:
-    hackage: haskell-gi-0.24.7
-- completed:
-    hackage: gi-pango-1.0.23@sha256:160443e93def8aa95e66fe1de40d51bb12ee922f7cafe6e33d6009f5490c66c5,8233
-    pantry-tree:
-      size: 360
-      sha256: fc5b1f6835549f148284950ab540df9d9f4d7a75df958b5de5e4c01d922dcb37
-  original:
-    hackage: gi-pango-1.0.23
-- completed:
-    hackage: gi-harfbuzz-0.0.3@sha256:0550f498854b7edac66b1a09f283e5b5c86033aff58b4ac30b024ae59e1bd866,5869
-    pantry-tree:
-      size: 364
-      sha256: f33e284484ab7520bb115508fe1ddae5585e42aa292c97f4f6abb2e7ec3d60eb
-  original:
-    hackage: gi-harfbuzz-0.0.3
-- completed:
-    hackage: gi-gtk-3.0.36@sha256:ed4525766763f290aa03ae19e41a31c429a8d381729d4869e7c44e551351df6a,39016
-    pantry-tree:
-      size: 359
-      sha256: cd1718b99526699f158dce646c2c20cf51eedca7f78c33f8d6290e2ba46ccbb4
-  original:
-    hackage: gi-gtk-3.0.36
-- completed:
-    hackage: gi-gobject-2.0.25@sha256:95ca4fd52538ad9b41e54fc9324a93fd680052f8ebb25811e3dc6f8a94bff009,9349
-    pantry-tree:
-      size: 364
-      sha256: 3187d2ae59029b353e1fa134cd7716e4602483d2f1b86fee02c957b4a0065e2b
-  original:
-    hackage: gi-gobject-2.0.25
-- completed:
-    hackage: gi-glib-2.0.24@sha256:46726f0fb6b0ef0d6f6620d53025a9ca2a5bc273ab65496b368df7bc3dbe6d83,9558
-    pantry-tree:
-      size: 358
-      sha256: b51e43df984a63058ca529a99875a3c42a37827cf11694542abf77586cf28532
-  original:
-    hackage: gi-glib-2.0.24
-- completed:
-    hackage: gi-gio-2.0.27@sha256:6535951e2ad0882bc7231da56457be52a85e99cb56acec9ec9919f1c15bed728,21981
-    pantry-tree:
-      size: 359
-      sha256: 75d3bd5fc1f9c00268537219d309ca289666da051835f6813bb636cebf4f1191
-  original:
-    hackage: gi-gio-2.0.27
-- completed:
-    hackage: gi-gdkpixbuf-2.0.24@sha256:287c7233cfecb69a6aff0fb6a952862d759b5562b488bb8046229ee0f4372c6f,3842
+    hackage: reflex-0.9.3.0@sha256:e0c67fbdd4e270a1a04e3fb7bab03ac431052e9a28296bd55659204a27fa44cb,12252
     pantry-tree:
-      size: 368
-      sha256: 9819be48b98d91cc69d84a9cc7c997262443e1c4d37a224a3a2f12b55c877740
+      sha256: e98a56416059f1c04d6c746a96977121dee47cf1caeb922196c438bcd5fe5efe
+      size: 4664
   original:
-    hackage: gi-gdkpixbuf-2.0.24
+    hackage: reflex-0.9.3.0
 - completed:
-    hackage: gi-gdk-3.0.23@sha256:33ad689aa6e1463c57946762016a789b6cb663df174e31f9705956a9385b7b0f,9003
+    hackage: patch-0.0.8.2@sha256:629479fb09e451570d4f7b2f581c37b16cb5ff131881f632138a199d8dcfe794,3338
     pantry-tree:
-      size: 355
-      sha256: 11ff63701019ed413a143b84849f058a83770ba251c8f5743a7edf5d252a1049
+      sha256: f39897e2021c8207dc02341d54c8ea2720a0ae98a1e8e6f82a8d894f4e2cb959
+      size: 1179
   original:
-    hackage: gi-gdk-3.0.23
+    hackage: patch-0.0.8.2
 - completed:
-    hackage: gi-cairo-1.0.24@sha256:451ba2f6f0954805c6d38f1e0bffd849607160e824abf4e077a95e999ef237dd,3727
+    hackage: constraints-0.13.4@sha256:0d8834307bb6798ac937955c00155c26d671b5df147f5622d335d1094290fd36,2504
     pantry-tree:
-      size: 358
-      sha256: 3e8d149deabf1894faec5b3e9e35869ad8174f911be659c9766b183b92770994
+      sha256: c74dab1ffbdd096ee0d71ce9662be556d8d37d7d65428de565a062efc8dd64f0
+      size: 867
   original:
-    hackage: gi-cairo-1.0.24
+    hackage: constraints-0.13.4
 - completed:
-    hackage: gi-atk-2.0.22@sha256:6ec2197aee4a1b5966302fc2875be05a9b3a54f694c4a6a9a330f4b0211223c5,6791
+    hackage: primitive-0.7.4.0@sha256:c2f0ed97b3dce97f2f43b239c3be8b136e4368f1eb7b61322ee9ac98f604622b,2982
     pantry-tree:
-      size: 355
-      sha256: b1398e06f447003ef9c9dde64ebae1cab214db2b20a179a85837604ddb0ac12b
+      sha256: 1cd1f40729b3038f1140fbf506ce59ab2db3f745b1727e0beba6390621aa9630
+      size: 1655
   original:
-    hackage: gi-atk-2.0.22
+    hackage: primitive-0.7.4.0
 snapshots:
 - completed:
-    size: 533252
-    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/27.yaml
-    sha256: c2aaae52beeacf6a5727c1010f50e89d03869abfab6d2c2658ade9da8ed50c73
-  original: lts-16.27
+    sha256: e2c529ccfb21501f98f639e056cbde50470b86256d9849d7a82d414ca23e4276
+    size: 712898
+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/12.yaml
+  original: lts-22.12
