{"id":13726255,"url":"https://github.com/aantron/luv","last_synced_at":"2025-04-05T20:08:25.196Z","repository":{"id":40554327,"uuid":"137495485","full_name":"aantron/luv","owner":"aantron","description":"Cross-platform asynchronous I/O and system calls","archived":false,"fork":false,"pushed_at":"2024-09-05T18:06:41.000Z","size":2211,"stargazers_count":283,"open_issues_count":28,"forks_count":26,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-29T19:04:07.929Z","etag":null,"topics":["asynchronous","events","io","libuv","ocaml","reasonml"],"latest_commit_sha":null,"homepage":"https://aantron.github.io/luv","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/aantron.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"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},"funding":{"github":"aantron"}},"created_at":"2018-06-15T14:13:38.000Z","updated_at":"2025-03-24T12:55:59.000Z","dependencies_parsed_at":"2023-12-15T02:47:01.837Z","dependency_job_id":"f870d72c-be9d-4833-ace4-88cd7c114944","html_url":"https://github.com/aantron/luv","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aantron%2Fluv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aantron%2Fluv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aantron%2Fluv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aantron%2Fluv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aantron","download_url":"https://codeload.github.com/aantron/luv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247393570,"owners_count":20931813,"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","events","io","libuv","ocaml","reasonml"],"created_at":"2024-08-03T01:02:57.043Z","updated_at":"2025-04-05T20:08:25.171Z","avatar_url":"https://github.com/aantron.png","language":"OCaml","funding_links":["https://github.com/sponsors/aantron"],"categories":["OCaml"],"sub_categories":[],"readme":"# Luv\n\n[**Luv**][luv] is a neatly-packaged OCaml/Reason binding to [libuv][libuv], the\ncross-platform C library that does asynchronous I/O in Node.js and runs Node's\nmain loop.\n\nHere's an example, which retrieves the Google search page:\n\n```ocaml\nlet () =\n  Luv.DNS.getaddrinfo ~family:`INET ~node:\"google.com\" ~service:\"80\" ()\n      begin fun result -\u003e\n\n    let address = (List.hd (Result.get_ok result)).addr in\n    let socket = Luv.TCP.init () |\u003e Result.get_ok in\n    Luv.TCP.connect socket address begin fun _ -\u003e\n\n      Luv.Stream.write socket [Luv.Buffer.from_string \"GET / HTTP/1.1\\r\\n\\r\\n\"]\n        (fun _ _ -\u003e Luv.Stream.shutdown socket ignore);\n\n      Luv.Stream.read_start socket (function\n        | Error `EOF -\u003e Luv.Handle.close socket ignore\n        | Error _ -\u003e exit 2\n        | Ok response -\u003e print_string (Luv.Buffer.to_string response))\n\n    end\n  end;\n\n  ignore (Luv.Loop.run () : bool)\n```\n\n\u003cbr/\u003e\n\nlibuv does more than just asynchronous I/O. It also supports\n[multiprocessing][processes] and [multithreading][threads]. You can even [run\nmultiple async I/O loops, in different threads][loops]. libuv wraps a lot of\nother functionality, and exposes a [comprehensive operating system API][api].\n\nIndeed, Luv does not depend on [`Unix`][unix]. It is an alternative operating\nsystem API. Nonetheless, Luv and `Unix` can coexist readily in one program.\n\nBecause libuv is a major component of Node.js, it is\n[cross-platform][platforms] and [well-maintained][maintainers]. Luv, being a\nfairly thin binding, inherits these properties.\n\n\u003cbr/\u003e\n\nLuv takes care of the tricky parts of dealing with libuv from OCaml:\n\n- **Memory management** \u0026mdash; Luv keeps track of OCaml objects that have been\n  passed to libuv, so that they don't get collected too early by the GC.\n- **The runtime lock** \u0026mdash; multithreaded Luv programs don't wreck the OCaml\n  runtime.\n- **API problems** \u0026mdash; where libuv is forced to offer difficult APIs due to\n  the limitations of C, Luv provides more natural APIs.\n- **The build** \u0026mdash; when Luv is installed, it internally builds libuv, so\n  users don't have to figure out how to do it.\n- **Linking** \u0026mdash; a specific release of libuv is statically linked into\n  your  program together with Luv, and there is no dependency on a system\n  installation of libuv.\n\nBasically, when wrapped in Luv, libuv looks like any normal OCaml library you\nmight install from opam or using esy. In a loose sense, libuv is just an\nimplementation detail of Luv \u0026mdash; though, indeed, a very powerful one.\n\n\u003cbr/\u003e\n\nOne of the design goals of Luv is to be easy to integrate into larger libraries,\nsuch as [Lwt][lwt]. To that end, Luv is...\n\n- **Minimalist** \u0026mdash; Luv only takes care of inherent libuv headaches, such\n  as memory management, adding as little else as possible over libuv.\n- **Unopinionated** \u0026mdash; Luv avoids committing to design decisions beyond\n  those dictated by libuv and OCaml.\n- **Maintainable** \u0026mdash; Luv uses [Ctypes][ctypes] to minimize the amount of C\n  code in this repo, and [vendors][vendor] libuv to avoid versioning issues.\n\nLuv is [thoroughly tested][tests]. Apart from checking return values and I/O\neffects, the test cases also check for memory leaks, invalid references, and\npotential issues with multithreading.\n\n\u003cbr/\u003e\n\n## Installing\n\n```\nopam install luv\n```\n\nIf using esy, add\n\n```\n\"dependencies\": {\n  \"@opam/luv\": \"*\"\n}\n```\n\n\u003cbr/\u003e\n\n## Documentation\n\n- [User guide][guide]\n- [API reference][api]\n- [Examples][examples] \u0026mdash; explained in the [user guide][guide].\n- [libuv manual][libuv-docs]\n\n\u003cbr/\u003e\n\n## Experimenting\n\nYou can run any example by cloning the repo:\n\n```\ngit clone https://github.com/aantron/luv.git --recursive\ncd luv\nopam install --deps-only .\n```\n\n*Note: the clone *has* to be recursive, because libuv is vendored using a git\nmodule. Also, the examples require OCaml 4.08+.*\n\nThen, to run, say, [`delay.ml`][delay.ml]...\n\n```\ndune exec example/delay.exe\n```\n\nThe first time you do this, it will take a couple minutes, because Luv will\nbuild libuv.\n\nYou can add your own experiments to the [`example/`][examples] directory. To run\nthem, add the module name to [`example/dune`][example/dune], and then run them\nlike any other example:\n\n```\ndune exec example/my_test.exe\n```\n\nAlternatively, you can try Luv in a REPL by installing [utop][utop]:\n\n```\nopam install --unset-root utop\ndune utop\n```\n\nOnce you get the REPL prompt, try running `Luv.Env.environ ();;`\n\n\u003cbr/\u003e\n\n## External libuv\n\nYou can tell Luv to ignore its vendored libuv, and build against an external one\nby setting `LUV_USE_SYSTEM_LIBUV=yes` during the build. This requires libuv to\nbe findable by `-luv`, `uv.h` to be in the header path, and the Luv version to\nbe at least 0.5.7.\n\nThe external libuv can be considerably older than what Luv vendors \u0026mdash; at\nthe moment, Luv supports compilation against libuv versions all the way down to\n1.3.0, using a bunch of [shims][shims].\n\nIf you use an older libuv, you may want to look at the feature tests exposed by\nLuv in auto-generated module [`Luv.Require`][require]. The one posted online was\ngenerated for Luv's vendored libuv, so everything is present. If you use an\nolder libuv, some of the features will have type `_false feature`.\n\n\u003cbr/\u003e\n\n## License\n\nLuv has several pieces, with slightly different permissive licenses:\n\n- Luv itself is under the [MIT license][license].\n- This repo links to libuv with a git submodule. However, a release archive will\n  generally include the full libuv source. Portions of libuv are variously\n  [licensed][libuv-license] under the MIT, 2-clause BSD, 3-clause BSD, and ISC\n  licenses.\n- The user guide is a very heavily reworked version of [uvbook][uvbook],\n  originally by Nikhil Marathe, which was incorporated into the libuv docs as\n  the [libuv user guide][libuv-guide], and made available under\n  [CC BY 4.0][guide-license].\n\n[luv]: https://github.com/aantron/luv\n[libuv]: https://github.com/libuv/libuv\n[platforms]: https://github.com/libuv/libuv/blob/master/SUPPORTED_PLATFORMS.md#readme\n[maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md#readme\n[ctypes]: https://github.com/ocamllabs/ocaml-ctypes#readme\n[vendor]: https://github.com/aantron/luv/tree/master/src/c/vendor\n[tests]: https://github.com/aantron/luv/tree/master/test\n[guide]: https://aantron.github.io/luv/\n[api]: https://aantron.github.io/luv/luv/index.html#api-reference\n[examples]: https://github.com/aantron/luv/tree/master/example\n[libuv-docs]: http://docs.libuv.org/en/v1.x/\n[experiment]: https://aantron.github.io/luv/introduction.html\n[lwt]: https://github.com/ocsigen/lwt#readme\n[license]: https://github.com/aantron/luv/blob/master/LICENSE.md\n[libuv-license]: https://github.com/libuv/libuv/blob/v1.x/LICENSE\n[uvbook]: https://github.com/nikhilm/uvbook\n[libuv-guide]: http://docs.libuv.org/en/v1.x/guide.html\n[guide-license]: https://github.com/aantron/luv/blob/master/docs/LICENSE\n[processes]: https://aantron.github.io/luv/processes.html\n[threads]: https://aantron.github.io/luv/threads.html\n[loops]: https://aantron.github.io/luv/threads.html#multiple-event-loops\n[unix]: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html\n[delay.ml]: https://github.com/aantron/luv/blob/master/example/delay.ml\n[example/dune]: https://github.com/aantron/luv/blob/master/example/dune\n[utop]: https://github.com/ocaml-community/utop\n[shims]: https://github.com/aantron/luv/blob/master/src/c/shims.h\n[require]: https://aantron.github.io/luv/luv/Luv/Require/index.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faantron%2Fluv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faantron%2Fluv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faantron%2Fluv/lists"}