Framework
scotty-web/scotty avatar
scotty-web/scotty

Scotty Haskell Web Framework: WAI, Warp, and Declarative Routing

Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp (Official Repository)

1,775 stars134 forksHaskellBSD-3-Clause

At a glance

What is it?
Scotty is a Haskell web framework for building REST-style services with declarative routes and WAI-compatible handlers. It is a practical fit for Haskell developers who want Warp without manually assembling the server interface.
Who is it for?
Scotty is suitable for Haskell developers who want concise route declarations and a WAI-compatible application backed by Warp, especially when middleware or the included examples fit the service. It is less suitable when a newer release cadence is the first requirement, because the latest documented release is 0.12.1 from 2022-11-17, although the repository is not archived and its last push was on 2026-06-26.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 119 days ago.
What is it written in?
Mainly Haskell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Scotty's REST Interface and Haskell Audience

Scotty addresses the part of web development that sits between a Haskell business function and an HTTP server: declaring routes, reading request data, producing response content, and connecting the application to a web interface. It is intended for Haskell developers who prefer a declarative structure similar to Ruby's Sinatra. A handler identifies an HTTP method, a URL pattern, and the action associated with that route. This makes it possible to keep routing close to the application logic without taking responsibility for the lower-level WAI request plumbing.

The repository's basic route captures a path segment. The `get` combinator matches `GET`, while `/:word` declares a one-segment parameter. The handler retrieves that value through `pathParam "word"` and sends an HTML response with `html`. Content is not tied to a particular template language because the README states that anything returning `Text` will work. That boundary makes Scotty relevant to JSON APIs, small HTML services, generated text, and applications that already have a Haskell rendering layer.

Scotty is a framework-layer choice rather than a complete application platform. The README does not prescribe database access, schema migration, authentication, deployment orchestration, or front-end delivery. Those concerns remain outside the features demonstrated by the basic program. Teams should therefore judge it as the HTTP routing and response layer, not as a substitute for the rest of an application's stack.

WAI Requests, Warp Serving, and Route Parameters

Scotty conforms to the Web Application Interface, or WAI, and uses Warp as its default web server. WAI defines the application interface beneath Scotty's route DSL, while Warp supplies the server side of that arrangement. This architecture matters because Scotty is not describing itself as an independent socket server with a proprietary request model. Its application can remain aligned with WAI while middleware handles concerns such as logging and header validation.

Request values cross the route boundary through named accessors. In the README example, `/:word` is a pattern and `pathParam "word"` retrieves its value inside the handler. Query parameters appear in the executable example's route for `/foo_query?p=42`, with the response displaying `42`. The examples directory also includes separate files for cookies, file uploads, sessions, request or application configuration, exceptions, global state, JSON mode, gzip, and nested routing.

The available middleware example is especially relevant for judging how Scotty composes with surrounding HTTP behavior. Logging and header validation are presented as WAI middleware examples, which indicates that cross-cutting HTTP processing does not need to be repeated inside every route. The README does not explain middleware ordering or provide a general middleware configuration interface, so those details would need verification for an application with several interacting middleware layers.

Running the Basic Scotty Example

The README's first executable path is the `examples/basic.hs` file. From a checkout, run it with `runghc`. The documented startup line says that the server listens on port 3000 and that `ctrl-c` stops it.

bash
runghc examples/basic.hs

After startup, request the root path. The README states that the response is `foobar`.

bash
curl localhost:3000

The example also accepts a query on the `/foo_query` route. The documented request includes `p=42`, and the response contains an HTML heading with the value.

bash
curl localhost:3000/foo_query?p=42

For environments using Stack and the example executable, the README gives an equivalent command. It expects the example package to have been installed in the working environment.

bash
stack exec -- scotty-basic

The repository Makefile also contains a `boot` target that installs the package with Cabal, plus a `ghci` target for opening a Cabal REPL.

bash
cabal install --force-reinstalls

That Make target is a development convenience rather than a complete dependency tutorial. The README does not give a version pin, project-level install command, or production launch procedure.

Feature Examples for Cookies, Sessions, and Uploads

Scotty's example directory gives a more useful adoption signal than a generic feature list because it identifies concrete implementation files. `examples/cookies.hs` covers cookies, while `examples/session.hs` covers session handling. These are materially different concerns: a cookie is a client-facing response or request mechanism, whereas a session example can demonstrate how application state is associated with requests. The README does not document session storage choices, expiration policy, signing, or cleanup behavior, so the existence of the example should not be read as a guarantee about any one backend.

File upload support is represented by `examples/upload.hs`, and the repository includes both `examples/uploads/` and an `examples/static/` directory. The presence of a custom static directory may also be relevant to services that deliver local assets, although the README excerpt does not state the routing call or directory option used by that example.

