{"id":13484472,"url":"https://github.com/ocsigen/lwt","last_synced_at":"2025-05-14T14:08:43.804Z","repository":{"id":38628739,"uuid":"11749475","full_name":"ocsigen/lwt","owner":"ocsigen","description":"OCaml promises and concurrent I/O","archived":false,"fork":false,"pushed_at":"2025-05-02T12:47:46.000Z","size":30068,"stargazers_count":755,"open_issues_count":74,"forks_count":177,"subscribers_count":42,"default_branch":"master","last_synced_at":"2025-05-08T00:46:14.941Z","etag":null,"topics":["asynchronous","concurency","events","fibers","futures","io","lwt","ocaml","promises"],"latest_commit_sha":null,"homepage":"https://ocsigen.org/lwt","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ocsigen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-07-29T20:47:51.000Z","updated_at":"2025-05-04T19:25:19.000Z","dependencies_parsed_at":"2023-02-17T20:45:57.809Z","dependency_job_id":"292a8952-3814-4d29-a4c7-feff5c7a182c","html_url":"https://github.com/ocsigen/lwt","commit_stats":{"total_commits":2333,"total_committers":155,"mean_commits":"15.051612903225806","dds":0.6605229318474068,"last_synced_commit":"3e35db2d929229cb39ea9e518ebc0602bdd04b6c"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocsigen%2Flwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocsigen%2Flwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocsigen%2Flwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocsigen%2Flwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ocsigen","download_url":"https://codeload.github.com/ocsigen/lwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254159936,"owners_count":22024566,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous","concurency","events","fibers","futures","io","lwt","ocaml","promises"],"created_at":"2024-07-31T17:01:24.939Z","updated_at":"2025-05-14T14:08:43.770Z","avatar_url":"https://github.com/ocsigen.png","language":"OCaml","readme":"# Lwt\n\n[![version][version]][releases] [![GitHub Actions status][github-actions-img]][github-actions]\n\n[version]:            https://img.shields.io/github/v/release/ocsigen/lwt\n[releases]:           https://github.com/ocsigen/lwt/releases\n[github-actions]:     https://github.com/ocsigen/lwt/actions\n[github-actions-img]: https://github.com/ocsigen/lwt/actions/workflows/workflow.yml/badge.svg?branch=master\n\nLwt is a concurrent programming library for OCaml. It provides a single data\ntype: the *promise*, which is a value that will become determined in the future.\nCreating a promise spawns a computation. When that computation is I/O, Lwt runs\nit in parallel with your OCaml code.\n\nOCaml code, including creating and waiting on promises, is run in a single\nthread by default, so you don't have to worry about locking or preemption. You\ncan detach code to be run in separate threads on an opt-in basis.\n\nHere is a simplistic Lwt program which requests the Google front page, and fails\nif the request is not completed in five seconds:\n\n```ocaml\nopen Lwt.Syntax\n\nlet () =\n  let request =\n    let* addresses = Lwt_unix.getaddrinfo \"google.com\" \"80\" [] in\n    let google = Lwt_unix.((List.hd addresses).ai_addr) in\n\n    Lwt_io.(with_connection google (fun (incoming, outgoing) -\u003e\n      let* () = write outgoing \"GET / HTTP/1.1\\r\\n\" in\n      let* () = write outgoing \"Connection: close\\r\\n\\r\\n\" in\n      let* response = read incoming in\n      Lwt.return (Some response)))\n  in\n\n  let timeout =\n    let* () = Lwt_unix.sleep 5. in\n    Lwt.return None\n  in\n\n  match Lwt_main.run (Lwt.pick [request; timeout]) with\n  | Some response -\u003e print_string response\n  | None -\u003e prerr_endline \"Request timed out\"; exit 1\n\n(* ocamlfind opt -package lwt.unix -linkpkg example.ml \u0026\u0026 ./a.out *)\n```\n\nIn the program, functions such as `Lwt_io.write` create promises. The\n`let* ... in` construct is used to wait for a promise to become determined; the\ncode after `in` is scheduled to run in a \"callback.\" `Lwt.pick` races promises\nagainst each other, and behaves as the first one to complete. `Lwt_main.run`\nforces the whole promise-computation network to be executed. All the visible\nOCaml code is run in a single thread, but Lwt internally uses a combination of\nworker threads and non-blocking file descriptors to resolve in parallel the\npromises that do I/O.\n\n\n\u003cbr/\u003e\n\n### Overview\n\nLwt compiles to native code on Linux, macOS, Windows, and other systems. It's\nalso routinely compiled to JavaScript for the front end and Node by js_of_ocaml.\n\nIn Lwt,\n\n- The [core library `Lwt`][core] provides promises...\n- ...and a few pure-OCaml helpers, such as promise-friendly [mutexes][mutex],\n  [condition variables][cond], and [mvars][mvar].\n- There is a big Unix binding, [`Lwt_unix`][unix] that binds almost every Unix\n  system call. A higher-level module [`Lwt_io`][io] provides nice I/O channels.\n- [`Lwt_process`][process] is for subprocess handling.\n- [`Lwt_preemptive`][preemptive] spawns system threads.\n- The [PPX syntax][ppx] allows using all of the above without going crazy!\n- There are also some other helpers, such as [`Lwt_react`][react] for reactive\n  programming. See the table of contents on the linked manual pages!\n\n[core]: https://ocsigen.org/lwt/latest/api/Lwt\n[cond]: https://ocsigen.org/lwt/latest/api/Lwt_condition\n[mutex]: https://ocsigen.org/lwt/latest/api/Lwt_mutex\n[mvar]: https://ocsigen.org/lwt/latest/api/Lwt_mvar\n[unix]: https://ocsigen.org/lwt/latest/api/Lwt_unix\n[io]: https://ocsigen.org/lwt/latest/api/Lwt_io\n[process]: https://ocsigen.org/lwt/latest/api/Lwt_process\n[preemptive]: https://ocsigen.org/lwt/latest/api/Lwt_preemptive\n[ppx]: https://ocsigen.org/lwt/latest/api/Ppx_lwt\n[react]: https://ocsigen.org/lwt/latest/api/Lwt_react\n\n\n\u003cbr/\u003e\n\n## Installing\n\n1. Use your system package manager to install a development libev package.\n   It is often called `libev-dev` or `libev-devel`.\n2. `opam install conf-libev lwt`\n\n\n\u003cbr/\u003e\n\n## Documentation\n\nWe are currently working on improving the Lwt documentation (drastically; we are\nrewriting the manual). In the meantime:\n\n- The current manual can be found [here][manual].\n- Mirage has a nicely-written [Lwt tutorial][mirage-tutorial].\n- An example of a [simple server][counter-server] written in Lwt.\n- [Concurrent Programming with Lwt][rwo-lwt] is a nice source of Lwt examples.\n  They are translations of code from the excellent Real World OCaml, but are\n  just as useful if you are not reading the book.\n\n*Note: much of the current manual refers to `'a Lwt.t` as \"lightweight threads\"\nor just \"threads.\" This will be fixed in the new manual. `'a Lwt.t` is a\npromise, and has nothing to do with system or preemptive threads.*\n\n[manual]:   https://ocsigen.org/lwt/\n[rwo-lwt]:  https://github.com/dkim/rwo-lwt#readme\n[mirage-tutorial]: https://mirage.io/docs/tutorial-lwt\n[counter-server]: https://baturin.org/code/lwt-counter-server/\n\n\n\u003cbr/\u003e\n\n## Contact\n\nOpen an [issue][issues], visit [Discord][discord] chat, ask on\n[discuss.ocaml.org][discourse], or on [Stack Overflow][so].\n\nRelease announcements are made on [discuss.ocaml.org][discourse]. Watching the\nrepo for \"Releases only\" is also an option.\n\n[so]:     https://stackoverflow.com/questions/ask?tags=ocaml,lwt,ocaml-lwt\n[discourse]: https://discuss.ocaml.org/tag/lwt\n[issues]: https://github.com/ocsigen/lwt/issues/new\n[discord]: https://discord.com/invite/cCYQbqN\n\n\n\u003cbr/\u003e\n\n## Contributing\n\n- [`CONTRIBUTING.md`][contributing-md] contains tips for working on the code,\n  such as how to check the code out, how review works, etc. There is also a\n  high-level outline of the code base.\n- [Ask](#contact) us anything, whether it's about working on Lwt, or any\n  question at all about it :)\n- The [documentation](#documentation) always needs proofreading and fixes.\n- You are welcome to pick up any other [issue][issues-and-prs], review a PR, add\n  your opinion, etc.\n- Any feedback is welcome, including how to make contributing easier!\n\n[issues-and-prs]: https://github.com/ocsigen/lwt/issues?utf8=%E2%9C%93\u0026q=is%3Aopen\n[contributing-md]: https://github.com/ocsigen/lwt/blob/master/docs/CONTRIBUTING.md#readme\n\n\n\u003cbr/\u003e\n\n## Libraries to use with Lwt\n\n- [alcotest](https://github.com/mirage/alcotest/) —\nunit testing\n- [angstrom](https://github.com/inhabitedtype/angstrom) —\nparser combinators\n- [cohttp](https://github.com/mirage/ocaml-cohttp) — HTTP client and server\n- [cstruct](https://github.com/mirage/ocaml-cstruct) —\ninterop with C-like structures\n- [ezjsonm](https://github.com/mirage/ezjsonm) —\nJSON parsing and output\n- [faraday](https://github.com/inhabitedtype/faraday) —\nserialization combinators\n- [logs](https://github.com/dbuenzli/logs) —\nlogging\n- [lwt-parallel](https://github.com/ivg/lwt-parallel) —\ndistributed computing\n- [mwt](https://github.com/hcarty/mwt) — preemptive (system) thread pools\n- [opium](https://github.com/rgrinberg/opium) —\nweb framework\n- [lwt_domain](https://github.com/ocsigen/lwt_domain) — domain parallelism when\n  using Lwt with OCaml 5\n","funding_links":[],"categories":["OCaml","\u003ca name=\"OCaml\"\u003e\u003c/a\u003eOCaml"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focsigen%2Flwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Focsigen%2Flwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focsigen%2Flwt/lists"}