Open-source project
flomesh-io/pipy avatar
flomesh-io/pipy

Pipy puts a JavaScript script engine inside a C++ proxy

Pipy is a programmable proxy for the cloud, edge and IoT.

833 stars81 forksC++NOASSERTION

At a glance

What is it?
Pipy is a small C++ proxy for cloud, edge and IoT deployments whose behavior is written in PipyJS and assembled from pluggable filters, so the same binary serves as a reverse proxy, a gateway or a traffic processor depending on the script you give it.
Who is it for?
Pipy is the right choice for platform engineers who need a proxy whose behavior they can change by script, at the edge or inside a service mesh, and it is the wrong choice for a team that wants declarative configuration or a stable plugin ecosystem, because the rules are JavaScript and the release line has not moved since 1.5.14 on 2025-09-18; before adopting it, read the LICENSE file, since the project uses a custom licence rather than a standard one, and confirm that the filters you need exist for your protocol.
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 62 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

The proxy is a script engine first and a router second

Pipy is described as a programmable proxy for the cloud, edge and IoT, written in C++, and fully programmable through PipyJS, a tailored version of standard JavaScript. That framing is the whole design. Most people meet Pipy as a high performance reverse proxy, and the README says as much, but the argument the project makes is that its real power comes from a range of basic pluggable building blocks called filters, with no restriction on how they are combined.

So a Pipy deployment is not a configuration file describing routes. It is a script that wires filters together and decides what happens to a connection as it moves through them. The README lists what people have used it for: converting protocols, recording network traffic, signing and verifying messages, triggering serverless functions and health checking servers. Those are five different products, and they come from the same mechanism.

The topic list for the repository shows the same spread: api-gateway, ingress-gateway, egress-gateway, forward-proxy, reverse-proxy, socks-proxy, load-balancer, service-mesh and sidecar-proxy all appear. The target user is a platform or edge engineer who already knows that a proxy sits in the request path and needs it to do something a stock reverse proxy cannot.

The performance claims are stated by the project rather than measured by third parties: Pipy leverages asynchronous network I/O, allocated resources are pooled and reused, and data is transferred internally by pointers whenever possible.

Filters are the unit of composition, and PipyJS is the unit of programming

Two ideas carry the weight here, and they are different in kind.

Filters are the runtime building blocks. The README is explicit that the point is providing a range of basic pluggable filters and not imposing restrictions on how you combine them, and it says outright that it is entirely up to you. A filter that balances, filters, caches, signs or rewrites is a piece you can place in a chain, and Pipy's own sample directory shows how varied that space is: samples/bgp, samples/bootload, samples/bpf, samples/dns, samples/fastcgi, samples/gateway, samples/nat, samples/netlink, samples/proxy, samples/rate-limit, samples/scan, samples/serve, samples/stress, samples/webapp and samples/ws-udp. BGP and eBPF samples next to a rate limit sample tells you the ambition.

PipyJS is the programming surface. At the core, Pipy is a script engine running a tailored version of ECMA standard JavaScript, and the argument the README makes for it is freedom: other products based on YAML configuration files give you a fixed set of knobs, while a scripting language gives you the whole language. The tradeoff follows directly. Pipy is more open than open source, the README says, without hiding details in a black box, and that same openness means a mistake in your script is your problem, not a limitation of the product.

Building from source needs Clang, CMake and optionally Node.js

The build prerequisites are short and stated up front: Clang 5.0 or newer, CMake 3.10 or newer, and Node.js v12 or newer, but only if the builtin Admin UI is enabled. With those in place, the build is one script:

bash
./build.sh

The result lands at bin/pipy.

The Makefile in the repository shows how much is really configurable. The full target builds the GUI and the codebases with CMake options for PIPY_GUI, PIPY_CODEBASES, PIPY_BPF, PIPY_SOIL_FREED_SPACE, PIPY_ASSERT_SAME_THREAD and PIPY_LTO, all set to ON for the GUI, OFF for the two SOIL and thread assertions, and LTO off. There is a no-gui target that skips the npm install and npm run build steps and turns PIPY_GUI and PIPY_CODEBASES off, and a debug target that switches to Debug and turns PIPY_SOIL_FREED_SPACE and PIPY_ASSERT_SAME_THREAD on.

That set of switches is worth reading as a statement about the codebase. Assertions on the same thread and a freed space check in SOIL are off by default in release, which tells you the project trades some strictness for speed in production builds. The install target copies the binary to /usr/local/bin/pipy and makes it executable for everyone.

Repo mode starts on port 6060 and opens an Admin UI

The first run is deliberately frictionless. Run the binary with zero command line options and Pipy starts in repo-mode listening on the default port 6060:

bash
$ bin/pipy

[INF] [admin] Starting admin service...
[INF] [listener] Listening on port 6060 at ::

Point a browser at http://localhost:6060 and you get the Admin UI, where the README says you can explore the documentation and play around with the tutorial codebases.

Repo mode is the on-ramp to the rest of the product. It gives you a running instance with a management surface before you have written a single filter, and the tutorial/ directory that ships in the repository is the same content the Admin UI exposes. The Dockerfile copies the tutorial directory into /etc/pipy/tutorial in the image, so the tutorials travel with the binary in container deployments as well.

The Admin UI is not a separate product though, and that has architectural consequences. The package.json at the repository root is a Gatsby site with React 17, Material UI, monaco-editor and the MDX toolchain, and its scripts are gatsby build, gatsby develop, gatsby serve and gatsby clean. The UI is a compiled front end embedded in the C++ binary, which is why the build needs Node.js when PIPY_GUI is enabled, and why a build without the GUI frontend resources gives you an executable merely around 10MB with zero external dependencies.

