Library / SDK
esy/esy avatar
esy/esy

Esy puts an npm style workflow in front of the Reason and OCaml toolchain

package.json workflow for native development with Reason/OCaml

853 stars95 forksReasonNOASSERTION

At a glance

What is it?
Esy is a package manager for Reason and OCaml that centres everything on a package.json file, installing to a sandbox instead of a system switch. It is published on npm, its own sources are built with dune and opam, the licence is one GitHub cannot classify, and the project asks for sponsors.
Who is it for?
Esy fits a team that wants to onboard Reason or OCaml developers from the JavaScript side of an organisation, because the dependency declaration, the install and the sandbox all look like npm and the tool handles the compiler and opam details underneath. It is the wrong tool for someone already settled on an opam switch with a dune workspace, since Esy adds a second resolution layer on top of the same compiler.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 29 days ago.
What is it written in?
Mainly Reason, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Esy addresses: OCaml tooling is hard to reproduce

Esy is a package manager for Reason and OCaml centred around the npm workflow, and the README explains the motivation in plain terms. Reason and OCaml are compiled languages, setting up the tools and developing a workflow that is intuitive and well documented is daunting, and developing natively compiled apps is hard to reproduce and often requires additional tooling.

The bet is that a familiar interface solves that. Where opam exposes a switch, a compiler selection and a solver that most JavaScript developers have never had to think about, Esy expects a package.json file. The primary language of the repository is listed as Reason, with the sources written in a Flow typed JavaScript dialect, since the .flowconfig and flow-typed/ directories are part of the tree.

The second half of the answer is the sandbox. Esy describes itself as offering light-weight sandboxing, which means a project installs its own copies of its dependencies into a project local store rather than mutating a shared compiler switch. The package.json file is the centre of that workflow, and the tool's own history is credited to the PackageJsonForCompilers experiment by Jordan Walke, which the README links as the origin of the idea.

For a reader who has never used OCaml, the important point is that Esy does not replace opam or dune. It wraps them and gives them a different front door.

The esy-* directories show how the tool is divided

The repository layout is unusually revealing because each service of the package manager has its own directory, and each one is named for what it does.

There is esy-package-config for reading and validating project configuration, esy-solve for dependency resolution, with esy-solve-cudf sitting beside it as a separate package that also appears as a devDependency in package.json. esy-fetch handles downloading artefacts, esy-build runs build steps, esy-build-package packages built output, esy-lib holds shared code, and esy-primitives and esy-shell-expansion provide the low level helpers. esy-command-expression parses the command expressions users write, esy-runtime handles the runtime pieces, esy-rewrite-prefix and esy-version do what their names say, and esy-opam deals with the opam side of the world. There is also esy-install-npm-release for the path where the tool itself is published through npm.

The build system underneath is OCaml tooling rather than JavaScript. The tree contains a dune-project, a dune-workspace, a dune directory and esy.opam, esy.opam.locked and esy.opam.template, so the project can be built and released through opam as well as npm. A flake.nix and flake.lock sit alongside a nix/ directory, which is the path for reproducible environments.

There is a design/ directory, which holds the design notes, and the Makefile carries an OPAM_REPOSITORY_COMMIT pinned to a specific commit from 2 June 2023, meaning the opam repository is fetched at a fixed revision rather than at HEAD.

Installing Esy is one npm command

Esy is available on npm and the install is global, because it is the tool that manages a project rather than a dependency of one.

sh
npm i -g esy

That is the whole installation section in the README. Once it is on your path, the documentation is where the real guidance lives, both on the website at esy.sh and in the docs/ folder of the source tree, which the README points to as an alternative to the site.

The contribution documentation is the part most developers will need if they intend to change Esy itself. The docs/contributing directory holds instructions for building the source, the CI setup, the release process and the internal concepts of the tool, and the same content is published online under the contributing section.

One thing the README does not show is a first project command. The package.json workflow is the core of the tool and its schema is documented on the website rather than in the README, so the practical first step after installing is to read the site documentation and set up a sample project there before pointing Esy at real code.

Issues are tracked in the esy/esy repository, so bug reports and feature discussion happen on GitHub rather than on the site.

Building Esy itself needs opam, dune and a static musl build

The Makefile shows what it takes to produce the tool rather than use it. There are two build paths, build-with-opam and build-with-esy, the second of which is the tool building itself, which is a good test of whether a package manager can bootstrap.

The opam path has three steps. The first initialises a bare, sandboxing disabled opam repository.

bash
opam init -y --disable-sandboxing --bare

The second creates a switch for the project itself, with the compiler packages and the static musl options appended.

bash
opam switch create . $(OPAM_COMPILER_BASE_PACKAGES)$(MUSL_STATIC_PACKAGES) -y --no-install

The third installs only the dependencies of the locked opam file.

bash
opam install . --locked --deps-only -y

After that, dune builds the release-static profile and installs to a prefix, which defaults to /usr/local and can be redirected with APP_ESY_INSTALL. The release arguments include --no-env and --static, and the Makefile notes that the static flag is no longer conditional, so every platform including FreeBSD attempts a static build. There is a dedicated openbsd target that raises the stack and file descriptor limits, fetches a perl shasum helper, and swaps sudo for doas.

That much machinery is a fair signal about the tool's ambitions. Esy is not a thin wrapper around opam, it is a reimplementation of the front end with its own solver, its own fetch layer and its own build runner.

