diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,115 @@
+# scotty-resource
+
+This module defines better resource routing for Scotty.
+
+Scotty is defined in terms of "routes", whereas HTTP is defined in
+terms of "resources".  This package adds a "resource" abstraction to
+the scotty ecosystem.
+
+(note: All examples probably require -XOverloadedStrings)
+
+Scotty comes out of the box with a way to model "routes". The problem
+is that "routes" is not the abstraction used by the HTTP standard and
+it can sometimes be tricky to write a perfectly correct HTTP service
+using the routes model (where "correct" is judged against rfc-2616).
+The most blatant, (and who knows, maybe the only) example of this problem
+is shown by the scotty code:
+
+```haskell
+import Web.Scotty.Trans (get, scottyT, text)
+
+...
+
+scottyT 8080 id $ do
+  get "/hello" $ do
+    text "world"
+```
+
+If a client requests something like `DELETE /hello`, this scotty application
+will return `404 Not Found`, which conflicts with section 5.1.1 of rfc-2616.
+A better response would be `405 Method Not Allowed`, and it would include an
+automatically generated `Allow` response header.
+
+This library gives users a way to model "resources" which is closer to the
+abstractions used in the HTTP standard.
+
+We can re-write the above example like this:
+
+```haskell
+import Web.Scotty.Trans (scottyT, text)
+import Web.Scotty.Resource.Trans (resource, get)
+
+...
+
+scottyT 8080 id $ do
+  resource "/hello" $ do
+    get $ do
+      text "world"
+```
+
+Given a request:
+
+```http
+DELETE /hello HTTP/1.1
+Host: localhost:8080
+```
+
+The resource-based scotty application will produce something like:
+
+```http
+HTTP/1.1 405 Method Not Allowed
+Allow: GET
+```
+
+Each resource is described by a `WebResource` value, which happens to be a
+`Monad`. The only reason `WebResource` implements `Monad` to fit in with the
+do-notation coding style of `ScottyT`. This is an abuse of `Monad`, but, you
+know, whatever. The `Monoid` typeclass more correctly represents what a
+`WebResource` really is. The `Monad` and `Monoid` typeclasses are used to
+compose instances of `WebResource`.
+
+Here is another more complex example, with multiple resources.
+
+```haskell
+import Data.Aeson (decode)
+import Network.HTTP.Types (notFound404, badRequest400, noContent204)
+import Web.Scotty.Resource.Trans (resource, get, post)
+import Web.Scotty.Trans (scottyT, text, body, raw, status, param)
+
+import MyApplication (lookupPerson, storePerson)
+
+...
+
+scottyT 8080 id $ do
+
+  -- an "echo" resource
+  resource "/echo" $ do
+    get $ do
+      text "hello world"
+    post $ do
+      -- echo the request body back to the user
+      raw =<< body
+
+  -- A resource that represents a kind of a RESTful database of people.
+  -- This resource supports GET and PUT.
+  resource "/people/:personId" $ do
+    get $ do
+      personId <- param "personId"
+      maybePerson <- lookupPerson personId
+      case maybePerson of
+        Nothing ->
+          status notFound404
+        Just person ->
+          json person
+    put $ do
+      personId <- param "personId"
+      maybePerson <- decode <$> body
+      case maybePerson of
+        Nothing -> do
+          status badRequest400
+          text "Invalid person JSON"
+        Just person ->
+          storePerson personId person
+          status noContent204
+```
+
diff --git a/scotty-resource.cabal b/scotty-resource.cabal
--- a/scotty-resource.cabal
+++ b/scotty-resource.cabal
@@ -1,39 +1,48 @@
--- Initial scotty-resource.cabal generated by cabal init.  For further 
--- documentation, see http://haskell.org/cabal/users-guide/
-
+cabal-version:       3.0
 name:                scotty-resource
-version:             0.2.0.2
+version:             0.4.0.0
 synopsis:            A Better way of modeling web resources.
 description:         
                      Allows users of the Scotty web framework to model
                      resources more like the HTTP standard models them.
-homepage:            https://github.com/taphu/scotty-resource
+homepage:            https://github.com/owensmurray/scotty-resource
 license:             Apache-2.0
 license-file:        LICENSE
 author:              Rick Owens
-maintainer:          rick@owenssoftware.com
-copyright:           2016 - Rick Owens
+maintainer:          rick@owensmurray.com
+copyright:           2025 Rick Owens
 category:            Web
 build-type:          Simple
--- extra-source-files:  
-cabal-version:       >=1.10
+extra-source-files:
+  README.md
+  LICENSE
 
+common dependencies
+  build-depends:
+    , base         >= 4.14.3.0 && < 4.22
+    , containers   >= 0.5.7.0  && < 0.8
+    , http-types   >= 0.9.1    && < 0.13
+    , scotty       >= 0.20.1   && < 0.23
+    , text         >= 1.2.3.2  && < 2.2
+    , transformers >= 0.5.6.2  && < 0.7
+    , wai          >= 3.2.2.1  && < 3.3
+    , unliftio     >= 0.2.0.0  && < 0.3
+
+common warnings
+  ghc-options:
+    -Wmissing-export-lists
+    -Wredundant-constraints
+    -Wall
+
 library
+  import: dependencies, warnings
   exposed-modules:     
     Web.Scotty.Resource.Trans
-  -- other-modules:       
+  -- other-modules:
   other-extensions:    
     OverloadedStrings
-  build-depends:
-    base         >= 4.8      && < 4.11,
-    containers   >= 0.1.0.0  && < 0.6,
-    http-types   >= 0.8.2    && < 0.13,
-    scotty       >= 0.10     && < 0.12,
-    text         >= 0.11.3.1 && < 1.3,
-    transformers >= 0.3.0.0  && < 0.6,
-    wai          >= 3.0.0    && < 3.3
-  hs-source-dirs: src
-  default-language: Haskell2010
+  hs-source-dirs:      src
+  default-language:    Haskell2010
 
 source-repository head
   type:     git
