scotty
Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp
https://github.com/scotty-web/scotty
| Version on this page: | 0.11.0@rev:2 | 
| LTS Haskell 24.18: | 0.22@rev:2 | 
| Stackage Nightly 2025-11-04: | 0.22@rev:2 | 
| Latest on Hackage: | 0.22@rev:2 | 
scotty-0.11.0@sha256:d26457a20e549b7577daf798b5bd7cdfca4e6b21e39b345175b7841e7660d22e,4394Module documentation for 0.11.0
- Web
- Web.Scotty
- Web.Scotty.Internal
 - Web.Scotty.Trans
 
 
 - Web.Scotty
 
Scotty 

A Haskell web framework inspired by Ruby’s Sinatra, using WAI and Warp.
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Data.Monoid (mconcat)
main = scotty 3000 $ do
    get "/:word" $ do
        beam <- param "word"
        html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
Scotty is the cheap and cheerful way to write RESTful, declarative web applications.
- A page is as simple as defining the verb, url pattern, and Text content.
 - It is template-language agnostic. Anything that returns a Text value will do.
 - Conforms to WAI Application interface.
 - Uses very fast Warp webserver by default.
 
See examples/basic.hs to see Scotty in action. (basic.hs needs the wai-extra package)
> runghc examples/basic.hs
Setting phasers to stun... (port 3000) (ctrl-c to quit)
(visit localhost:3000/somepath)
As for the name: Sinatra + Warp = Scotty.
More Information
Tutorials and related projects can be found in the Scotty wiki:
https://github.com/scotty-web/scotty/wiki
Development & Support
Open an issue on GitHub or join #scotty on Freenode.
Copyright (c) 2012-2014 Andrew Farmer
Changes
0.11.0
- IO exceptions are no longer automatically turned into ScottyErrors by
liftIO. UseliftAndCatchIOto get that behavior. - New 
finishfunction. - Text values are now leniently decoded from ByteStrings.
 - Added 
MonadFailinstance forScottyT - Lots of bound bumps on dependencies.
 
0.10.2
- Removed debug statement from routes
 
0.10.1
Parsableinstances forWord,Word8,Word16,Word32,Word64[adamflott]Parsableinstances forInt8,Int16,Int32,Int64, andNatural- Removed redundant 
Monadconstraint onmiddleware 
0.10.0
- 
The monad parameters to
ScottyThave been decoupled, causing the type of theScottyTconstructor to change. As a result,ScottyTis no longer aMonadTransinstance, and the type signatures ofscottyT,scottyAppT, andscottyOptsThave been simplified. [ehamberg] - 
socketDescriptionno longer uses the deprecatedPortNumconstructor. Instead, it uses theShowinstance forPortNumber. This changes the bytes from host to network order, so the output ofsocketDescriptioncould change. [ehamberg] - 
Alternative,MonadPlusinstances forActionT - 
scottynow depends ontransformers-compat. As a result,ActionTnow usesExceptT, regardless of which version oftransformersis used. As a result, several functions inWeb.Scotty.Transno longer require aScottyErrorconstraint, sinceExceptTdoes not require anErrorconstraint (unlikeErrorT). - 
Added support for OPTIONS routes via the
optionsfunction [alvare] - 
Add
scottySocketandscottySocketT, exposing Warp Unix socket support [hakujin] - 
Parsableinstance for lazyByteString[tattsun] - 
Added streaming uploads via the
bodyReaderfunction, which retrieves chunks of the request body. [edofic]ActionEnvhad agetBodyChunkfield added (inWeb.Scotty.Internal.Types)RequestBodyStateandBodyPartiallyStreamedadded toWeb.Scotty.Internal.Types
 - 
jsonDatausesaeson’seitherDecodeinstead of justdecode[k-bx] 
0.9.1
- text/html/json only set Content-Type header when not already set
 
0.9.0
- 
Add
charset=utf-8toContent-Typefortext,htmlandjson - 
Assume HTTP status 500 for
defaultHandler - 
Remove deprecated
sourcemethod. - 
No longer depend on conduit.
 
0.8.2
- 
Bump
aesonupper bound - 
Fix
mtlrelated deprecation warnings 
0.8.1
- 
Export internal types
 - 
Added
MonadBase,MonadTransControlandMonadBaseControlinstances forActionT 
0.8.0
- 
Upgrade to wai/wai-extra/warp 3.0
 - 
No longer depend on conduit-extra.
 - 
The
sourceresponse method has been deprecated in favor of a newstreamresponse, matching changes in WAI 3.0. - 
Removed the deprecated
reqHeaderfunction. 
0.7.3
- Bump upper bound for case-insensitive, mtl and transformers.
 
0.7.2
- Bump lower bound on conduit, add conduit-extra to cabal build depends.
 
0.7.1
- Default warp settings now use 
setFdCacheDuration 0to work around a warp issue where file changes are not getting picked up. 
0.7.0
- 
Renamed
reqHeadertoheader. Addedheadersfunction to get all headers. - 
Changed
MonadIOinstance forActionTsuch that IO exceptions are lifted intoScottyErrors viastringError. - 
Make
Boolparsing case-insensitive. Goal: support both Haskell’s True/False and Javascript’s true/false. Thanks to Ben Gamari for suggesting this. - 
Bump
aeson/textupper bounds. - 
Bump
wai/wai-extra/warpbounds, including new lower bound forwarp, which fixes a security issue related to Slowloris protection. 
0.6.2
- Bump upper bound for 
text. 
0.6.1
- Match changes in 
wai-extra. 
0.6.0
- 
The Scotty transformers (
ScottyTandActionT) are now parameterized over a custom exception type, allowing one to extend Scotty’sErrorTlayer with something richer thanTexterrors. See theexceptionsexample for use.ScottyMandActionMremain specialized toTextexceptions for simplicity. - 
Both monads are now instances of
FunctorandApplicative. - 
There is a new
cookiesexample. - 
Internals brought up-to-date with WAI 2.0 and related packages.
 
0.5.0
- 
The Scotty monads (
ScottyMandActionM) are now monad transformers, allowing Scotty applications to be embedded in arbitraryMonadIOs. The old API continues to be exported fromWeb.Scottywhere:type ScottyM = ScottyT IO type ActionM = ActionT IOThe new transformers are found in
Web.Scotty.Trans. See theglobalstateexample for use. Special thanks to Dan Frumin (co-dan) for much of the legwork here. - 
Added support for HTTP PATCH method.
 - 
Removed lambda action syntax. This will return when we have a better story for typesafe routes.
 - 
reqHeader :: Text -> ActionM Text==>reqHeader :: Text -> ActionM (Maybe Text) - 
New
rawmethod to set body to a rawByteString - 
Parse error thrown by
jsonDatanow includes the body it couldn’t parse. - 
headersplit intosetHeaderandaddHeader. The former replaces a response header (original behavior). The latter adds a header (useful for multipleSet-Cookies, for instance).