package lwt_ppx

  1. Overview
  2. Docs
PPX syntax for Lwt, providing something similar to async/await from JavaScript

Install

dune-project
 Dependency

Authors

Maintainers

Sources

6.1.0.tar.gz
md5=16d58c8295b5273e58779db0ad1f967a
sha512=d5eafe2f5d2dc576b76db15b84caf69d673cb3d736dc3e40b239e6a42c6036658c78bd4b883e9f2b9f627c144be515b1824f1f2de9d79c05d5744c456fb63257

Description

Published: 03 Feb 2026

README

Lwt

version GitHub Actions status

Lwt is a concurrent programming library for OCaml. It provides a single data type: the promise, which is a value that will become resolved in the future. Creating a promise spawns a computation. When that computation is I/O, Lwt runs it in parallel with your OCaml code.

OCaml code, including creating and waiting on promises, is run in a single thread by default, so you don't have to worry about locking or preemption. You can detach code to be run in separate threads on an opt-in basis.

Here is a simplistic Lwt program which requests the Google front page, and fails if the request is not completed in five seconds:

let () =
  let request =
    let%lwt addresses = Lwt_unix.getaddrinfo "google.com" "80" [] in
    let google = Lwt_unix.((List.hd addresses).ai_addr) in

    Lwt_io.(with_connection google (fun (incoming, outgoing) ->
      write outgoing "GET / HTTP/1.1\r\n";%lwt
      write outgoing "Connection: close\r\n\r\n";%lwt
      let%lwt response = read incoming in
      Lwt.return (Some response)))
  in

  let timeout =
    Lwt_unix.sleep 5.;%lwt
    Lwt.return_none
  in

  match Lwt_main.run (Lwt.pick [request; timeout]) with
  | Some response -> print_string response
  | None -> prerr_endline "Request timed out"; exit 1

(* ocamlfind opt -package lwt.unix,lwt_ppx -linkpkg example.ml && ./a.out *)

If you are not using the lwt_ppx syntax extension, you can use the let* binding opoerators from the Lwt.Syntax module instead.

let () =
  let open Lwt.Syntax in
  let request =
    let* addresses = Lwt_unix.getaddrinfo "google.com" "80" [] in
    let google = Lwt_unix.((List.hd addresses).ai_addr) in

    Lwt_io.(with_connection google (fun (incoming, outgoing) ->
      let* () = write outgoing "GET / HTTP/1.1\r\n" in
      let* () = write outgoing "Connection: close\r\n\r\n" in
      let* response = read incoming in
      Lwt.return (Some response)))
  in

  let timeout =
    let* () = Lwt_unix.sleep 5. in
    Lwt.return_none
  in

  match Lwt_main.run (Lwt.pick [request; timeout]) with
  | Some response -> print_string response
  | None -> prerr_endline "Request timed out"; exit 1

(* ocamlfind opt -package lwt.unix,lwt_ppx -linkpkg example.ml && ./a.out *)

In the program above, functions such as Lwt_io.write create promises. The let%lwt ... in construct (provided by lwt_ppx) or the let* ... in construct (provided by Lwt.Syntax) are used to wait for a promise to resolve. The code after in is scheduled to run after the code inside the let...in has resolved.

Lwt.pick races promises against each other, and behaves as the first one to complete.

Lwt_main.run forces the whole promise-computation network to be executed. All the visible OCaml code is run in a single thread, but Lwt internally uses a combination of worker threads and non-blocking file descriptors to resolve in parallel the promises that do I/O.


Overview

Lwt compiles to native code on Linux, macOS, Windows, and other systems. It's also routinely compiled to JavaScript for the front end and Node by js_of_ocaml.

In Lwt,

  • The core library Lwt provides promises...
  • ...and a few pure-OCaml helpers, such as promise-friendly mutexes, condition variables, and mvars.
  • There is a big Unix binding, Lwt_unix that binds almost every Unix system call. A higher-level module Lwt_io provides nice I/O channels.
  • Lwt_process is for subprocess handling.
  • Lwt_preemptive spawns system threads.
  • The PPX syntax allows using all of the above without going crazy!
  • There are also some other helpers, such as Lwt_react for reactive programming. See the table of contents on the linked manual pages!

Installing

  1. Use your system package manager to install a development libev package. It is often called libev-dev or libev-devel.
  2. opam install conf-libev lwt

Documentation

We are currently working on improving the Lwt documentation (drastically; we are rewriting the manual). In the meantime:

  • The current manual can be found here.
  • Mirage has a nicely-written Lwt tutorial.
  • An example of a simple server written in Lwt.
  • Concurrent Programming with Lwt is a nice source of Lwt examples. They are translations of code from the excellent Real World OCaml, but are just as useful if you are not reading the book.