diff --git a/src/Web/Scotty/Resource/Trans.hs b/src/Web/Scotty/Resource/Trans.hs
--- a/src/Web/Scotty/Resource/Trans.hs
+++ b/src/Web/Scotty/Resource/Trans.hs
@@ -56,8 +56,8 @@
   Each resource is described by a `WebResource` value, which happens to
   be a `Monad`. The only reason `WebResource` implements `Monad` to fit
   in with the do-notation coding style of `ScottyT`. This is an abuse of
-  `Monad`, but, you know, whatever. The `Monoid` typeclass more correctly
-  represents what a `WebResource` really is. The `Monad` and `Monoid`
+  `Monad`, but, you know, whatever. The `Semigroup` typeclass more correctly
+  represents what a `WebResource` really is. The `Monad` and `Semigroup`
   typeclasses are used to compose instances of `WebResource`.
 
   Here is another more complex example, with multiple resources.
@@ -119,25 +119,24 @@
 import Prelude hiding (head)
 
 import Control.Monad (liftM, ap)
-import Control.Monad.IO.Class (MonadIO)
 import Data.List (intersperse)
 import Data.Maybe (fromMaybe)
-import Data.Monoid ((<>))
 import Data.Set (fromList, toList)
 import Data.Text.Encoding (decodeUtf8)
 import Data.Text.Lazy (fromStrict)
 import Network.HTTP.Types (Method, methodNotAllowed405)
 import Network.Wai (requestMethod)
 import Web.Scotty.Trans (ActionT, RoutePattern, ScottyT, matchAny,
-  request, ScottyError, setHeader, status)
+  request, setHeader, status)
+import UnliftIO (MonadUnliftIO)
 
 {- |
   Add a resource whose uri matches the route pattern.
 -}
-resource :: (MonadIO m, ScottyError e)
+resource :: (MonadUnliftIO m)
   => RoutePattern
-  -> WebResource e m ()
-  -> ScottyT e m ()
+  -> WebResource m ()
+  -> ScottyT m ()
 resource uri (W methods ()) = matchAny uri $
     getMethod `liftM` request >>= fromMaybe notAllowed
   where
@@ -162,29 +161,28 @@
 
 {- |
   An opaque representation of an http resource. Use `get`, `post`, etc. to
-  create one of these. Use the `Monad` or `Monoid` instances to compose them.
+  create one of these. Use the `Monad` or `Semigroup` instances to compose them.
 -}
-data WebResource e m a = W [(Method, ActionT e m ())] a
-instance Functor (WebResource e m) where
+data WebResource m a = W [(Method, ActionT m ())] a
+instance Functor (WebResource m) where
   fmap = liftM
-instance Applicative (WebResource e m) where
-  pure = return
+instance Applicative (WebResource m) where
+  pure = W []
   (<*>) = ap
-instance Monad (WebResource e m) where
-  return = W []
+instance Monad (WebResource m) where
+  return = pure
   W methods a >>= f =
     let W newMethods b = f a
     in W (methods <> newMethods) b
-instance Monoid (WebResource e m a) where
-  mempty = W mempty undefined
-  mappend (W a _) (W b _) = W (a <> b) undefined
+instance Semigroup (WebResource m a) where
+  W a _ <> W b c = W (a <> b) c
 
 
 {- |
   Create a `WebResource` that handles OPTIONS requests using the given
   scotty action.
 -}
-options :: ActionT e m () -> WebResource e m ()
+options :: ActionT m () -> WebResource m ()
 options action = W [("OPTIONS", action)] ()
 
 
@@ -192,7 +190,7 @@
   Create a `WebResource` that handles GET requests using the given
   scotty action.
 -}
-get :: ActionT e m () -> WebResource e m ()
+get :: ActionT m () -> WebResource m ()
 get action = W [("GET", action)] ()
 
 
@@ -200,7 +198,7 @@
   Create a `WebResource` that handles HEAD requests using the given
   scotty action.
 -}
-head :: ActionT e m () -> WebResource e m ()
+head :: ActionT m () -> WebResource m ()
 head action = W [("HEAD", action)] ()
 
 
@@ -208,7 +206,7 @@
   Create a `WebResource` that handles POST requests using the given
   scotty action.
 -}
-post :: ActionT e m () -> WebResource e m ()
+post :: ActionT m () -> WebResource m ()
 post action = W [("POST", action)] ()
 
 
@@ -216,7 +214,7 @@
   Create a `WebResource` that handles PUT requests using the given
   scotty action.
 -}
-put :: ActionT e m () -> WebResource e m ()
+put :: ActionT m () -> WebResource m ()
 put action = W [("PUT", action)] ()
 
 
@@ -224,7 +222,7 @@
   Create a `WebResource` that handles DELETE requests using the given
   scotty action.
 -}
-delete :: ActionT e m () -> WebResource e m ()
+delete :: ActionT m () -> WebResource m ()
 delete action = W [("DELETE", action)] ()
 
 
@@ -232,7 +230,7 @@
   Create a `WebResource` that handles PATCH requests using the given
   scotty action.
 -}
-patch :: ActionT e m () -> WebResource e m ()
+patch :: ActionT m () -> WebResource m ()
 patch action = W [("PATCH", action)] ()
 
 
@@ -240,7 +238,7 @@
   Create a `WebResource` that handles the specific method using the given
   scotty action.
 -}
-method :: Method -> ActionT e m () -> WebResource e m ()
+method :: Method -> ActionT m () -> WebResource m ()
 method m action = W [(m, action)] ()
 
 