The container image is Alpine with a non-root user and one exposed port

The Dockerfile shows how the project ships to Kubernetes and similar environments, and it is a good example of a small binary wrapped carefully.

The build stage starts from alpine:3.22.2 and installs the toolchain through apk, including cmake, clang, alpine-sdk, autoconf, automake and libtool, then configures with cmake and the PIPY_GUI, PIPY_STATIC and PIPY_CODEBASES options before running make with a job count taken from getconf _NPROCESSORS_ONLN. The release stage copies the binary to /usr/local/bin/pipy, copies the tutorial content to /etc/pipy/tutorial, and installs runtime packages including ca-certificates, libcap, su-exec, iptables, socat, logrotate, curl and busybox-extras.

Two details stand out. The image creates a dedicated user with adduser -Su 1340 pipy and switches to it with USER pipy, so the proxy does not run as root inside the container. And it exposes a single port, 6000, which is the listener port used in the container path, distinct from the 6060 admin port used in the local repo-mode run.

For multi-architecture builds the repository carries Dockerfile-loongnix, a multi_arch_images_build.sh script, an rpm/ directory and a get-pipy.sh installer script, which matches the compatibility list covering X86/64, ARM64, LoongArch and Hygon.

Testing platforms and architectures are named, and the license is not standard

Pipy is described as being constantly tested on RHEL/CentOS, Fedora, Ubuntu, Debian, macOS, FreeBSD, OpenBSD, OpenEuler, OpenWrt, Deepin and Kylin. That list is a deployment compatibility claim you can check against your own fleet, including the router oriented OpenWrt and the Kylin and Deepin distributions.

The licensing is the part that needs the most attention. The project does not use one of the standard open source licences that GitHub can classify automatically. The repository contains COPYRIGHT, LICENSE and TRADEMARK files as separate documents, and the README asks readers to refer to COPYRIGHT and LICENSE rather than reproducing the terms. So the correct move for an adopter is to read those two files directly, because the label Other tells you nothing about redistribution, modification or deployment obligations.

On maintenance, the picture is mixed. The last push was on 2026-08-22, so the code tree is being worked on. The tagged releases are older: 1.5.14 on 2025-09-18, 1.5.13 on 2025-07-15 and 1.5.12 on 2025-06-05. The README also states that Pipy is more open than open source, meaning the internals are visible and modifiable, but the licensing terms are exactly the part you should read before building on it commercially.

How Pipy compares with declarative gateway configuration

The obvious alternative is the kind of gateway that describes routes, upstreams and policies in a YAML or JSON file, and the README itself frames the comparison by disparaging other products based on YAML configuration files.

The difference in approach is where the two designs diverge. A declarative gateway gives you a fixed vocabulary of directives and a schema that validates them, so a mistake is caught by the parser and the configuration can be reviewed and diffed like code. Pipy gives you a scripting language instead, so the expressiveness is much higher, a protocol conversion or a message signature is ordinary code rather than a feature request, and the failure mode moves from a rejected config file to a runtime error in a script you wrote.

There is also a middle option that the sample directories suggest. samples/bgp, samples/bpf, samples/nat and samples/netlink show Pipy being used for network level work that a declarative gateway generally does not attempt, and samples/scan, samples/stress and samples/bootload suggest it is used to test and load the network rather than only to route traffic through it.

For an edge or service mesh deployment where the traffic rules are ordinary, a declarative config may be easier to operate. For anything where the proxy has to understand or rewrite the payload, the scripting model is the reason to pick Pipy.

Editorial conclusion

Pipy is the right choice for platform engineers who need a proxy whose behavior they can change by script, at the edge or inside a service mesh, and it is the wrong choice for a team that wants declarative configuration or a stable plugin ecosystem, because the rules are JavaScript and the release line has not moved since 1.5.14 on 2025-09-18; before adopting it, read the LICENSE file, since the project uses a custom licence rather than a standard one, and confirm that the filters you need exist for your protocol.

Frequently asked questions

What is Pipy and what language is it written in?

Pipy is a programmable proxy for cloud, edge and IoT deployments, written in C++, and its behavior is configured with PipyJS, a tailored version of standard JavaScript. A build without the GUI frontend resources produces an executable around 10MB with zero external dependencies.

How do I build Pipy from source?

You need Clang 5.0 or newer, CMake 3.10 or newer and, only if the Admin UI is enabled, Node.js v12 or newer. Run ./build.sh and the resulting binary is at bin/pipy, and the Makefile also offers no-gui and debug targets.

How do I start Pipy and reach its Admin UI?

Run bin/pipy with no command line options and it starts in repo-mode listening on port 6060, printing a startup line for the admin service and the listener. Opening http://localhost:6060 in a browser gives you the Admin UI with the documentation and the tutorial codebases.

What licence does Pipy use?

It uses a custom licence that GitHub cannot classify as a standard one. The terms live in the COPYRIGHT and LICENSE files in the repository, and the README points readers to those two documents rather than summarizing the obligations.

Which platforms does Pipy run on?

The README lists RHEL/CentOS, Fedora, Ubuntu, Debian, macOS, FreeBSD, OpenBSD, OpenEuler, OpenWrt, Deepin and Kylin as platforms Pipy is tested on, and X86/64, ARM64, LoongArch and Hygon as supported architectures.

Official sources

  1. flomesh-io/pipy 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/flomesh-io-pipy.svg)](https://hysenlabs.com/projects/flomesh-io-pipy)

Was this useful?