Note: much of the current manual refers to 'a Lwt.t as "lightweight threads" or just "threads." This will be fixed in the new manual. 'a Lwt.t is a promise, and has nothing to do with system or preemptive threads.


Contact

Open an issue, visit Discord chat, ask on discuss.ocaml.org, or on Stack Overflow.

Release announcements are made on discuss.ocaml.org. Watching the repo for "Releases only" is also an option.


Contributing

  • CONTRIBUTING.md contains tips for working on the code, such as how to check the code out, how review works, etc. There is also a high-level outline of the code base.
  • Ask us anything, whether it's about working on Lwt, or any question at all about it :)
  • The documentation always needs proofreading and fixes.
  • You are welcome to pick up any other issue, review a PR, add your opinion, etc.
  • Any feedback is welcome, including how to make contributing easier!

Libraries to use with Lwt

Dependencies (4)

  1. lwt >= "6"
  2. ppxlib >= "0.36"
  3. ocaml >= "4.08"
  4. dune >= "3.18"

Dev Dependencies (1)

  1. odoc with-doc

  1. activitypub
  2. anthill
  3. awso-lwt
  4. azure-cosmos-db < "0.4.0"
  5. azure-cosmos-db-lwt
  6. canary
  7. chamo
  8. chess_com_api
  9. cohttp-lwt-jsoo >= "5.3.0"
  10. css
  11. curl_lwt
  12. dap
  13. devkit
  14. docker_hub < "0.2.0"
  15. dream >= "1.0.0~alpha4"
  16. dream-encoding >= "0.2.0"
  17. dream-httpaf
  18. dream-inertia
  19. dream-livereload >= "0.2.0"
  20. dream-pure
  21. dream-serve
  22. dream_middleware_ext
  23. earlybird
  24. elasticsearch-cli
  25. eliom < "12.0.0"
  26. erssical
  27. FPauth-core
  28. gdbprofiler
  29. granary
  30. granary_repl
  31. gremlin
  32. guardian
  33. hyper
  34. i3ipc
  35. jupyter
  36. jupyter-kernel < "0.5"
  37. lambdapi >= "2.4.0"
  38. ldp
  39. lichess_api
  40. lru_cache
  41. mehari-lwt-unix < "0.3"
  42. mehari-mirage < "0.3"
  43. menhir-lsp
  44. monorobot
  45. mpris
  46. mqtt
  47. multipart-form-data
  48. mwt
  49. naboris >= "0.1.3"
  50. neo4j_bolt
  51. obus >= "1.2.1"
  52. ocaml-ai-sdk
  53. ocsigen-toolkit >= "4.3.0"
  54. ocsipersist-lib >= "1.0.3" & < "2.1.0"
  55. ojs-base
  56. ojs_base
  57. opam-check-npm-deps < "4.1.0"
  58. openai
  59. opentelemetry-client-cohttp-eio < "0.90"
  60. opentelemetry-client-cohttp-lwt
  61. opentelemetry-client-ocurl-lwt
  62. opentelemetry-lwt >= "0.5"
  63. oraft >= "0.3.0"
  64. order-i3-xfce
  65. owork
  66. passage < "0.1.8"
  67. pgn_parser
  68. plotkicadsch
  69. ppx_cstruct >= "6.0.1"
  70. ppx_defer >= "0.4.0"
  71. qcow-stream >= "0.13.0"
  72. qcow-types >= "0.13.0"
  73. qdrant < "0.2.0"
  74. qfs
  75. quests
  76. quickterface
  77. rdf_json_ld
  78. rdf_lwt
  79. SZXX < "2.0.0"
  80. scgi
  81. server-reason-react
  82. sihl >= "0.6.0~rc1"
  83. slack
  84. slacko
  85. speed
  86. statocaml
  87. stk
  88. stog >= "0.19.0"
  89. syguslib-utils
  90. testcontainers
  91. testcontainers-elasticsearch
  92. testcontainers-kafka
  93. testcontainers-localstack
  94. testcontainers-memcached
  95. testcontainers-mockserver
  96. testcontainers-mongo
  97. testcontainers-mysql
  98. testcontainers-postgres
  99. testcontainers-rabbitmq
  100. testcontainers-redis
  101. textrazor
  102. tidy_email_mailgun
  103. tidy_email_sendgrid
  104. tidy_email_smtp
  105. usb
  106. ws-server

Conflicts (2)

  1. lwt = "6.0.0-beta01"
  2. lwt = "6.0.0~alpha00"