diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,9 +1,18 @@
 # Revision history for reflex-gadt-api
 
+## 0.2.2.2
+
+* Make Readme part of the library
+* Support GHC 9.10
+* Loosen version bounds
+
+## 0.2.2.1-r1
+
+* Loosen version bounds
+
 ## 0.2.2.1
 
 * Support constraints-extras 0.4
-* Update obelisk version used by example
 
 ## 0.2.2.0
 
diff --git a/Readme.lhs b/Readme.lhs
--- a/Readme.lhs
+++ b/Readme.lhs
@@ -1,9 +1,10 @@
 reflex-gadt-api
 ===============
-[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/reflex-gadt-api.svg)](https://hackage.haskell.org/package/reflex-gadt-api) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/reflex-gadt-api/badge)](https://matrix.hackage.haskell.org/#/package/reflex-gadt-api) [![Travis CI](https://api.travis-ci.org/reflex-frp/reflex-gadt-api.svg?branch=develop)](https://travis-ci.org/reflex-frp/reflex-gadt-api) [![Github CI](https://github.com/reflex-frp/reflex-gadt-api/workflows/Haskell%20CI/badge.svg)](https://github.com/reflex-frp/reflex-gadt-api/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/reflex-frp/reflex-gadt-api/blob/master/LICENSE)
 
+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/reflex-gadt-api.svg)](https://hackage.haskell.org/package/reflex-gadt-api) [![Github CI](https://github.com/reflex-frp/reflex-gadt-api/workflows/Haskell%20CI/badge.svg)](https://github.com/reflex-frp/reflex-gadt-api/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/reflex-frp/reflex-gadt-api/blob/master/LICENSE)
 
 
+
 This package is designed to be used in full-stack Haskell applications where the API is defined as a GADT, the wire format is JSON, and the frontend is using reflex-dom(-core). reflex-gadt-api provides the basic FRP and encoding/decoding infrastructure to support this architecture.
 
 To serialize the GADT API definition, we use [aeson-gadt-th](https://github.com/obsidiansystems/aeson-gadt-th) with a little help from [constraints-extras](https://github.com/obsidiansystems/constraints-extras).
@@ -29,9 +30,9 @@
 > {-# LANGUAGE TemplateHaskell #-}
 > {-# LANGUAGE TypeFamilies #-}
 > {-# LANGUAGE UndecidableInstances #-}
->
+
 > module Readme where
->
+
 > import Control.Monad (void)
 > import Control.Monad.IO.Class (MonadIO)
 > import Control.Monad.Fix (MonadFix)
@@ -39,13 +40,14 @@
 > import Data.Aeson.GADT.TH (deriveJSONGADT)
 > import Data.Constraint.Extras (Has)
 > import Data.Constraint.Extras.TH (deriveArgDict)
+> import Data.Kind (Type)
 > import Data.Text as T (Text, null, pack)
 > import Data.Time (UTCTime, Day)
 > import GHC.Generics (Generic)
 > import Reflex.Dom.Core
 > import Reflex.Dom.GadtApi
->
 
+
 ```
 
 The code that follows would typically go in a common module, since it would be used on the frontend and on the backend. It sets up the basic data type definitions and a couple of GADTs that describe the API.
@@ -59,31 +61,31 @@
 >   , _dog_imageUri :: Maybe Text
 >   }
 >   deriving (Generic)
->
+
 > instance ToJSON Dog
 > instance FromJSON Dog
->
 
+
 ```
 
 Here we have an API for retrieving and interacting with the `Dog` data:
 
 ```haskell
 
-> data DogApi :: * -> * where
+> data DogApi :: Type -> Type where
 >   DogApi_GetByDay :: Day -> DogApi [Dog]
 >   DogApi_GetByName :: Text -> DogApi [Dog]
 >   DogApi_GetLastSeen :: DogApi (Maybe Dog)
 >   DogApi_ReportSighting :: Text -> Bool -> Maybe Text -> DogApi (Either Text ())
 >   DogApi_GetSuspiciousSightings :: DogApi [Dog]
->
+
 > newtype Token = Token { unToken :: Text }
 >   deriving (Generic)
->
+
 > instance ToJSON Token
 > instance FromJSON Token
->
 
+
 ```
 
 We can take the `DogApi` and embed it in another GADT API. This outer API will handle authentication. (Note that we're not actually implementing a secure authentication scheme or anything here. This is just a toy example.)
@@ -93,13 +95,13 @@
 > data CatApi a where
 >   CatApi_Identify :: Text -> CatApi (Either Text Token)
 >   CatApi_DogApi :: Token -> DogApi a -> CatApi a
->
+
 > deriveJSONGADT ''DogApi
 > deriveJSONGADT ''CatApi
 > deriveArgDict ''DogApi
 > deriveArgDict ''CatApi
->
 
+
 ```
 
 On the frontend, we'll run a `RequesterT` widget that allows us to emit an event of requests, and we'll transform those requests into XHR calls to the API endpoint.
@@ -107,8 +109,8 @@
 ```haskell
 
 > type Catnet t m = (RequesterT t CatApi (Either Text) m)
->
 
+
 ```
 
 This synonym is just here for convenience. The right-hand-side describes a `RequesterT` widget that issues `CatApi` requests and receives responses.  In other words, when we're inside this `RequesterT` we can call the `requesting` function to send API requests and receive responses.
@@ -177,8 +179,8 @@
 >       rsp <- dogSighting token
 >       leave <- delay 3 rsp
 >       pure ((), catnetW token <$ leave) -- Go back to catnet
->
 
+
 ```
 
 If you're building your frontend in a context where the user interface needs to be susceptible to server-side rendering (for example, if you're using [obelisk](https://github.com/obsidiansystems/obelisk)'s "prerendering" functionality to serve static pages that are "hydrated" once the JS loads), you'll need to wrap any code relying on Javascript (e.g., your XHR requests) in a `prerender`. The function below does this for us.
@@ -190,8 +192,8 @@
 >   => Event t (Request (Client (Catnet t m)) a)
 >   -> Catnet t m (Event t (Response (Client (Catnet t m)) a))
 > requestingJs r = fmap (switch . current) $ prerender (pure never) $ requesting r
->
 
+
 ```
 
 On the login page, we construct a `Behavior` of a `CatApi_Identify` request and send it when the user clicks the submit button.
@@ -204,7 +206,7 @@
 >   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender t m)
 >   => Catnet t m (Event t Token)
 > login = do
->   el "h1" $ text "Identify Yourself"
+>   el "h1" $ text "Identify Yourself, Cat"
 >   cat <- inputElement def
 >   click <- button "submit"
 >   rsp <- requestingJs $
@@ -213,8 +215,8 @@
 >         Right (Right catToken) -> Just catToken
 >         _ -> Nothing
 >   pure token
->
 
+
 ```
 
 This function builds a UI with a few buttons. Depending on which button is clicked, we'll issue an API request and display the result, with one exception: the "Report a Sighting" button click event is returned (and used by the `Workflow` above to navigate to another page).
@@ -245,8 +247,8 @@
 >     Right dogs -> el "ul" $ mapM_ (el "li" . showDog) dogs
 >   -- Return the "Report a sighting" click event
 >   pure addDog
->
 
+
 ```
 
 The `showDog` widget below does not have `Catnet` or `RequesterT` in its type signature, so we know that it doesn't issue requests. It just builds a display widget for a particular `Dog`.
@@ -267,8 +269,8 @@
 >   el "dd" $ case _dog_imageUri dog of
 >     Just img -> elAttr "img" ("src" =: img <> "alt" =: "dog mugshot") blank
 >     Nothing -> text "None"
->
 
+
 ```
 
 This rudimentary form allows us to assemble a `Dynamic` `DogApi` request, embed it in a `CatApi` request, and send it.
@@ -317,7 +319,7 @@
 >     Right (Left err) -> Left err
 >     Left err -> Left err
 >     Right (Right result) -> Right result
->
+
 > main :: IO ()
 > main = return ()
 
diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -1,9 +1,10 @@
 reflex-gadt-api
 ===============
-[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/reflex-gadt-api.svg)](https://hackage.haskell.org/package/reflex-gadt-api) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/reflex-gadt-api/badge)](https://matrix.hackage.haskell.org/#/package/reflex-gadt-api) [![Travis CI](https://api.travis-ci.org/reflex-frp/reflex-gadt-api.svg?branch=develop)](https://travis-ci.org/reflex-frp/reflex-gadt-api) [![Github CI](https://github.com/reflex-frp/reflex-gadt-api/workflows/Haskell%20CI/badge.svg)](https://github.com/reflex-frp/reflex-gadt-api/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/reflex-frp/reflex-gadt-api/blob/master/LICENSE)
 
+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/reflex-gadt-api.svg)](https://hackage.haskell.org/package/reflex-gadt-api) [![Github CI](https://github.com/reflex-frp/reflex-gadt-api/workflows/Haskell%20CI/badge.svg)](https://github.com/reflex-frp/reflex-gadt-api/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/reflex-frp/reflex-gadt-api/blob/master/LICENSE)
 
 
+
 This package is designed to be used in full-stack Haskell applications where the API is defined as a GADT, the wire format is JSON, and the frontend is using reflex-dom(-core). reflex-gadt-api provides the basic FRP and encoding/decoding infrastructure to support this architecture.
 
 To serialize the GADT API definition, we use [aeson-gadt-th](https://github.com/obsidiansystems/aeson-gadt-th) with a little help from [constraints-extras](https://github.com/obsidiansystems/constraints-extras).
@@ -29,9 +30,9 @@
 > {-# LANGUAGE TemplateHaskell #-}
 > {-# LANGUAGE TypeFamilies #-}
 > {-# LANGUAGE UndecidableInstances #-}
->
+
 > module Readme where
->
+
 > import Control.Monad (void)
 > import Control.Monad.IO.Class (MonadIO)
 > import Control.Monad.Fix (MonadFix)
@@ -39,13 +40,14 @@
 > import Data.Aeson.GADT.TH (deriveJSONGADT)
 > import Data.Constraint.Extras (Has)
 > import Data.Constraint.Extras.TH (deriveArgDict)
+> import Data.Kind (Type)
 > import Data.Text as T (Text, null, pack)
 > import Data.Time (UTCTime, Day)
 > import GHC.Generics (Generic)
 > import Reflex.Dom.Core
 > import Reflex.Dom.GadtApi
->
 
+
 ```
 
 The code that follows would typically go in a common module, since it would be used on the frontend and on the backend. It sets up the basic data type definitions and a couple of GADTs that describe the API.
@@ -59,31 +61,31 @@
 >   , _dog_imageUri :: Maybe Text
 >   }
 >   deriving (Generic)
->
+
 > instance ToJSON Dog
 > instance FromJSON Dog
->
 
+
 ```
 
 Here we have an API for retrieving and interacting with the `Dog` data:
 
 ```haskell
 
-> data DogApi :: * -> * where
+> data DogApi :: Type -> Type where
 >   DogApi_GetByDay :: Day -> DogApi [Dog]
 >   DogApi_GetByName :: Text -> DogApi [Dog]
 >   DogApi_GetLastSeen :: DogApi (Maybe Dog)
 >   DogApi_ReportSighting :: Text -> Bool -> Maybe Text -> DogApi (Either Text ())
 >   DogApi_GetSuspiciousSightings :: DogApi [Dog]
->
+
 > newtype Token = Token { unToken :: Text }
 >   deriving (Generic)
->
+
 > instance ToJSON Token
 > instance FromJSON Token
->
 
+
 ```
 
 We can take the `DogApi` and embed it in another GADT API. This outer API will handle authentication. (Note that we're not actually implementing a secure authentication scheme or anything here. This is just a toy example.)
@@ -93,13 +95,13 @@
 > data CatApi a where
 >   CatApi_Identify :: Text -> CatApi (Either Text Token)
 >   CatApi_DogApi :: Token -> DogApi a -> CatApi a
->
+
 > deriveJSONGADT ''DogApi
 > deriveJSONGADT ''CatApi
 > deriveArgDict ''DogApi
 > deriveArgDict ''CatApi
->
 
+
 ```
 
 On the frontend, we'll run a `RequesterT` widget that allows us to emit an event of requests, and we'll transform those requests into XHR calls to the API endpoint.
@@ -107,8 +109,8 @@
 ```haskell
 
 > type Catnet t m = (RequesterT t CatApi (Either Text) m)
->
 
+
 ```
 
 This synonym is just here for convenience. The right-hand-side describes a `RequesterT` widget that issues `CatApi` requests and receives responses.  In other words, when we're inside this `RequesterT` we can call the `requesting` function to send API requests and receive responses.
@@ -177,8 +179,8 @@
 >       rsp <- dogSighting token
 >       leave <- delay 3 rsp
 >       pure ((), catnetW token <$ leave) -- Go back to catnet
->
 
+
 ```
 
 If you're building your frontend in a context where the user interface needs to be susceptible to server-side rendering (for example, if you're using [obelisk](https://github.com/obsidiansystems/obelisk)'s "prerendering" functionality to serve static pages that are "hydrated" once the JS loads), you'll need to wrap any code relying on Javascript (e.g., your XHR requests) in a `prerender`. The function below does this for us.
@@ -190,8 +192,8 @@
 >   => Event t (Request (Client (Catnet t m)) a)
 >   -> Catnet t m (Event t (Response (Client (Catnet t m)) a))
 > requestingJs r = fmap (switch . current) $ prerender (pure never) $ requesting r
->
 
+
 ```
 
 On the login page, we construct a `Behavior` of a `CatApi_Identify` request and send it when the user clicks the submit button.
@@ -204,7 +206,7 @@
 >   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender t m)
 >   => Catnet t m (Event t Token)
 > login = do
->   el "h1" $ text "Identify Yourself"
+>   el "h1" $ text "Identify Yourself, Cat"
 >   cat <- inputElement def
 >   click <- button "submit"
 >   rsp <- requestingJs $
@@ -213,8 +215,8 @@
 >         Right (Right catToken) -> Just catToken
 >         _ -> Nothing
 >   pure token
->
 
+
 ```
 
 This function builds a UI with a few buttons. Depending on which button is clicked, we'll issue an API request and display the result, with one exception: the "Report a Sighting" button click event is returned (and used by the `Workflow` above to navigate to another page).
@@ -245,8 +247,8 @@
 >     Right dogs -> el "ul" $ mapM_ (el "li" . showDog) dogs
 >   -- Return the "Report a sighting" click event
 >   pure addDog
->
 
+
 ```
 
 The `showDog` widget below does not have `Catnet` or `RequesterT` in its type signature, so we know that it doesn't issue requests. It just builds a display widget for a particular `Dog`.
@@ -267,8 +269,8 @@
 >   el "dd" $ case _dog_imageUri dog of
 >     Just img -> elAttr "img" ("src" =: img <> "alt" =: "dog mugshot") blank
 >     Nothing -> text "None"
->
 
+
 ```
 
 This rudimentary form allows us to assemble a `Dynamic` `DogApi` request, embed it in a `CatApi` request, and send it.
@@ -317,7 +319,7 @@
 >     Right (Left err) -> Left err
 >     Left err -> Left err
 >     Right (Right result) -> Right result
->
+
 > main :: IO ()
 > main = return ()
 
diff --git a/reflex-gadt-api.cabal b/reflex-gadt-api.cabal
--- a/reflex-gadt-api.cabal
+++ b/reflex-gadt-api.cabal
@@ -1,12 +1,12 @@
 cabal-version:      >=1.10
 name:               reflex-gadt-api
-version:            0.2.2.1
+version:            0.2.2.2
 synopsis:           Interact with a GADT API in your reflex-dom application.
 description:
   This package is designed to be used in full-stack Haskell applications where the API is defined as a GADT and the frontend is using reflex-dom.
 
 bug-reports:        https://github.com/reflex-frp/reflex-gadt-api/issues
-license:            BSD3 
+license:            BSD3
 license-file:       LICENSE
 author:             Obsidian Systems
 maintainer:         maintainer@obsidian.systems
@@ -20,26 +20,28 @@
 tested-with:        GHC ==8.6.5 || ==8.8.1 || ==8.10.7
 
 library
-  hs-source-dirs:   src
+  hs-source-dirs:   src, .
   build-depends:
-      aeson               >=1.4.4  && <1.6
+      aeson               >=1.4.4  && <2.3
     , aeson-gadt-th       >=0.2.4  && <0.3
-    , base                >=4.12   && <4.16
-    , bytestring          >=0.10.8 && <0.11
+    , base                >=4.12   && <4.21
+    , bytestring          >=0.10.8 && <0.13
     , constraints-extras  >=0.3.0  && <0.5
-    , containers          >=0.6    && <0.7
-    , data-default        >=0.6    && <0.8
+    , containers          >=0.6    && <0.8
+    , data-default        >=0.6    && <0.9
     , jsaddle             >=0.9.7  && <0.10
-    , reflex              >=0.7    && <0.9
+    , reflex              >=0.7    && <1
     , reflex-dom-core     >=0.7.0  && <0.9
     , some                >=1      && <1.1
-    , text                >=1.2    && <1.3
+    , text                >=1.2    && <2.2
     , time                >=1.6.0  && <2
 
   exposed-modules:
     Reflex.Dom.GadtApi
     Reflex.Dom.GadtApi.WebSocket
     Reflex.Dom.GadtApi.XHR
+
+    Readme
 
   default-language: Haskell2010
   ghc-options:      -Wall