Other examples expose operational requirements directly. `examples/exceptions.hs` addresses exception handling, `examples/globalstate.hs` addresses shared state, `examples/reader.hs` addresses configuration, `examples/middleware.hs` shows WAI middleware, and `examples/nested.hs` demonstrates nested route behavior. `examples/json_mode.hs` and `examples/gzip.hs` cover response concerns beyond plain HTML. Engineers can use these files to identify the exact feature area they need, but the README does not summarize their APIs or explain which production settings they represent.

Windows regex-posix Compilation Constraint

Scotty documents a Windows compilation issue involving `regex-posix`. This is a concrete boundary for teams adopting the framework on Windows, and the README supplies separate Stack and Cabal remedies. With Stack, the documented `stack.yaml` configuration enables the `regex-posix-clib` package and its feature:

yaml
extra-deps:
- regex-posix-clib-2.7
flags:
  regex-posix:
    _regex-posix-clib: true

For Cabal, the README calls for adding a constraint in `cabal.project.local`:

yaml
constraints:
  regex-posix +_regex-posix-clib

These settings address the documented Windows compilation failure, but the README does not state which other platforms require them or explain the underlying native-library build process. That omission matters for reproducible CI. A Windows build should confirm that the chosen dependency solution, compiler environment, and Cabal or Stack workflow all accept the documented constraint before the project is adopted.

Scotty Compared with a Direct WAI Application

The most relevant alternative visible from the repository is a Haskell web application written directly against WAI and Warp. Scotty adds a declarative route DSL and response helpers on top of those interfaces, while a direct WAI implementation would handle the WAI application contract and server setup without relying on Scotty's route combinators. The choice is therefore between a more compact application layer and more explicit control over the underlying interface.

The README identifies WAI middleware, header validation, and logging as supported or demonstrated concerns. A direct implementation would still need to arrange equivalent HTTP processing, but this repository does not claim that such an implementation would be more complex or faster. It provides no comparison benchmarks, middleware ordering guide, or performance measurements.

Scotty is also inspired by Ruby's Sinatra, but the documented difference is the language and runtime stack: Scotty is Haskell, conforms to WAI, and uses Warp by default. The README does not document feature parity with Sinatra. For a Haskell team already using WAI middleware, the key question is whether Scotty's route DSL removes enough application repetition to justify an additional framework layer.

Release History, Maintenance, and BSD-3-Clause

Scotty follows the Haskell Package Versioning Policy, as stated in the README. The latest listed release is 0.12.1, dated 2022-11-17. The repository is not archived, and its last push was on 2026-06-26. These facts indicate that source changes have continued after the release, but they do not establish that a new package release is available. Engineers should distinguish repository activity from the versioned dependency they will actually deploy.

The project is licensed under BSD-3-Clause. That identifier permits use and modification under its terms, including notice and disclaimer conditions, but this review does not provide legal advice. Teams still need to review the repository `LICENSE`, dependency licenses, and their own distribution obligations.

The README points tutorials and related projects to the Scotty wiki, while contribution work and issue reports are directed to the GitHub issue tracker. It also says that issues have been labeled since September 2023, including categories such as `easy fix`, `new feature`, `bugs`, and `R&D`. That helps explain how contributors navigate work, but it does not promise response times or guarantee that issues will be resolved.

Editorial conclusion

Scotty is suitable for Haskell developers who want concise route declarations and a WAI-compatible application backed by Warp, especially when middleware or the included examples fit the service. It is less suitable when a newer release cadence is the first requirement, because the latest documented release is 0.12.1 from 2022-11-17, although the repository is not archived and its last push was on 2026-06-26. Before adoption, verify compatibility with the intended Haskell toolchain, especially `regex-posix` on Windows, and review the example matching each required feature.

Frequently asked questions

How do I install Scotty and run its basic example?

The repository's Makefile has a `boot` target that runs `cabal install --force-reinstalls`. For the first example, the README documents `runghc examples/basic.hs`, followed by requests to port 3000.

Which web interface and server does Scotty use?

Scotty conforms to the Web Application Interface, or WAI, and uses Warp as its default web server.

Does Scotty include examples for sessions, uploads, and middleware?

The repository includes `examples/session.hs`, `examples/upload.hs`, and `examples/middleware.hs`. The middleware example covers areas such as logging and header validation.

Official sources

  1. License: BSD-3-Clause
  2. Project website
  3. README
  4. Releases
  5. scotty-web/scotty on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/scotty-web-scotty.svg)](https://hysenlabs.com/projects/scotty-web-scotty)

Was this useful?