Easy-to-use, feature-complete Web framework without boilerplate.
Dream is one flat module in one package, documented on one page, but with many examples. It offers:
- WebSockets and GraphQL for your modern Web apps.
- HTML templates with embedded OCaml or Reason — use existing skills!
- Sessions with pluggable storage back ends.
- Easy HTTPS and HTTP/2 support — Dream runs without a proxy.
- Helpers for secure cookies and CSRF-safe forms.
- Full-stack ML with clients by Melange, ReScript, or js_of_ocaml.
...all without sacrificing ease of use — Dream has:
- A simple programming model — Web apps are just functions!
- Composable middleware and routes.
- Unified, internationalization-friendly error handling.
- Cryptography helpers, key rotation, and a chosen cipher.
- A neat logger, and attention to configuring the OCaml runtime nicely.
Every part of the API is arranged to be easy to understand, use, and remember.
Dream sticks to base OCaml types like string
and list
, introducing only a
few types of its own — and some of those are just abbreviations
for bare functions!
The neat interface is not a limitation. Everything is still configurable by a large number of optional arguments. Where necessary, Dream exposes the lower-level machinery that it is composed from. For example, the basic body and WebSocket readers return strings, but you can also do zero-copy streaming.
You can even run Dream as a quite bare abstraction over its underlying set of HTTP libraries, where it acts only as minimal glue code between their slightly different interfaces, and takes care of horridness like ALPN.
And, even though Dream is presented as one package for ordinary usage, it is internally factored into several sub-libraries, according to the different dependencies of each, for fast porting to different environments.
Dream is not yet announced or released! Before release, Dream will get a quick-start script, and some other help for getting started quickly. However, if you want to try Dream now, you can do:
git clone https://github.com/aantron/dream.git --recursive
cd dream
opam install .
Note: the clone must be --recursive
, because Dream vendors several
packages as git submodules. Also, if you have gluten
, httpaf
, h2
,
or websocketaf
, or their gluten-*
, etc., subpackages independently
installed in your switch, you may have to remove them with opam remove
to
avoid conflicts. However, they should not be pulled into a basic build of Dream
and most programs that use it.
After that, go to one of the examples, such as 1-hello
, and
try building it:
cd example/1-hello
dune exec --root . ./hello.exe
If you prefer Reason syntax, try example r-hello
instead.
You should be able to copy the example out to a completely separate directory,
if you didn't use a local _opam
switch scoped to Dream's clone directory. If
you did, you can pin Dream to your clone in a different opam switch with
opam pin add dream /path/to/your/clone
- Tutorial — Threads together the first several examples
of Dream, touching all the basic topics, including security. See the full list
and start wherever you like, or begin at
1-hello
, the Dream version of Hello, world! - Reason syntax — Several of the examples are
written in Reason. See
r-hello
. - Full-stack — see skeleton projects
r-fullstack-melange
,w-fullstack-rescript
, andw-fullstack-jsoo
. - Examples — These cover various HTTP scenarios.
- API reference
Apart from the issues, good places to discuss Dream are...
- The OCaml and/or Reason Discord servers.
- The OCaml Discuss forum.
Highlight @antron
to poke @aantron specifically.
Dream uses several submodules, so be sure to clone with
git clone https://github.com/aantron/dream.git --recursive
Dream is based on work by the authors and contributors of its many dependencies and their transitive dependencies. There are, however, several influences that cannot be discovered directly:
- Templates are inspired by ECaml from Alexander Markov and Embedded OCaml Templates from Emile Trotignon.
- Dream's handler and middleware types are simplified from Opium by Rudi Grinberg and contributors.
- The lower-level HTTP and WebSocket servers are vendored copies of Antonio Nuno Monteiro's forks and original works, with credit also due to their contributors, and Spiros Eliopoulos in particular, as the original author of two of the projects.
- The API docs are instantiated by Soupault from Daniil Baturin.
- The name was inspired by Morph from Ulrik Strid, which was itself partially inspired by Opium.
- Raphael Rafatpanah and El-Hassan Wanas provided important early feedback.
- GraphQL subscriptions.
- Optimizations: router, logger, microparsers (form data, etc.), fully zero-allocation streaming.
- WebSocket and stream backpressure.
- HTTP3/QUIC.
- Review JSON.
- Review SQL prepared statements.
- Switch to AEAD_AES_256_GCM_SIV for the cipher.
- WebSocket streaming (frames).
- Factor out internal sub-libraries to port Dream to MirageOS, etc.
- Token rotation-based session management.
- Lots of optionals for decoupling defaults, e.g. forms without CSRF checking, SQL sessions with a different database.
- Bundle GraphiQL into a single HTML file that does not access any external CDN.
- Maybe a logo.
- i18n helper, URL templates.
- Auth library.
- Maybe REST helpers.
- Maybe Async support.
- Multicore.
- Effects.
- Proxy headers support.
- Introspection.
- Dependency reduction, especially system dependencies.
- And lots, lots more.