FlyEnv: a native local development manager whose clean script only removes one native module
All-in-One Native Local Development Environment for Windows, macOS & Linux. Docker alternative for PHP, Node.js, Python and more. Faster alternative to XAMPP, Laragon, MAMP and Laravel Herd with databases, Cron Jobs and runtime management.
At a glance
- What is it?
- FlyEnv installs PHP, Node, Python, Go, databases and web servers directly on Windows, macOS and Linux instead of in containers, and its repository shows the seams: a clean target that deletes one native module, download links pinned to a single version string, and a dozen test entries that each name one script.
- Who is it for?
- FlyEnv fits a developer who wants real services on the host without writing compose files, and it will not fit anyone who needs the isolation a container gives, since its own README draws that line and puts container reproducibility on Docker's side of it. Two things to check before adopting it.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- xpf0000/FlyEnv3,363 ★ · +270
| Repository | 2026-07-28 | 2026-11-14 |
|---|---|---|
| xpf0000/FlyEnv | 3.1k | 3.4k |
270 Stars in the last 109 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The clean target deletes one native module and nothing else
Two scripts carry the names a reader would expect to mean something different:
"clean:dev": "npx rimraf dist",
"clean": "npx rimraf node_modules/node-pty/build"The one called clean does not remove a build directory, a cache or generated output. It deletes the compiled build of node-pty, the package that gives the app a pseudo terminal, which is the piece that has to be rebuilt after a native toolchain change. The script that removes dist carries the dev suffix instead. Neither is wrong on its own, but a developer reaching for clean after a bad build gets a node-pty rebuild and finds dist still on disk, and a developer who wants the pseudo terminal rebuilt after switching Node versions has to know to type clean rather than the name they would guess. Both run through npx, so each invocation resolves rimraf at call time instead of pinning it in the lockfile.
Every install link is pinned to the version in package.json
The installation section hard-codes 4.19.1 into every artifact URL: the Windows installer, the Windows portable executable, the macOS Intel dmg, the macOS Apple Silicon dmg, and the four Linux packages covering deb and rpm for x86_64 and arm64. package.json carries the same 4.19.1, and the newest release is v4.19.1 from 2026-09-27, so the three agree at the moment. Keeping them in agreement is manual work, though: eight URLs and one version field change together on every release, which is a slower edit than a version script and a common place for a stale link to survive. The macOS path is the odd one out because it also has a package manager route, brew install flyenv, which is the only install instruction in the file that does not name a version at all and therefore does not need editing.
A dozen test entries, each naming one script and no runner
The script list is where this repository is most honest about its shape. Every test is a separate entry that invokes a single file:
"test:documentation-version": "node scripts/documentation-version-test.mjs",
"test:macos-signing": "tsx scripts/macos-signing-workflow-test.ts",
"test:clickhouse-config-page": "cross-env NODE_ENV=production tsx scripts/clickhouse-config-page-test.ts",
"test:go-gvm": "tsx scripts/go-gvm-test.ts"The naming is per behaviour rather than per module: ClickHouse alone has three entries for the config page, the ch-ui and the service lifecycle, and others cover the Go version manager, the SDKMAN Java parser, the Rust Windows installer, PHP project directories, Hermes providers, PostgreSQL with pgAdmin, module onboarding, documentation versions, macOS signing and two separate tray popup lifecycles. Two runners appear, node for the one mjs file and tsx for the TypeScript ones, and one entry sets NODE_ENV to production. The coverage is aimed at the places where this kind of app actually breaks, a version manager here and a tray icon there, rather than at library code.
The dev runner is bundled into the electron directory through a shim
The developer runner does not run from source. One script bundles it first:
"build-dev-runner": "npx esbuild --platform=node --bundle --packages=external --inject:scripts/shim-dynamic-require.mjs --format=esm scripts/dev-runner.ts --outfile=electron/dev-runner.mjs"Four flags in that line each answer a specific problem. --packages=external keeps dependencies out of the bundle so they resolve from node_modules at runtime, --platform=node and --format=esm produce something Node can execute directly, --inject:scripts/shim-dynamic-require.mjs supplies a shim for a dynamic require that a bundler cannot see, and the output lands at electron/dev-runner.mjs, inside the directory that holds the desktop shell rather than in dist. So a change to the runner or to that shim needs this step to run again, which is why the script exists as its own name instead of being chained onto the development command.
Clearing the macOS quarantine flag runs through sudo
One script exists only to strip the quarantine attribute from prebuilt helpers:
"fix-flyenv-helper": "sudo xattr -dr \"com.apple.quarantine\" ./build/bin/arm/flyenv-helper && sudo xattr -dr \"com.apple.quarantine\" ./build/bin/x86/flyenv-helper"It is macOS only, it needs root, and it targets two hard-coded paths, the arm build and the x86 build of the same helper binary, so both architectures get the attribute removed whether or not the machine is one of them. The attribute is what Gatekeeper sets on a downloaded file, and clearing it is the documented way to let a locally built binary run without a quarantine prompt. Written this way, the escape hatch is a root command a developer runs on a path inside the build directory, which means anyone auditing this project should know that clearing it is a manual step and not something the application does for you at launch.
Update manifests for five targets sit in the repository root
Six files in the root describe how the application updates itself: app-update.yml plus latest.yml, latest-mac.yml, latest-mac-arm64.yml, latest-linux.yml and latest-linux-arm64.yml. That is one manifest per platform pair, which is the shape an electron-builder updater expects, and keeping them in the repository rather than on a release server means the update feed is whatever the repository says it is. The Windows side is signed, and the signing story is spelled out: packages are built through GitHub Actions, and free Windows code signing comes from SignPath.io with the certificate provided by the SignPath Foundation. The consequence for anyone evaluating this project is that the trust chain for a Windows binary runs through a foundation rather than through a certificate purchased by the author, and the manifests in the root are the files to inspect if you want to know which builds a client will accept.
A DNS server, an FTP server and a tunnel client, all installed natively
The runtime list is the familiar one, PHP through Zig, MySQL through ClickHouse, Nginx through Tomcat. The other tools list is where the host surface grows: a DNS server, an FTP server, an SMTP catcher for Mailpit, Cloudflare Tunnel, MkCert for certificates, a static HTTP server, Cron Jobs and Git. None of these sit in a container, because the stated premise is that no container setup is required and services run directly on the operating system. That is the trade the project is making, speed and direct file access in exchange for the boundary a container would have provided. It is also why HTTPS for a local domain, reverse proxies and per-project ports are ordinary operations here: each one binds a socket on the real machine, and the app has no network namespace of its own to hide them in.
The comparison table admits the overlap with four other tools
FlyEnv names its competitors rather than avoiding them. A table maps XAMPP and MAMP to needing more runtimes and project level versions, Laragon to needing a cross platform workflow, Laravel Herd to needing an environment beyond PHP, and Docker Desktop to wanting native services when container parity is not the task. A line above it is blunter: if those tools already make sense to you, this solves a similar problem across a broader stack. The same paragraph picks out AI coding clients and a built-in MCP server as the part that is new, where an MCP client is registered inside the app and can inspect selected services, sites, configs, logs, versions and lifecycle actions. The release history backs the breadth claim in small ways: v4.19.0 added a plugin market and a Kafka plugin, v4.18.3 added first-run technology stack selection with drag-and-drop ordering of startup groups.
Editorial conclusion
FlyEnv fits a developer who wants real services on the host without writing compose files, and it will not fit anyone who needs the isolation a container gives, since its own README draws that line and puts container reproducibility on Docker's side of it. Two things to check before adopting it. First, the surface it puts on your machine is wider than the runtime list suggests: a DNS server, an FTP server, an SMTP catcher, a tunnel client and certificate tooling all install and run natively, so bind addresses and open ports belong in your review, not just the language versions. Second, the build is Yarn and Node 18 or newer, and the macOS helper fix asks for sudo, so a locked-down workstation is not the target. If you take it, take it from a tagged release rather than the default branch, and read the update manifests before you trust the auto-update path.
Frequently asked questions
how to use flyenv
Install a build for your platform, either from the release artifacts, which cover a Windows installer and portable executable, an Intel and an Apple Silicon macOS dmg, and deb and rpm packages for x86_64 and arm64 Linux, or with brew install flyenv on macOS. Building from source wants Node 18 or newer and then yarn install followed by yarn run dev.
is flyenv free
The repository is BSD 3-Clause licensed and packages are built through GitHub Actions, with Windows code signing provided free by SignPath.io under the SignPath Foundation. The project file describes no paid tier, and the download links point at public release artifacts.
Does FlyEnv need Docker to run a local stack?
No. The stated premise is that installed services run directly on the operating system with no container setup, and its own comparison text puts containerised reproducibility and production parity on the Docker side of the line. It offers a Docker-style route for CI parity only as something it explicitly does not aim to replace.
What can FlyEnv manage besides language runtimes?
Beyond PHP, Node.js, Python, Java, Go, .NET, Flutter, Ruby, Rust, Erlang, Bun, Deno and Zig, the list covers databases such as PostgreSQL, MongoDB, ClickHouse, Neo4j and Qdrant, servers including Nginx, Apache, Caddy, FrankenPHP and Tomcat, cache and messaging with Redis, Memcached and RabbitMQ, plus a DNS server, an FTP server, Mailpit, Cloudflare Tunnel and MkCert.
Official sources
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.
[](https://hysenlabs.com/projects/xpf0000-flyenv)Star history chart for your README
[](https://hysenlabs.com/projects/xpf0000-flyenv)Was this useful?