Test suites split into unit, end to end and slow end to end

The test layout is split by cost. There is a test-unit/ directory, a test-e2e/ directory and a test-e2e-slow/ directory, plus a test/ directory. The jest.config.js file shows that the JavaScript side of the project runs on jest, with the test script in package.json set to jest test-e2e.

The end to end suites are where the interesting assertions live, because Esy's behaviour is mostly about what happens to a real project on disk: which packages get built, in what order, and what ends up in the sandbox. There is even a dedicated test-e2e-re/ directory, which suggests the rewrite and the rewrite prefix rewriting code has its own coverage.

The jest setup includes a pnp resolver, which fits the project, since the flow types in flow-typed/ and the.flowconfig file indicate the sources are checked with Flow. The devDependencies also pull in jest-junit for reporting, and the resolutions block pins a long list of transitive packages, including braces, micromatch, semver, ws, tough-cookie, ajv and tar, most of which have had security advisories in the past. That pinning is a maintenance burden that comes with running a large JavaScript dependency tree, and the tree here is large for a tool whose selling point is a small, reproducible workflow.

The package.json in the repository records version 0.6.14, while the newest published release is 0.9.2 dated 2025-08-04, so the version in the source tree is not a reliable guide to what npm serves.

One maintainer, an unclassified licence and a request for sponsors

The governance is stated in a short paragraph near the end of the README. The project was originally authored by Andrey Popp and is currently maintained by ManasJayanth, and the README says plainly that the project is not funded and could benefit from generous sponsorships.

That single sentence tells you what the risk profile is. A package manager that every developer on a project has to install globally, with a solver and a build system of its own, depends on very few people. The repository is not archived and the last push was on 2026-09-24, so the code is being worked on, but there is no team and no funded roadmap behind it.

The licence is the other loose end. GitHub records it as a custom licence that it cannot classify, and the terms are in the LICENSE file at the root of the tree. A custom licence is not necessarily a restrictive one, but it is not the well known MIT or Apache 2.0 text that a legal reviewer recognises on sight, so read it before you build a company toolchain on it. Note that the packages Esy pulls from the opam ecosystem carry their own licences, and those come with the sandbox rather than from this repository.

The release history itself looks healthy, with 0.9.1 on 2025-07-03, 0.9.2-beta.1 on 2025-07-26 and 0.9.2 on 2025-08-04.

How Esy differs from a plain opam and dune setup

The realistic alternative is the one Esy wraps. An opam switch with a dune project gives you a compiler, a dependency solver and a build system, and dune workspaces handle monorepos. Esy offers the same capability behind a package.json, a project local sandbox instead of a shared switch, and an npm style install for the tool itself.

The difference in approach is real and it cuts both ways. The JSON manifest is easier for a web developer to read, easier to generate from other tooling, and easier to review in a pull request. The sandbox means a project does not mutate a machine wide switch, which makes a checkout buildable on a colleague's laptop without a day of environment repair.

Against that, Esy inserts its own solver between you and opam. That is an extra layer where a dependency conflict can be reported in Esy's own vocabulary rather than opam's, and it means the opam repository is fetched at a pinned commit rather than at whatever HEAD is, which is a stability choice with a freshness cost. There is also a second resolution layer to debug when something fails to build, and the Makefile shows that building Esy itself needs opam, dune, a pinned opam repository commit and a musl static toolchain.

If your team already runs opam and dune well, Esy adds a layer rather than removing one. If your team comes from npm and is starting an OCaml project, that layer is the point.

Editorial conclusion

Esy fits a team that wants to onboard Reason or OCaml developers from the JavaScript side of an organisation, because the dependency declaration, the install and the sandbox all look like npm and the tool handles the compiler and opam details underneath. It is the wrong tool for someone already settled on an opam switch with a dune workspace, since Esy adds a second resolution layer on top of the same compiler. Before adopting it, read the custom LICENSE file that GitHub cannot classify, check whether the version on npm matches the release you expect, since package.json in the repository records 0.6.14 while the newest published release is 0.9.2, and confirm that the compiler version in your project is one Esy supports.

Frequently asked questions

How do I install Esy?

Esy is available on npm and is installed globally with npm i -g esy. The documentation lives on the website at esy.sh and in the docs folder of the source tree.

What is Esy used for?

Esy is a package manager for Reason and OCaml centred around the npm workflow, offering a package.json based workflow and light-weight sandboxing so that dependencies are installed into a project local store rather than a shared opam switch.

How do I build Esy from source?

The Makefile offers build-with-opam and build-with-esy targets. The opam path runs opam init with a bare repository, creates a switch with opam switch create, installs dependencies with opam install . --locked --deps-only, then builds with dune and installs to a prefix that defaults to /usr/local.

How is Esy tested?

The repository has separate unit, end to end and slow end to end suites, and the package.json test script runs jest test-e2e. The sources are Flow typed, with a .flowconfig and a flow-typed directory, and the devDependency list includes jest-junit for reporting.

Who maintains Esy and what license does it use?

The project was originally authored by Andrey Popp and is currently maintained by ManasJayanth, and the README states that it is not funded and could benefit from sponsorships. GitHub records the licence as a custom one it cannot classify, with the terms in the LICENSE file.

Official sources

  1. esy/esy on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/esy-esy.svg)](https://hysenlabs.com/projects/esy-esy)

Was this useful?