I am pleased to announce Dream, a very easy-to-use Web framework with high performance, secure defaults, and thorough documentation!
It is available now from opam, with
opam install dream.1.0.0~alpha2.
- WebSockets and GraphQL.
- A template syntax, which you can see in the image above.
- Trivial HTTPS and HTTP/2 support, allowing simple deployments without a proxy.
- Sessions with pluggable back ends.
- Easy secure cookies and CSRF-safe forms.
…and more, yet Dream sticks to a simple programming model:
- Web apps are just bare functions from requests to responses.
- Middlewares are just higher-order wrapper functions.
- Routes tell the router which of these functions to call.
Indeed, for those who like algebra, there is a certain structure to Dream. However, that’s not the point of this post!
Dream is meant to be very easy to understand. It sticks to base types, introducing only a few types of its own, and uses existing languages, such as HTML for templates, and URLs for routes. Dream itself is one module in one opam package, which lives in a monorepo. The docs are on one page.
Dream is loosely coupled. Even though Dream offers many defaults, it is unopinionated, and you can quickly configure or replace anything. For example, it is easy to use TyXML for templates, and Dream happily supports such usage with examples.
Security-sensitive features, such as cookies, are arranged so that simple and obvious usage is automatically secure. Wherever security still depends on the Dream app, the docs highlight it. Dream has selected a modern cipher as a default, supports key rotation, and offers suggestions for other purposes, such as password hashing. It implements and abstracts away all of the OWASP security guidelines that are relevant to its level.
Dream is designed for full internationalization. It has a centralized error handler that intercepts even lower-level HTTP errors, so that you can decorate them with your app’s own error template, and leak no hardcoded strings. Dream’s URL encoders favor internationalized (UTF-8) URIs, and the router accepts them.
Finally, Dream is designed for a wide range of applications, including with or without a proxy, standalone or embedded in larger binaries, and with external static assets or assets compiled in.
Dream is very extensively documented. See…
- Examples, the first several of which make up a tutorial. Each example is a complete project.
- The online playground, which features many of the examples, and is itself a Dream app!
- The API docs.
In particular, see
- Deployment examples for Heroku, Digital Ocean with Docker, and Digital Ocean with systemd, all of which include GitHub Actions scripts and instructions.
- Full-stack examples with js_of_ocaml, ReScript, and Melange.
- Examples in Reason syntax.
- Development watching and live reloading.
Dream has already received several very helpful contributions, and more are very welcome! See
CONTRIBUTING.md. I must also acknowledge all the people working on Dream’s dependecies and prior art. In particular, Dream relies heavily on the HTTP and WebSocket servers primarily by Spiros Eliopoulos (@seliopou) and Antonio Nuno Monteiro (@anmonteiro).
Apart from accepting code, docs, and examples, Dream will happily link to:
- Blogs and articles, as different people learn best from different presentations.
- “Downstream” libraries to use with Dream.
For example, Thibaut Mattio (@tmattio) is working on dream-livereload, a live-reloading middleware for Dream, similar to the example, which he also contributed! Once dream-livereload is slightly more mature, Dream will link to it from its README.
There is also dream-serve, a live-reloading static site server based on Dream and libuv, which was used to develop the docs.
Dream is currently in an alpha state. It is thought (by me) to be internally quite stable. However, there will probably be various API tweaks before release 1.0.0.
My current, rough plan is to release several alphas of Dream over six months or so. The releases will address:
- Flow control for very large responses, and getting the “advanced” part of the I/O API to be as close to zero-copy and non-allocating as possible (or reasonable).
- Remaining (optional) security enhancements, such as a default content security policy.
- Remaining session improvements, such as re-keying.
- Friction in handling of JSON, database access, etc. This is not properly part of or due to Dream, but it should be addressed for a better Web development experience.
- Multicore and effects support.
That’s all. Let’s bring OCaml to the Web! Happy Web programming!