# Pony Pony is an open-source, object-oriented, actor-model, capabilities-secure, high-performance programming language. This documentation covers learning Pony, using the ecosystem, frequently asked questions, and the philosophy behind the language. # Learn # Learn Pony New to Pony? Start with [installing Pony](https://www.ponylang.io/learn/installing-pony/index.md) and then work through the [tutorial](https://tutorial.ponylang.io). The tutorial covers the language from the ground up and is the best way to get a feel for how Pony works. Once you’re comfortable with the basics, the [Pony Patterns](https://patterns.ponylang.io) cookbook and [standard library documentation](https://stdlib.ponylang.io) are good next steps. The [cheat sheet](https://www.ponylang.io/media/cheatsheet/pony-cheat-sheet.pdf) is handy to keep nearby as a quick reference. [Reference capabilities](https://www.ponylang.io/learn/reference-capabilities/index.md) are the concept most people struggle with. We have a page dedicated to resources that will help you get over that hump. If you get stuck, don’t worry. The Pony community is small but helpful. Check out [getting help](https://www.ponylang.io/learn/getting-help/index.md) for how to reach us. # Getting Help If you run into trouble while you are learning Pony, don’t worry, we’ve got you covered. If you are looking for an answer “right now”, we suggest you give our Zulip community a try. Whatever your question is, it isn’t dumb, and we won’t get annoyed. We only request that you follow proper etiquette: - Be polite and respectful. Constructive criticism is good, but it’s even more important that users get along and foster a welcoming community. Being rude won’t get your questions answered. - Be clear whether you are asking if something already exists in Pony (eg. “does Pony have X?”), or if you are requesting new functionality. We’ve received several messages asking about libraries or features present in other languages, by new users who weren’t familiarized with Pony’s philosophy or programming style well enough. Make sure that you understand what is your problem and if it makes sense in Pony’s ecosystem, and clarify your intention of proposing a change. Baseless suggestions will be ignored. - Don’t rush experienced users for immediate answers. This is an all-volunteer project, and folks will help whenever they are available. Also, Zulip makes it easy to keep conversations of the same topic in one place, so you can check later to see if someone has answered your questions. The [#beginner help](https://ponylang.zulipchat.com/#narrow/stream/189985-beginner-help) channel is a good starting point for basic questions. If you need more information on what is considered appropriate or inappropriate behaviour, check out our [Code of Conduct](https://github.com/ponylang/ponyc/blob/main/CODE_OF_CONDUCT.md). Many folks encounter the same issues or have the same questions, be sure to give the [frequently asked questions](https://www.ponylang.io/faq/index.md) section of this website a read. Think you’ve found a bug? It’s quite possible. Pony is a relatively young language that is still changing at a rapid pace and bugs do happen. Your best bet. Write to the mailing list with your issue and verify that you are experiencing an issue. Once a more knowledge member of the community confirms you are experiencing a bug, open an issue. - [Open an issue](https://github.com/ponylang/ponyc/issues) The Pony community while small is very helpful and inviting. We think you’ll find interacting with us to be an enjoyable experience. You can find a lot more community-related resources in the [community section](https://www.ponylang.io/community/index.md) of this site. # Installing Pony The easiest way to install Pony is through [ponyup](https://github.com/ponylang/ponyup), Pony’s toolchain manager. Ponyup handles installing and updating the Pony compiler and related tools. ## Supported platforms | OS \\ CPU | `amd64` | `arm64` | `arm32` | `riscv64` | | ----------------- | ----------- | ------------- | -------------- | --------- | | **Linux** | ✅ Released | ✅ Released | 🔧 Best-effort | 🧪 Tested | | **macOS** | ✅ Released | ✅ Released | — | — | | **Windows** | ✅ Released | ✅ Released | — | — | | **FreeBSD** | 🧪 Tested | ✗ Unsupported | — | — | | **OpenBSD** | 🧪 Tested | ✗ Unsupported | — | — | | **DragonFly BSD** | 🧪 Tested | — | — | — | - ✅ **Released** — official prebuilt binaries; also tested in CI - 🧪 **Tested** — tested in CI; build from source (no prebuilt binary) - 🔧 **Best-effort** — not in CI; built from source and tested periodically on real hardware - ✗ **Unsupported** — no support - — **Not applicable** — combination doesn’t exist On Windows, the minimum supported version is **Windows 11 / Windows Server 2022** (build 20348). Pony’s networking uses an OS readiness API introduced in that build; earlier versions, including Windows 10, are unsupported. Platforms marked 🧪 Tested or 🔧 Best-effort have no prebuilt binary; you’ll need to [build ponyc from source](https://github.com/ponylang/ponyc/blob/main/BUILD.md). ## Install ponyup On Linux or macOS, run: ``` sh -c "$(curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/ponylang/ponyup/latest-release/ponyup-init.sh)" ``` ## Install the Pony compiler Once ponyup is installed, install the latest release of the Pony compiler: ``` ponyup update ponyc release ``` Prebuilt packages are only available for certain platforms. Check the [ponyc INSTALL.md](https://github.com/ponylang/ponyc/blob/main/INSTALL.md) for the current list of supported distributions. If yours isn’t listed, you’ll need to build from source. ## Additional dependencies On Linux, the Pony compiler requires a C compiler and may need additional libraries depending on your distribution. See the [ponyc installation instructions](https://github.com/ponylang/ponyc/blob/main/INSTALL.md) for distro-specific details. ## More information See the [ponyup repository](https://github.com/ponylang/ponyup) for full documentation, including how to install nightly builds and manage multiple toolchain versions. # Papers If reading academic papers is your thing, you’re in luck. There are a number of papers that have been written about Pony. We host a number of them on this website. If you’re interested in learning more about “deep Pony”, these papers are a great place to start. ## [Pony: Co-designing a Type System and a Runtime](https://www.ponylang.io/media/papers/codesigning.pdf) The best overview paper. Explains how Pony’s type system and runtime were designed together so that reference capabilities enable a concurrent garbage collector without stop-the-world pauses. ## [Deny Capabilities for Safe, Fast Actors](https://www.ponylang.io/media/papers/fast-cheap.pdf) Introduces deny capabilities, the formal foundation for Pony’s reference capability system. Shows how denying certain operations on a reference (rather than granting them) lets the type system guarantee data-race freedom. ## [A Principled Design of Capabilities in Pony](https://www.ponylang.io/media/papers/a_prinicipled_design_of_capabilities_in_pony.pdf) Extends the deny capabilities work with a more complete formalization. Covers viewpoint adaptation, safe-to-write, and how capabilities compose under aliasing and subtyping. ## [ORCA: GC and Type System Co-Design for Actor Languages](https://www.ponylang.io/media/papers/orca_gc_and_type_system_co-design_for_actor_languages.pdf) Describes Pony’s production garbage collector. ORCA uses the type system’s knowledge of reference capabilities to do per-actor garbage collection with no stop-the-world pauses and no read or write barriers. ## [Ownership and Reference Counting based Garbage Collection in the Actor World](https://www.ponylang.io/media/papers/OGC.pdf) An earlier take on actor garbage collection that influenced ORCA. Combines ownership tracking with reference counting to collect both objects within an actor and actors themselves. ## [Fully Concurrent Garbage Collection of Actors on Many-Core Machines](https://www.ponylang.io/media/papers/opsla237-clebsch.pdf) Focuses on collecting actors themselves (not just the objects they own) without stopping the world. Covers the protocol for detecting when an actor is unreachable and can be reclaimed. ## [A String of Ponies: Transparent Distributed Programming with Actors](https://www.ponylang.io/media/papers/a_string_of_ponies.pdf) Explores distributing Pony actors across multiple machines. Actors communicate the same way whether local or remote, so distribution is transparent to the programmer. ## [Formalizing Generics for Pony](https://www.ponylang.io/media/papers/formalizing-generics-for-pony.pdf) Covers how generic types interact with reference capabilities. Works through the formalism for constraining type parameters with capabilities and how that affects subtyping. # Reference Capabilities If you are like most people learning Pony, your biggest stumbling block is going to be [reference capabilities](https://tutorial.ponylang.io/capabilities/reference-capabilities.html). Reference capabilities look like a very foreign concept to most folks. This isn’t surprising as they are one of the ideas that make Pony unique. Lots of folks get frustrated while learning reference capabilities and end up thinking that Pony has “too much type system” or is “too hard”. While we don’t agree with such assessments, we will agree that they can be quite hard for some folks to get a handle on. ## What are reference capabilities Reference capabilities allow you the programmer to use the Pony type system to guarantee that you are safely handling data in your application. If you try to do something unsafe, your program won’t compile. ## What background do I need? We’ve noticed that folks who have the easiest time with reference capabilities tend to have a couple things in common: - Familiarity with at least one strongly-typed language - Experience working in a highly concurrent, non-actor based language If you are coming from a dynamically typed background then reference capabilities are probably going to be doubly hard for you. Why? Well, you are going to be learning to navigate general type errors in general and then, you’ll have the added overhead of reference capabilities related type errors. It’s quite possible to get over the hump but just be aware you are in for a bit more work. More important than your type system background is your “concurrency background”. While reference capabilities might seem exotic, they aren’t really. They codify in the type system safe data handling practices that many programmers have learned over the course of time. If you have previously worked in a highly-concurrent, thread-based programming language like Java or C++ then there’s a chance that you have a leg up on learning reference capabilities. We’re not going to pretend that all programmers know how to safely handle data when using threads. If they did, we wouldn’t need Pony. The sad fact is, handling data correctly when you have many threads is hard. Even the most experienced programmer makes mistakes and they are really hard to go back and find. That said, if you are at least used to thinking about how different threads interact with data in your program, you have a leg up. Reference capabilities are all about describing for the compiler how data should be handled. So, if you are coming from a single-threaded language like Ruby or Python, odds are, you haven’t thought a lot about many threads safely accessing your variables. That’s ok, it just means you are going to have more work to do on understanding the concepts that the various reference capabilities represent. If you get hung up on something, don’t worry. [We’re here to help](https://www.ponylang.io/learn/getting-help/index.md). ## Reference capabilities resources A note about code samples All recommended resources are incredibly helpful but represent Pony at a given point in time. While the core concepts will remain static, it’s possible that individual code examples will no longer compile with the latest versions of Pony. Pony is pre-1.0 and breaking changes are still quite common. If you run into code that doesn’t work, reach out and [get help](https://www.ponylang.io/learn/getting-help/index.md). There are 4 primary resources that we currently recommend for understanding reference capabilities: - [Safely Sharing Data: Reference Capabilities in Pony](http://jtfmumm.com/blog/2016/03/06/safely-sharing-data-pony-reference-capabilities/) - [Reference Capabilities, Consume and Recover in Pony](https://bluishcoder.co.nz/2017/07/31/reference_capabilities_consume_recover_in_pony.html) - [Pony VUG #1: Sylvan Clebsch - Writing Generic Code](https://vimeo.com/163871856) - [Bang, Hat and Arrow in Pony](https://bluishcoder.co.nz/2016/05/04/bang-hat-and-arrow-in-pony.html) We suggest you start with John Mumm’s excellent overview “[Safely Sharing Data: Reference Capabilities in Pony](http://jtfmumm.com/blog/2016/03/06/safely-sharing-data-pony-reference-capabilities/)” and Chris Double’s “[Reference Capabilities, Consume and Recover in Pony](https://bluishcoder.co.nz/2017/07/31/reference_capabilities_consume_recover_in_pony.html)”. They are both good general overviews of reference capabilities and why they exist. From there, continue on and watch Sylvan’s Pony Virtual Users’ Group presentation on “[Writing Generic Code](https://vimeo.com/163871856)”. A lot of what you see and watch in that video is going to go over your head. Don’t worry, that happens to everyone. We suggest that you pair it with “[Bang, Hat and Arrow in Pony](https://bluishcoder.co.nz/2016/05/04/bang-hat-and-arrow-in-pony.html)”. It’s an excellent write-up of the concepts introduced in the video. If you are looking for a slightly more academic take, [Adrian Colyer](https://twitter.com/adriancolyer) did an excellent write up of [Deny Capabilities for Safe, Fast Actors](https://web.archive.org/web/20241207181100/https://blog.acolyer.org/2016/02/17/deny-capabilities/). It’s an overview of Pony’s reference capabilities. Generics and references capabilities are the hardest things to get a handle on while learning Pony so don’t get frustrated. It’s not just you. We all go through this. During the video, you’ll hear one of our core team members, Sean T. Allen, commenting at numerous points that he was sort of following everything but not all of it. Sean now has a strong grasp on all the concepts. It takes time. Our recommendation is to [watch the video](https://vimeo.com/163871856), read “[Bang, Hat and Arrow in Pony](https://bluishcoder.co.nz/2016/05/04/bang-hat-and-arrow-in-pony.html)” and then try writing code that uses generic classes like collections. Once you have a handle on using generic classes, move on to trying to write your own generic classes. All the while, repeatedly return to watching the video and reading the accompanying blog post. Don’t worry. You will get it. And remember, the [helpful Pony community](https://www.ponylang.io/learn/getting-help/index.md) is waiting to assist. # Watch Videos are a great way to get a feel for Pony. Here are some we recommend. ## [Pony: High-Performance, Memory-Safe Actors (Developer Voices)](https://www.youtube.com/watch?v=u9da3UzEhEI) Sean Allen explains what Pony is, why reference capabilities exist, and how the garbage collector works. Good first video if you want to understand the “why” behind Pony. ## [VUG #11: Pony via a GitHub REST API](https://vimeo.com/592434464) Sean walks through a real Pony library in progress. Good for seeing what actual Pony code looks like. ## [Learn Pony with Brian and Sean, Episode 1](https://www.youtube.com/watch?v=ODelwNLePRA) Sean teaches Brian Pony from scratch. Watch someone ask the questions you’ll have. ## [Learn Pony with Brian and Sean, Episode 2](https://www.youtube.com/watch?v=wBzPIYgfbdo) Continuation of the hands-on learning session. # Use # Use The Use section collects practical information for developing with Pony. **Development Environment** covers tools for setting up and managing your project: dependency management with corral, the Pony language server for editor integration, linting with pony-lint, documentation generation with pony-doc, LLM skills for AI-assisted development, and a query server for AI coding agents. **Development** covers writing, testing, debugging, and optimizing Pony code. You’ll find guides on unit testing and property-based testing with the standard library, step debugging with LLDB, memory tracking, tracing, and performance tuning. **Cross-Compilation** covers building Pony programs on one platform to run on another. ponyc has a built-in linker for cross-compiling to Linux targets including RISC-V and ARM. **Ecosystem** lists official packages maintained by the Pony developers. **Build and Release Tools** covers Docker images, GitHub Actions, and CI/CD tooling maintained by the Pony developers for building and releasing Pony projects. # Build and Release Tools The Pony Developers maintain a number of repositories that contain tools designed to make it easier to build and release projects associated with the Pony programming language. Each of the repositories is used extensively by us. We encourage the community to use and contribute to these repositories. If you’d like to discuss contributing to any of the repositories, please stop by the [#contribute to Pony](https://ponylang.zulipchat.com/#narrow/stream/192795-contribute-to-Pony) channel. To get assistance using any of the build and release tools, please stop by the [#tooling](https://ponylang.zulipchat.com/#narrow/stream/190367-tooling) channel. ## Container Images The [shared-docker](https://github.com/ponylang/shared-docker) repository contains the Dockerfiles and scripts used to build the Docker images used by the Pony Developers. We have a variety of different types of images available. See the repository for more information. A variety of different images are available including: - Build environments with the Pony compiler and SSL libraries installed. These are updated nightly and for each release of the Pony compiler. - Build environment with the Pony compiler and PCRE installed. It is updated nightly and for each release of the Pony compiler. ## Tools ### [changelog-tool](https://github.com/ponylang/changelog-tool) Tool for modifying “standard Pony” changelogs. ## GitHub Actions ### [changelog-bot-action](https://github.com/ponylang/changelog-bot-action) Bot to update a Pony format changelogs with new entries. ### [library-documentation-action-v2](https://github.com/ponylang/library-documentation-action-v2) Generates documentation for Pony modules. ### [release-bot-action](https://github.com/ponylang/release-bot-action) Bot that handles the standard release process for ponylang projects. ### [release-notes-bot-action](https://github.com/ponylang/release-notes-bot-action) Bot to update release notes with new entries. ### [release-notes-reminder-bot-action](https://github.com/ponylang/release-notes-reminder-bot-action) Bot to remind that release notes are needed when a “CHANGELOG label” is added to a PR. # Working with the Compiler This section covers compiler-related topics for Pony users: runtime flags for tuning compiled programs, building ponyc from source with instrumentation for debugging, and cross-compilation to other platforms. ## Runtime Options Compiled Pony programs accept `--pony*` command-line flags for tuning scheduler threads, garbage collection, the cycle detector, and other runtime behavior. These flags are passed to the compiled binary, not to `ponyc`. - [Runtime Options](https://www.ponylang.io/use/compiler/runtime-options/index.md) ## Custom ponyc Builds ponyc can be built from source with instrumentation options for debugging: Valgrind annotations, sanitizers (address, thread, undefined behavior), and systematic testing for the runtime’s own concurrency bugs. - [Custom ponyc Builds for Debugging](https://www.ponylang.io/use/compiler/custom-ponyc-builds/index.md) ## Cross-Compilation ponyc can cross-compile Pony programs to run on a different architecture. The compiler embeds the LLD linker for cross-compiling to Linux targets, so you don’t need an external cross-linker installed. - [Cross-Compilation](https://www.ponylang.io/use/cross-compilation/index.md) # Cross-Compilation Cross-compilation is building a program on one platform that runs on a different one. You compile on your x86-64 Linux workstation, and the resulting binary runs on a RISC-V board or an ARM device. The compiler does all the work on your machine; the target hardware only needs to run the result. ponyc has built-in support for cross-compiling to Linux targets. The compiler embeds the [LLD](https://lld.llvm.org/) linker, which it uses for all Linux linking — both native and cross-compilation. You don’t need an external cross-linker installed. For cross-compilation, you still need a few things from the target platform (its C library and runtime objects), but ponyc handles the linking itself. ## How It Works ponyc uses its embedded LLD linker for all Linux targets, both native and cross-compilation. There’s nothing to enable. Linking happens in-process, with no external linker involved. ## What You Need Cross-compiling a Pony program requires three things: - **A ponyc with embedded LLD.** Any ponyc built from source since the LLD integration or installed via ponyup from a nightly release as of March 8, 2026 has this. - **A cross-compiled Pony runtime.** The Pony runtime library (`libponyrt`) and CRT objects must be compiled for the target architecture. These are not yet included in ponyc distributions, so you currently need to build them from the ponyc source tree. We plan to include pre-built cross-compiled runtimes in future ponyc releases ([ponylang/ponyc#4968](https://github.com/ponylang/ponyc/issues/4968)) to eliminate this step. - **A target sysroot.** This is a directory containing the target platform’s C library (libc), CRT startup objects (`crt1.o`, `crti.o`, `crtn.o`), and system libraries. Installing a cross-compiler package for your target typically provides this. ## Building the Cross-Compiled Runtime Until pre-built runtimes ship with ponyc releases, you need to build the runtime from the ponyc source. This needs the LLVM libraries built, but not a full native ponyc — you compile your program with your host `ponyc` (a ponyup install or a from-source build, as covered in [What You Need](https://www.ponylang.io/use/cross-compilation/#what-you-need) above). ``` git clone https://github.com/ponylang/ponyc.git cd ponyc cmake -DJOBS=8 -P lib/build-libs.cmake ``` Then build the cross-compiled runtime for your target. There’s no preset for cross-builds, so configure a target-specific build directory directly, then build only the `libponyrt` and `crt_objects` targets: ``` cmake -B build//build_release -S . \ -DCMAKE_CROSSCOMPILING=true -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_SYSTEM_PROCESSOR= \ -DCMAKE_C_COMPILER= -DCMAKE_CXX_COMPILER= \ -DPONY_CROSS_LIBPONYRT=true -DCMAKE_BUILD_TYPE=release \ -DCMAKE_C_FLAGS="" -DCMAKE_CXX_FLAGS="" \ -DPONY_ARCH= -DLL_FLAGS="" cmake --build build//build_release --config release --target libponyrt crt_objects ``` The build tree goes in `build//build_release` and the compiled runtime in `build//release` (for example, `build/rv64gc/release/`). To compile a program, run your host `ponyc` with `PONYPATH` pointed at that output directory. See the target-specific guides below for the exact commands for each supported target. For full source build prerequisites, see [Building ponyc from Source](https://www.ponylang.io/contribute/compiler/building-ponyc-from-source/index.md). ## Compiler Flags These flags control cross-compilation. Most are “rarely needed” in normal use, but essential when targeting a different platform. | Flag | Description | | ------------- | ----------------------------------------------------------------------------------------------------- | | `--triple` | Target triple (e.g., `riscv64-unknown-linux-gnu`). Defaults to the host. | | `--cpu` | Target CPU (e.g., `generic-rv64`, `cortex-a9`). Defaults to the host CPU. | | `--features` | CPU features to enable or disable (e.g., `+m,+a,+f,+d,+c`). | | `--abi` | Target ABI (e.g., `lp64d`). Defaults to the host ABI. | | `--link-arch` | Linking architecture (e.g., `rv64gc`, `armv7-a`). | | `--sysroot` | Path to the target system root. Auto-detected from common cross-toolchain locations if not specified. | The `--sysroot` flag tells ponyc where to find the target’s libc CRT objects and system libraries. If you don’t specify it, ponyc searches these locations in order: 1. `/usr//` 1. `/usr/local//` 1. `/usr//libc/` 1. `/usr/local//libc/` If auto-detection fails, ponyc tells you which paths it searched and asks you to specify `--sysroot` explicitly. ## Supported Targets These targets are tested in ponyc’s CI and have step-by-step setup guides: - [RISC-V 64-bit Linux (glibc)](https://www.ponylang.io/use/cross-compilation/riscv64-linux/index.md) - [ARM Linux (glibc, soft-float)](https://www.ponylang.io/use/cross-compilation/arm-linux/index.md) - [ARM Linux (glibc, hard-float)](https://www.ponylang.io/use/cross-compilation/armhf-linux/index.md) Other Linux targets may work with the appropriate triple, sysroot, and runtime build, but these three are the ones we actively test. ## Verifying with QEMU If you don’t have the target hardware handy, [QEMU](https://www.qemu.org/) user-mode emulation lets you run cross-compiled binaries on your host machine. Each target guide includes QEMU verification instructions. QEMU is also how ponyc’s own CI tests cross-compiled binaries. # Debugging ## Debugging Pony Programs [`LLDB`](https://lldb.llvm.org/) is the primary step debugger we use with Pony. However, you can use any similar step debugger like [`gdb`](https://www.sourceware.org/gdb/). We have a couple of resources that can help get up to speed with using LLDB with Pony. We have a quickstart guide: [Pony LLDB Cheat Sheet](https://www.ponylang.io/use/debugging/pony-lldb-cheat-sheet/index.md). Which if you have some experience with debuggers like LLDB, should be enough to get up going. There’s also a collection of [Pony LLDB Extensions](https://github.com/ponylang/pony-lldb-extensions) that can help improve your Pony/LLDB experience. ### Debugging Pony with Visual Studio Code In order to debug programs in the Visual Studio Code debugger (either on Windows or with GDB or LLDB on Unix), you need to set the `debug.allowBreakpointsEverywhere` setting to `true`, so you can set breakpoints in `.pony` files. Then make a launch configuration that runs your program. ## Tracking Memory Usage Interested in tracking Pony runtime memory consumption? Checkout [“Making Pony track memory usage”](https://www.ponylang.io/use/debugging/track-memory-usage/index.md). ## Tracing Pony Programs Interested in tracing the execution of a Pony program? Checkout [“Tracing Pony Programs”](https://www.ponylang.io/use/debugging/tracing/index.md). ## Custom ponyc Builds ponyc can be built from source with instrumentation options for debugging: Valgrind annotations, sanitizers (address, thread, undefined behavior), and systematic testing for the runtime’s own concurrency bugs. See [Custom ponyc Builds for Debugging](https://www.ponylang.io/use/compiler/custom-ponyc-builds/index.md). # Dependency Management [Corral](https://github.com/ponylang/corral) is the dependency manager for Pony. It handles fetching dependencies, managing versions, and setting up the `PONYPATH` so the compiler can find your modules. Corral is currently in beta. ## Installation Install corral via [ponyup](https://github.com/ponylang/ponyup): ``` ponyup update corral release ``` To build from source, see corral’s [BUILD.md](https://github.com/ponylang/corral/blob/main/BUILD.md). ## Getting Started Initialize a project in the current directory: ``` corral init ``` This creates two files: `corral.json` (your project manifest) and `lock.json` (revision locks). Add a dependency: ``` corral add github.com/ponylang/valbytes.git ``` Fetch all dependencies and lock their revisions: ``` corral update ``` Build your project with dependencies on the `PONYPATH`: ``` corral run -- ponyc ``` Arguments after `--` are passed through to the command. For example, to build in debug mode: ``` corral run -- ponyc --debug ``` In your Pony source, import the dependency by package name: ``` use "valbytes" ``` After running `corral update`, two directories appear in your project: - `_corral/` — per-project dependency workspace - `_repos/` — local VCS repo cache Add both to your `.gitignore`. They are managed by corral and do not belong in version control. ## Configuration ### corral.json The project manifest. It describes your project and lists its dependencies: ``` { "info": { "name": "myproject", "description": "A Pony project" }, "deps": [ { "locator": "github.com/ponylang/valbytes.git", "version": ">=0.6.0 <2.0.0" } ] } ``` The `info` section is optional metadata. The `deps` list contains one entry per dependency, each with a `locator` (where to find it) and an optional `version` constraint. ### lock.json Auto-generated by `corral update`. It pins each dependency to an exact revision so that builds are reproducible. Commit `lock.json` to version control. ## More Information See the corral [README](https://github.com/ponylang/corral) for an overview and the [DOCS.md](https://github.com/ponylang/corral/blob/main/DOCS.md) for the full command reference, all dependency types (remote git, local git, local path), and version constraint syntax. # Documentation Generation pony-doc generates API documentation for Pony modules. It is part of the [ponylang/ponyc](https://github.com/ponylang/ponyc) repository, built alongside the compiler, and distributed with it. Installing ponyc from source or via ponyup will include pony-doc. The default backend produces a complete [MkDocs](https://www.mkdocs.org/) site with the [Material](https://squidfunk.github.io/mkdocs-material/) theme, including type pages, method signatures, docstrings, and source code browsing. An Info backend produces a single `.info` file readable by any GNU Info viewer. ## Usage ``` # Generate docs for the current directory pony-doc # Generate docs for a specific module pony-doc path/to/my-module # Write output to a specific directory pony-doc -o docs path/to/my-module # Include private types and methods pony-doc --include-private # Print version pony-doc --version ``` pony-doc compiles the module through the type-checking pass, extracts type information from the AST, and writes the output in the selected format. The default backend is `mkdocs`. ## Output ### MkDocs (default) The MkDocs backend writes a directory named `-docs/` inside the output directory (current directory by default). The generated site includes: - A home page listing all modules - A page per module with its public (and optionally private) types - A page per type with constructors, fields, methods, parameters, and return types - Source code pages with line-numbered Pony source - Cross-reference links between types By default, only public types and methods are included. Use `--include-private` to include private types and methods as well. To view the output locally: ``` pip install mkdocs-material cd -docs mkdocs serve ``` Then open `http://127.0.0.1:8000` in a browser. ### Info The Info backend writes a single `.info` file into the output directory. The output includes cross-reference links between types, the same type and method information as the MkDocs backend, and a tag table for navigation. ## Using with Corral For projects that use [corral](https://github.com/ponylang/corral) for dependency management, run pony-doc through `corral run` so that dependencies are on the module search path: ``` corral run -- pony-doc ``` # Linting pony-lint checks Pony source files for style violations and reports diagnostics with file, line, and column information. It is part of the ponyc repository, built alongside the compiler, and distributed with it. Installing ponyc from source or via ponyup will include pony-lint. ## Usage ``` # Lint the current directory pony-lint # Lint specific paths pony-lint src/ test/ # Disable a rule pony-lint --disable style/hard-tabs # Disable a category pony-lint --disable style # Use a config file pony-lint --config .pony-lint.json # Print version pony-lint --version ``` ## Using with Corral For projects that use [corral](https://github.com/ponylang/corral) for dependency management, run pony-lint through `corral run` so that dependencies are on the module search path: ``` corral run -- pony-lint corral run -- pony-lint src/ test/ ``` ## Rules | Rule ID | Default | Description | | ----------------------------------- | ------- | ------------------------------------------------------------------------------------------ | | `safety/exhaustive-match` | on | Exhaustive `match` should use `\exhaustive\` annotation | | `style/acronym-casing` | on | Acronyms in type names should be fully uppercased | | `style/array-literal-format` | on | Multiline array literal formatting (bracket placement and spacing) | | `style/assignment-indent` | on | Multiline assignment RHS must start on the line after `=` | | `style/blank-lines` | on | Blank line conventions within and between entities | | `style/call-argument-format` | on | Multiline call argument formatting (argument layout and placement) | | `style/comment-spacing` | on | `//` not followed by exactly one space | | `style/control-structure-alignment` | on | Control structure keywords must be vertically aligned | | `style/docstring-format` | on | Docstring `"""` tokens should be on their own lines | | `style/docstring-leading-blank` | on | No blank line after opening `"""` | | `style/dot-spacing` | on | No spaces around `.`; `.>` spaced as infix operator | | `style/file-naming` | on | File name should match principal type | | `style/hard-tabs` | on | Tab characters anywhere in source | | `style/indentation-size` | on | Indentation should be a multiple of 2 spaces | | `style/lambda-spacing` | on | No space after `{` in lambdas; space before `}` only on single-line | | `style/line-length` | on | Lines exceeding 80 codepoints | | `style/match-case-indent` | on | Match case `\|` must align with `match` keyword | | `style/match-no-single-line` | on | Match expressions must span multiple lines | | `style/member-naming` | on | Member names should be snake_case | | `style/method-declaration-format` | on | Multiline method declaration formatting (parameter layout, return type and `=>` alignment) | | `style/operator-spacing` | on | Binary operators need surrounding spaces and belong at line end; no space after unary `-` | | `style/module-docstring` | on | Module should have a `.pony` file with a docstring | | `style/module-naming` | off | Module directory name should be snake_case | | `style/partial-call-spacing` | on | `?` at call site must immediately follow `)` | | `style/partial-spacing` | on | `?` in method declaration needs surrounding spaces | | `style/prefer-chaining` | on | Local variable can be replaced with `.>` chaining | | `style/public-docstring` | on | Public types and methods should have a docstring | | `style/trailing-whitespace` | on | Trailing spaces or tabs | | `style/type-alias-format` | on | Multiline type alias formatting (paren placement and spacing) | | `style/type-naming` | on | Type names should be CamelCase | | `style/type-parameter-format` | on | Multiline type parameter formatting (bracket placement, layout, and `is` alignment) | See the [Rule Reference](https://www.ponylang.io/use/linting/rule-reference/index.md) for detailed explanations and code examples for each rule. ## Configuration Create a `.pony-lint.json` file in your project root (next to `corral.json`) to configure rule status. Each entry maps a rule ID or category name to `"on"` or `"off"`: ``` { "rules": { "style/line-length": "off", "style": "on" } } ``` Rule-specific entries take precedence over category entries. CLI `--disable` flags take precedence over all config files, including subdirectory overrides. Config file discovery order: 1. `.pony-lint.json` in the current working directory 1. Walk up to find `corral.json`, then `.pony-lint.json` in that directory 1. Not found – all rules use their defaults ### Subdirectory Overrides `.pony-lint.json` files in subdirectories override the root config for all files in that subtree. The format is the same as the root config. For example, to turn off `style/module-docstring` for everything under `examples/`, add an `examples/.pony-lint.json`: ``` { "rules": { "style/module-docstring": "off" } } ``` Precedence follows proximity – the nearest directory with a setting wins. Rules omitted from a subdirectory config defer to the parent, not the default. Category entries in a subdirectory config override parent rule-specific entries in that category. A subdirectory config with `"style": "off"` overrides a root config’s `"style/line-length": "on"`. A subdirectory config can combine both: `"style": "off"` with `"style/line-length": "on"` turns off all style rules except `style/line-length`. Malformed subdirectory configs produce a `lint/config-error` diagnostic and fall through to the parent config – the subtree is still linted with the parent’s rules. ## Suppression Comments Inline comments suppress diagnostics for specific lines or regions: ``` // pony-lint: off style/line-length let long = "this line won't be flagged for length" // pony-lint: on style/line-length // pony-lint: allow style/trailing-whitespace let x = 1 ``` Directives: - `// pony-lint: off ` – suppress from this line onward - `// pony-lint: on ` – resume checking - `// pony-lint: allow ` – suppress next line only - Omit the rule/category to suppress all rules A rule-specific `on` overrides a category-level `off`. Unclosed `off` regions produce `lint/unclosed-suppression` diagnostics. Malformed directives (missing space, unknown directive, empty directive, duplicate `off`) produce `lint/malformed-suppression` diagnostics. ## Exit Codes | Code | Meaning | | ---- | ---------------------------------------------------------------------------- | | 0 | No violations found | | 1 | One or more violations found | | 2 | Operational error (unreadable file, malformed config, malformed suppression) | # LLM Skills [ponylang/llm-skills](https://github.com/ponylang/llm-skills) is a collection of skills for working with Pony in LLM coding harnesses. Each skill is a self-contained reference that your LLM loads on demand during coding sessions. Some skills provide Pony-specific knowledge (language reference, testing patterns). Others provide language-agnostic methodology (code review, debugging protocols, software design). All skills use a `pony-` prefix as an org namespace to avoid collisions with skills from other sources — the prefix is about where they come from, not what languages they apply to. The skills require a harness that supports sub-agents. They’re tested with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and compatible with [OpenAI Codex](https://developers.openai.com/codex), which loads the same `SKILL.md` format. If your harness supports sub-agents and can load skill files, the skills themselves are harness-agnostic. If you’re just getting started, load `pony-skills`. It’s a routing index — it points you to the right skill for the task at hand, so it’s the single trigger that covers all the others. For Pony coding sessions, `pony-ref` is the one to load every time. The rest are available when you need them. ## Installation Clone the repo and run the install script. It detects which harnesses you have installed and symlinks each skill into their skills directory, so the skills stay up to date when you pull. ``` git clone https://github.com/ponylang/llm-skills.git cd llm-skills python install.py ``` With no arguments, `install.py` installs for every harness it detects: Claude Code (into `~/.claude/skills/`) and Codex (into `~/.agents/skills/`). To target a specific harness regardless of what’s detected, pass `--claude` and/or `--codex`. Start a new session and the skills are available. To update: ``` cd llm-skills git pull ``` No re-install needed. The symlinks point to your clone, so pulling new content updates the skills automatically. To uninstall: ``` python install.py --uninstall ``` This removes the symlinks from your detected harnesses, or just the one you name with `--claude`/`--codex`. Your clone stays put. ## Skills ### Routing #### pony-skills A routing index for the other skills. Load it — or reference it from a project’s `CLAUDE.md` or `AGENTS.md` — and it tells you which `pony-` skill to load for each task. It’s the single-trigger alternative to wiring up every skill’s trigger by hand, and a good place to start. ### Pony Language #### pony-ref The Pony language reference. Covers the capabilities table, subtyping rules, viewpoint adaptation, common gotchas, property-based testing patterns, and standard library pitfalls. Behind the quick reference, deeper documents are available for the LLM to read on demand: the full text of the nine Pony papers as PDFs, type-system and runtime/GC synopses distilled from them, and snapshots of the tutorial, patterns cookbook, and main website. The reference documentation updates nightly from the Pony website and tutorial. Pull the repo often. ### Project Conventions #### pony-examples-readme Conventions for writing `examples/README.md` files in ponylang projects. Structure, description format, ordering, what to omit. #### pony-library-readme Conventions for writing Pony library project READMEs. Required sections, optional sections, what ponylang library READMEs deliberately omit. #### pony-release-notes How to write release notes and manage CHANGELOG entries in ponylang projects. Writing style, mechanics, changelog labels, and workflows. Assumes the target repo uses [changelog-bot-action](https://github.com/ponylang/changelog-bot-action) and [release-notes-bot-action](https://github.com/ponylang/release-notes-bot-action). ### Development Workflow #### pony-software-design Disciplines for software design work — APIs, type systems, features, system boundaries. Counters the tendency to retrieve familiar patterns instead of discovering what the problem needs. Has full (8-persona) and lightweight (5-persona) modes. #### pony-code-review Ensemble code review with specialized reviewer personas. Personas cover correctness, security, performance, API design, test quality, adversarial scenarios, design principles, and wildcard concerns. Has full (8-persona, iterative re-review) and lightweight (3-persona, single pass) modes. #### pony-docs-review Ensemble documentation review — the prose counterpart to `pony-code-review`, for documentation-only changes like tutorials, READMEs, and reference pages. Personas cover accuracy, completeness, clarity, structure, consistency, reader experience, design principles, and wildcard concerns. Has full (8-persona, iterative re-review) and lightweight (3-persona, single pass) modes. #### pony-test-design Two-stage ensemble for planning meaningful tests. Counters the tendency to write tests that exercise the stdlib instead of your code. Has full (8-persona) and lightweight (5-persona) modes. #### pony-pbt-patterns Property-based and generative testing patterns, built on one idea: chance is not coverage, so a generator has to bias toward where bugs live. Covers biasing toward important values, swarm testing (varying which operations are enabled so emergent state reaches the extremes), the valid/invalid/mixed boundary triad, compositional generators, and multi-angle oracles. Maps directly onto PonyTest’s property-based testing support. #### pony-debug Structured debugging protocol with checkpoints. Provides an OODA-loop investigation process: characterize the failure, gather context, build a minimal reproduction, then iterate through hypothesis/experiment/observe cycles. Load it before forming any hypothesis about the cause. ### Infrastructure These skills are internal plumbing used by the ensemble skills above. You don’t invoke them directly. #### pony-ensemble The mechanical process for producing higher-confidence outputs through decorrelated reasoning paths. Multiple agents work the same problem with different attention focuses, then a synthesizer integrates their outputs. This is infrastructure — `pony-software-design`, `pony-code-review`, and `pony-test-design` build on it. #### pony-synthesize Fixed instructions for the ensemble synthesizer — integrates multiple agent outputs into a single result. Infrastructure loaded by `pony-ensemble` during the synthesis step. ## Using Skills ### Manual invocation Load a skill on demand when you need it for the current task but don’t want it loaded every session. In Claude Code, type the skill name as a slash command: ``` /pony-ref ``` In Codex, skills load automatically based on their description, or you can name one explicitly with `$pony-ref`. Either way, the LLM loads the skill’s reference material into context. ### CLAUDE.md and AGENTS.md triggers Claude Code reads `CLAUDE.md` files at the start of every session — one global (`~/.claude/CLAUDE.md`) and one per project; Codex reads `AGENTS.md` the same way. You can add instructions to these files that tell the LLM when to load skills automatically. Each trigger is a sentence or two describing the condition and the action. The simplest setup is a single trigger that loads `pony-skills`, the routing index, which then points to whatever the task needs: ``` **Load `pony-skills` at the start of Pony work**: At the start of work in a Pony project, load the `pony-skills` skill — a routing index that tells you which `pony-` skill to load for each task. ``` Prefer to wire up skills individually? For example, to load the language reference at the start of every Pony coding session: ``` **Load `pony-ref` proactively when working on Pony code**: At the start of any conversation where the working directory is a Pony project (contains `corral.json` or `*.pony` files), load `pony-ref` before doing any work. Also load it mid-conversation when hitting capabilities, type system, runtime, or testing questions. ``` To load the debugging protocol when needed: ``` **Load `pony-debug` when you start debugging**: Before forming any hypothesis about the cause of a non-trivial issue, load `pony-debug`. ``` To load code review for PRs: ``` **Load `pony-code-review` for code reviews**: When conducting a code review of a PR, branch, or local changes, load `pony-code-review`. ``` The trigger text is natural language. Write it so the LLM can match the condition to the current situation. The [ponylang/llm-skills README](https://github.com/ponylang/llm-skills#suggested-triggers) has suggested triggers for every skill. # Packages The Pony Developers maintain a number of packages that exist outside of the standard library that you can utilize. Each of the packages is tested nightly to make sure it works with the latest Pony compiler builds. While the packages are maintained by us, we welcome contributions from the community at large. If you’d like to discuss contributing to any of the packages, please stop by the [#contribute to Pony](https://ponylang.zulipchat.com/#narrow/stream/192795-contribute-to-Pony) channel. ## Networking ### [hobby](https://github.com/ponylang/hobby) Hobby is a simple HTTP web framework for Pony, powered by [Stallion](https://github.com/ponylang/stallion). It provides radix-tree routing with named and wildcard parameters, two-phase middleware (before/after), route groups with shared prefixes and middleware, and streaming responses via chunked transfer encoding. Routes are registered through method chaining and frozen into an immutable router when the server starts, giving you a mutable-friendly setup phase followed by a fully `val` runtime with no locking or coordination overhead. Hobby is designed to feel lightweight while taking full advantage of Pony’s type system and reference capabilities. Handlers are `val` - safe to share across concurrent connections without copying. The `Context` is `ref`, so middleware and handlers can read and mutate request state without juggling `iso` ownership. If you’re building an HTTP service in Pony and want a familiar route/middleware/handler model without fighting the capability system, Hobby is a good place to start. ### [livery](https://github.com/ponylang/livery) Livery is a server-side library for building interactive LiveView UIs over WebSocket in Pony. You implement the `LiveView` trait — `mount` initializes state, `handle_event` responds to client interactions, `handle_info` receives server-push messages, and `render` produces HTML from current assigns. The JavaScript client connects over WebSocket, patches the DOM with [morphdom](https://github.com/patrick-steele-iber/morphdom) on each render, and delegates UI events back to the server. No client-side application code is needed beyond including the script. Livery supports stateful `LiveComponent` instances for composing UIs from independent pieces, each with its own assigns, lifecycle, and event handling. `PubSub` enables topic-based server push across connections. Split rendering sends static template parts once and only changed dynamic values on subsequent renders, minimizing wire traffic for large templates. `PageRenderer` renders a view to HTML without a WebSocket connection for server-rendered first paint, eliminating the empty-page flash on initial load. The library is built on [mare](https://github.com/ponylang/mare) for WebSocket transport and [templates](https://github.com/ponylang/templates) for HTML rendering with contextual auto-escaping. ### [mare](https://github.com/ponylang/mare) Mare is a WebSocket server library for Pony. It implements RFC 6455 and provides a callback-driven API for handling WebSocket connections. You write an actor that implements `WebSocketServerActor` and responds to connection events — `on_open`, `on_text_message`, `on_binary_message`, and `on_closed` — and mare handles the protocol framing, upgrade handshake, and connection lifecycle. Configuration is explicit: bind address, port, and SSL are set through `WebSocketConfig`. ### [stallion](https://github.com/ponylang/stallion) Stallion is an HTTP/1.x server library for Pony. Rather than hiding connections behind an opaque server object, Stallion asks you to write the connection actor yourself - your actor owns an `HTTPServer` instance and receives HTTP lifecycle callbacks directly. There are no hidden internal actors, no implicit concurrency, and no magic. You get a typed request with a pre-parsed URI, a `Responder` for sending replies, and a `ResponseBuilder` state machine for constructing well-formed responses. Pipelined requests are queued and responses are sent in order, even when your actor handles them out of sequence. Stallion supports both complete and streaming responses. Complete responses are pre-serialized via `ResponseBuilder` for efficient repeated use. Streaming responses use chunked transfer encoding with flow control - each chunk gets an asynchronous acknowledgement callback so producers can match their send rate to the network. Configuration is explicit: parser limits, idle timeouts, pipelining depth, and TLS are all opt-in via `ServerConfig`. If you want a minimal, transparent HTTP layer that fits naturally into Pony’s actor model without imposing its own abstractions, Stallion is the foundation to build on. ### [web_link](https://github.com/ponylang/web_link) Parser for [RFC 8288](https://www.rfc-editor.org/rfc/rfc8288) (Web Linking) HTTP Link headers in Pony. Implements the link-value grammar from Section 3 including quoted-string parameters, OWS/BWS handling, and multi-link comma-separated headers. ## Databases ### [postgres](https://github.com/ponylang/postgres) Pure Pony Postgres client. Postgres is a pure Pony PostgreSQL driver with no libpq dependency — it implements the wire protocol directly. It supports simple queries, parameterized queries (both unnamed and named prepared statements), COPY IN/OUT for bulk data transfer, row streaming with bounded memory via portal suspension, SSL/TLS, and SCRAM-SHA-256 authentication. The API is fully async and callback-driven: you implement receiver interfaces (`ResultReceiver`, `CopyInReceiver`, `StreamingResultReceiver`, etc.) and the `Session` actor calls back with results or errors. Query execution is serialized within a session — for concurrency, create multiple sessions. ### [redis](https://github.com/ponylang/redis) Pure Pony Redis client. The client supports strings, keys, hashes, lists, sets, and pub/sub, with builder primitives for type-safe command construction. Any Redis command not covered by a builder can be sent as a raw byte array. Commands are pipelined by default — each `execute()` sends immediately without waiting for prior responses. The client supports both RESP2 and RESP3 protocols, SSL/TLS, and Redis 6.0+ ACL authentication. Backpressure is bounded: a configurable send buffer rejects commands when full rather than growing without limit. Note that this package has not yet had a formal release. ## Data Formats and Parsing ### [msgpack](https://github.com/ponylang/msgpack) A pure Pony implementation of the [MessagePack](https://msgpack.org/) serialization format. `MessagePackEncoder` provides compact methods that automatically select the smallest wire format for a given value — a small integer encodes as a single-byte `positive_fixint`, a short string as a `fixstr`, and so on. `MessagePackDecoder` provides matching compact methods that accept any wire format within a family. When you need explicit control, format-specific methods on the encoder (`uint_8`, `uint_32`, `fixstr`, `str_8`, `bin_8`, `fixext_1`, `ext_8`, etc.) and corresponding methods on the decoder target exactly one wire format. Both styles work through the standard library’s `Writer` and `Reader` buffers. `MessagePackStreamingDecoder` handles data that arrives incrementally. It peeks at format bytes and length fields before consuming anything; if insufficient data is available, it returns `NotEnoughData` with zero bytes consumed so the caller can append more and retry. The decoder produces typed values — including integers, floats, strings, booleans, binary data, timestamps, extension types, array headers, and map headers — via a single `next()` call. Configurable size limits via `MessagePackDecodeLimits` protect against oversized payloads from untrusted sources; the batch `MessagePackDecoder` does not enforce limits. ### [multipart_mime](https://github.com/ponylang/multipart_mime) A streaming multipart MIME parser for Pony, implementing RFC 2046. The parser delivers data through a callback interface (`MultipartNotify`) as it encounters boundaries, headers, and body chunks — there is no buffering of entire parts unless you opt into it. For simple cases, `CollectParts` buffers all parts in memory and delivers them as an array. For large uploads or streaming use cases, implement `MultipartNotify` directly to handle body data incrementally. `FormData` provides helpers for extracting `Content-Disposition` field names and filenames from part headers. The parser enforces configurable size limits on part headers, part bodies, preamble length, and total part count. Transport padding after boundaries is capped at 256 bytes. Header parsing follows RFC 7230 rather than the RFC 822 rules referenced by RFC 2046 — obsolete header folding and whitespace before the colon are rejected. ### [peg](https://github.com/ponylang/peg) A parsing expression grammar package for Pony. The library offers two ways to define parsers. You can build grammars programmatically using Pony operator overloading — `*` for sequence, `/` for ordered choice, `-` for skip, `.many()` for repetition — which makes grammar definitions read close to standard PEG notation. Alternatively, you can write grammars in `.peg` text files and compile them at runtime. Both approaches produce the same `Parser val` type, which parses input into a labeled AST of nodes and tokens. The library supports hidden channels for automatic whitespace skipping, separated lists, forward declarations for recursive rules, and positional error reporting with source context. ### [regex](https://github.com/ponylang/regex) Perl compatible regular expression support for Pony. The library wraps PCRE2 (the 8-bit variant) via FFI, with JIT compilation enabled by default and a graceful fallback to interpreted matching. UTF-8 mode is always on. The `Regex` class compiles a pattern once and provides `apply` for matching, `replace` for substitution (single or global), `split` for splitting, and `matches` for iterating over all non-overlapping matches. Both numbered and named capture groups are supported. PCRE2 compile-time options like case-insensitive or multiline mode are set via inline flags in the pattern (e.g., `(?i)`, `(?m)`). The library requires `libpcre2-8` to be installed on the system. ### [semver](https://github.com/ponylang/semver) A semantic versioning package for Pony. The library is organized into three sub-modules. `semver/version` handles parsing, validation, comparison, and stringification of semver 2.0.0 version strings, including pre-release fields and build metadata. `semver/range` provides interval-based version ranges with inclusive/exclusive bounds. `semver/solver` is a constraint-based dependency resolver that takes a set of available artifacts with their version-constrained dependencies and finds a compatible combination using a backtracking search. Parsing never throws — `ParseVersion` always returns a `Version` object, and `is_valid()` plus the `errors` field indicate whether parsing succeeded. ### [templates](https://github.com/ponylang/templates) A template engine for Pony with optional HTML-aware contextual auto-escaping. Templates uses `{{ ... }}` delimiters and supports variable substitution, dot-notation property access, `for` loops over sequences, conditionals (`if`, `ifnot`, `else`, `elseif`), filter pipes (`{{ name | upper | trim }}`), includes, template inheritance, comments, raw blocks, and whitespace trimming. Built-in filters cover common operations — `upper`, `lower`, `trim`, `capitalize`, `title`, `default("fallback")`, and `replace("old", "new")` — and custom filters can be registered via `TemplateContext`. Templates are compiled into an immutable `val` representation that can be shared across actors and rendered repeatedly with different values. `HtmlTemplate` adds automatic context-aware escaping — text content gets entity escaping, URL attributes get scheme filtering and percent-encoding, and script contexts get JS string escaping. Trusted content can bypass escaping via `TemplateValue.unescaped`. Template inheritance lets child templates extend a base with `{{ extends "base" }}` and override named `{{ block }}` sections, with multi-level chains supported. Partials are registered and resolved through `TemplateContext`, which also handles circular dependency detection at parse time. ### [valbytes](https://github.com/ponylang/valbytes) Package to deal with multiple concatenated byte-arrays as if they were a single byte-array. `ByteArrays` lets you concatenate byte arrays without copying data. Each `+` operation wraps the existing data and the new chunk in a tree node, making concatenation O(1). You can then index into the combined structure, search for subsequences, slice with `select`/`drop`/`take` (also zero-copy), or read little-endian multi-byte integers — all as if the bytes were contiguous. When you do need a flat array, `trim` and `array` materialize the data. `ByteArrays` is `val` (immutable), so it is safe to share across actors. The typical use case is accumulating data from I/O in chunks and processing it later without intermediate copies. ## External Services ### [github_rest_api](https://github.com/ponylang/github_rest_api) Pony package for working with GitHub’s REST API. The library covers a subset of the GitHub REST API — repositories, issues, issue comments, labels, pull requests, commits, releases, and issue search. Operations are async and return promises. Two API styles are available: call operation primitives directly, or chain methods on model objects starting from a `GitHub` entry point. Authentication is via an optional personal access token. Paginated endpoints return objects with `prev_page()` and `next_page()` methods. The library does not aim for full API coverage — it implements what the Pony project’s own tooling needs and grows on demand. ## Concurrency and Distribution ### [crdt](https://github.com/ponylang/crdt) Conflict-free replicated data types (CRDTs) for Pony, based on delta-state replication. The library provides twelve CRDT types covering counters (grow-only, positive-negative, and causal), sets (grow-only, two-phase, timestamp-based, add-wins and remove-wins observed-remove), registers (last-write-wins and multi-value), a timestamped log, and a composable keyed collection. All types use delta-state replication — mutator methods return a delta containing only the new information, which you send to other replicas instead of the full state. Convergence is commutative and idempotent, so deltas can arrive in any order and be applied more than once without harm. The library handles the data structures and serialization; you provide the transport and logical timestamps. ### [fork_join](https://github.com/ponylang/fork_join) Pony parallel processing package. Fork_join handles the plumbing of distributing data processing across multiple actors. You supply four components: a `Generator` that produces work items on demand, a `Worker` that processes them, a `WorkerBuilder` that creates worker instances, and a `Collector` that aggregates results. The library creates one worker actor per scheduler thread (configurable), pulls items from the generator as workers become available, and delivers results to the collector. Work items must be independent — there is no inter-worker communication or ordering guarantee. The generator can pre-partition data in bulk or produce items one at a time for natural load balancing. Early termination is supported from both the job owner and the collector side. ### [reactive_streams](https://github.com/ponylang/reactive_streams) Pony implementation of . The package maps the Reactive Streams specification to Pony’s actor model. Publishers and subscribers are actor interfaces; the `Subscription` connecting them is passed as `iso` to enforce single-owner semantics at the type level. No data flows until the subscriber signals demand via `request(n)`, giving full subscriber-driven backpressure. The library includes `Broadcast` and `Unicast` subscriber managers that handle demand tracking and bounded queuing, so building a publisher is a matter of implementing `ManagedPublisher` and calling `publish()` when data is available. ## Utilities ### [appdirs](https://github.com/ponylang/appdirs) Package for getting platform-specific application directories e.g. directory for user-based config. Appdirs gives you the correct OS-specific directory paths for user data, config, cache, logs, and state. On Linux it follows the XDG Base Directory Specification, on macOS it uses `~/Library/...` paths (with an opt-in XDG mode for CLI tools that want consistent cross-platform behavior), and on Windows it calls the Known Folders API. All methods are partial — they can fail if the home directory is not set or the OS API call fails. The library computes paths but does not create directories. ### [glob](https://github.com/ponylang/glob) Pony package that provides the ability to find all pathnames matching a given pattern based on Unix shell rules. Glob supports `*` (match within a directory), `**` (match across directories), `?` (single character), and `[seq]`/`[!seq]` (character classes). You can match patterns against strings with `fnmatch`, filter a list of names with `filter`, or walk the filesystem with `glob` and `iglob`. Unlike many glob implementations, this one exposes what each wildcard matched via capturing groups — the `filter` and `iglob` APIs return the matched substrings alongside each result. The library depends on [regex](https://github.com/ponylang/regex) and requires PCRE2 on the system. ### [logger](https://github.com/ponylang/logger) A simple logging package for Pony. Logger provides four log levels (`Fine`, `Info`, `Warn`, `Error`) and a generic `Logger[A]` class that accepts any type with a conversion lambda. For string logging, use `StringLogger`. The idiomatic usage pattern is `logger(Warn) and logger.log("message")` — Pony’s short-circuit evaluation of `and` means the log message is never constructed when the level is suppressed. `Logger` is `val`, so a single instance can be shared across actors. Output goes to any `OutStream`; formatting is customizable via the `LogFormatter` interface, and the default formatter includes source file, line, and column from the call site. # Performance We advertise Pony as a high-performance language. And Pony can definitely be fast. We have personal experience with making Pony applications fast. We also have experience with people writing Pony code that is rather slow. Writing fast code isn’t easy. Some languages make it easier than others. Some languages make it harder than others. But, you can write slow code in any language. Trust us, we know. We’ve done it. All this it to let you know, you can write very fast code with Pony, but it will require some effort. There is no language that you can use that will make your code fast without effort. We’ve collected together some resources to help you write fast Pony code. In addition to these resources, we have a [#performance help](https://ponylang.zulipchat.com/#narrow/stream/190362-performance-help) channel on Zulip. If you have questions about performance, drop by and ping us. ## Microbenchmarking The Pony standard library contains a microbenchmarking package called `pony_bench`. Microbenchmarking is the process of measuring the performance of small pieces of code. It’s a useful tool for understanding the performance characteristics of small sections code. It won’t help you make your entire application fast, but it can help you make small sections of your code fast. We recommend only spending time using Pony Bench on code that will be used in a “hot path”. That is, code that will executed many times. And by “many times”, we mean “millions” or “billions”. - [Pony Bench](https://stdlib.ponylang.io/pony_bench--index/) ## Profiling The performance cheat sheet covers what to fix; a profiler shows you where to look. Pony compiles to native code, so standard tools like `perf` and Instruments work on Pony binaries. Our profiling guide covers the compiler flags you need, what Pony-specific symbols mean in a profile, and how to use each tool. - [Profiling Pony Programs](https://www.ponylang.io/use/performance/profiling/index.md) ## Performance Cheat Sheet We’ve collected together a ton of information about making Pony programs fast. It covers a ton of topics. Some are related to how to design programs for speed. Some are related to how to maximize the performance of code you write. Some are related to optimizing the environment your Pony program runs in. - [Pony Performance Cheat Sheet](https://www.ponylang.io/use/performance/pony-performance-cheat-sheet/index.md) ## Runtime Options Compiled Pony programs accept `--pony*` runtime flags for tuning scheduler threads, garbage collection, the cycle detector, and other runtime behavior. These flags are passed to the compiled binary at runtime, not to `ponyc`. - [Runtime Options](https://www.ponylang.io/use/compiler/runtime-options/index.md) ## Performance Testing Performance testing is very hard to get right. Most people do it poorly. That’s just a fact. The environment you use to test is very important, we suggest you take a look at the documentation we’ve put together for [testing Pony runtime changes](https://www.ponylang.io/contribute/developer-resources/performance-testing-setup/index.md). It might give you some inspiration for doing better testing of your own programs. # Pony Agent Server `pony-agent-server` is a query server that gives AI coding agents access to Pony type information from the compiler. It compiles a Pony package, then returns query results about types, definitions, scopes, and APIs over a JSON protocol. It is part of the [ponylang/ponyc](https://github.com/ponylang/ponyc) repository, built alongside the compiler. `pony-agent-server` is experimental. The query interface is subject to change. ## How It Works On startup, `pony-agent-server` compiles the package you point it at. Once compilation finishes, it accepts queries over stdin and writes responses to stdout — one JSON object per line in each direction. This is a standard stdio transport that AI agent tool integrations use. When source files change, you can send the server a reload query without restarting it. ## Starting It ``` pony-agent-server [-D define]... ``` The server accepts the same `-D` flags as `ponyc`. Run `pony-agent-server --queries` to see a summary of available queries. ## Using with Corral For projects that use [corral](https://github.com/ponylang/corral) for dependency management, run `pony-agent-server` through `corral run` so that dependencies are on the package search path: ``` corral run -- pony-agent-server . ``` ## What It Can Answer `pony-agent-server` exposes type and definition information at source positions, scope visibility at a given location, and the full list of exports from a package. It can list the methods on a type filtered by what a particular reference capability can call, check whether one type is a subtype of another (using the compiler’s actual subtype checker, not a reimplementation), and find every type that implements a given trait or interface. It also reports compilation errors from the most recent load. ## Using It with AI Agents There are three ways to connect an AI agent to `pony-agent-server`: - ponylang’s [llm-skills](https://github.com/ponylang/llm-skills) will include guidance for agents that support skill loading. - Add instructions to your project’s `AGENTS.md` or `CLAUDE.md` telling your agent to use it. - Prompt your agent directly during a session. ## Getting pony-agent-server `pony-agent-server` is distributed via [ponyup](https://github.com/ponylang/ponyup) alongside `ponyc`. Installing a recent `ponyc` will also install `pony-agent-server`. See the [ponyc installation instructions](https://github.com/ponylang/ponyc/blob/main/INSTALL.md) for details. # Pony Language Server pony-lsp is the Pony Language Server. It communicates with editors via stdout/stdin using the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/). It is part of the [ponylang/ponyc](https://github.com/ponylang/ponyc) repository, built alongside the compiler. Your editor launches the `pony-lsp` binary as a subprocess. See the [editor configuration](https://www.ponylang.io/use/pony-lsp/#editor-configuration) section for setup instructions. ## Getting pony-lsp `pony-lsp` is distributed via [ponyup](https://github.com/ponylang/ponyup) alongside `ponyc`. Installing a recent `ponyc` will also install `pony-lsp`. See the [ponyc installation instructions](https://github.com/ponylang/ponyc/blob/main/INSTALL.md) for details. ## Feature Support | Feature | Description | Supported since version | | ------------------ | ------------------------------------------------------------------------------------------------- | ----------------------- | | Diagnostics | Compiler errors and warnings published on file open and save | >= 0.60.5 | | Hover | Type information and documentation on hover | >= 0.60.5 | | Go To Definition | Jump to the definition of a symbol | >= 0.60.5 | | Document Symbols | List of symbols in the current file | >= 0.60.5 | | Document Highlight | All occurrences of the symbol under the cursor are highlighted simultaneously across the document | > 0.63.0 | | Find References | Show all references to the thing under the cursor | > 0.63.0 | | Inlay Hints | Display helpful hints in between the code. Mostly resolved types for expressions and variables. | > 0.63.0 | ## Workspace Detection pony-lsp needs to know the root of your project so it can resolve modules correctly. It determines this by scanning parent directories for a workspace root marker. The following are recognised as markers: - `corral.json` (Pony’s dependency manager) - `bundle.json` - `.git`, `.hg`, `.bzr`, or `.svn` directories Most Pony projects will have at least one of these already. If yours doesn’t, create an empty `corral.json` in the project root or initialise a Git repository there. ## Settings pony-lsp supports settings via [`workspace/configuration`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration) request and [`workspace/didChangeConfiguration`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeConfiguration) notification. | Setting | Type | Example | Description | | ---------- | --------------- | -------------------------- | ------------------------------------------------------------------------- | | `defines` | `Array[String]` | `["FOO", "BAR"]` | Defines active during compilation, equivalent to the `-D` flag in `ponyc` | | `ponypath` | `Array[String]` | `["/path/to/pony/module"]` | Additional module search paths for pony-lsp | The standard library is discovered automatically from the pony-lsp installation path. You only need `ponypath` if your project depends on modules outside the standard search locations. Example settings: ``` { "defines": ["FOO", "BAR"], "ponypath": ["/path/to/pony/module", "/another/path"] } ``` How to pass these settings depends on your editor. See the editor configuration sections below. ## Editor Configuration ### Helix Getting Helix set up with pony-lsp is very easy. Add the following to your [`languages.toml`](https://docs.helix-editor.com/languages.html). ``` [[language]] name = "ponylang" language-servers = [ "pony-lsp" ] indent = { tab-width = 2, unit = " " } [language-server.pony-lsp] command = "pony-lsp" args = [] ``` #### Project-Specific Defines Defines are almost always project-specific. Rather than adding them to your global `languages.toml`, create a `.helix/languages.toml` in the project root: ``` [language-server.pony-lsp.config] defines = [ "MY_DEFINE_ONE", "MY_DEFINE_TWO", ] ``` Replace the example values with the actual defines your project needs. ### Neovim If you have [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/tree/master) installed, add this to your `init.lua`: ``` vim.lsp.enable('pony_lsp') ``` and for project specific defines you can add the following to your `init.lua`: ``` vim.lsp.config["pony_lsp"].settings = { defines = {"FOO", "BAR"}, ponypath = {"/path/to/pony/package1", "/path/to/pony/package2"} } ``` or if you dont want to install the `nvim-lspconfig` package you could copy this [file](https://github.com/neovim/nvim-lspconfig/blob/master/lsp/pony_lsp.lua) and place it in your nvim config directory `lsp/pony_lsp.lua` and then add this your `init.lua`: ``` vim.lsp.enable('pony_lsp') ``` ### Visual Studio Code To get `pony-lsp` working with Visual Studio Code, first install the [Pony VS Code extension](https://marketplace.visualstudio.com/items?itemName=ponylang.ponylang-vscode-extension). Ensure `pony-lsp` is on your `PATH` — the extension will show an error if it isn’t found. Open your VS Code settings to configure the extension (all options are optional): ``` { "pony.lsp.executable": "/usr/local/bin/pony-lsp", "pony.trace.server": "off", "pony-lsp.defines": ["FOO", "BAR"], "pony-lsp.ponypath": ["/path/to/pony/package1", "/path/to/pony/package2"] } ``` `pony.lsp.executable` sets the path to `pony-lsp` if it isn’t on your `PATH`. `pony.trace.server` traces communication between VS Code and the language server (`"off"`, `"messages"`, or `"verbose"`). `pony-lsp.defines` and `pony-lsp.ponypath` are passed directly to `pony-lsp`. For more details, see the [Pony VS Code extension project documentation](https://github.com/ponylang/vscode-extension). ### Zed To get `pony-lsp` working with the [Zed](https://zed.dev/) editor, first install the Pony Zed extension: 1. Open Zed 1. Press cmd-shift-x (macOS) or ctrl-shift-x (Linux/Windows) 1. Search for “Pony” 1. Click Install Next, open your Zed settings to configure `pony-lsp` (all options are optional): ``` { "lsp": { "pony-lsp": { "settings": { "executable": "/pony/bin/pony-lsp", "ponypath": [ "/path/to/project-a/modules", "/path/to/project-b/modules" ], "defines": [ "MY_DEFINE_ONE", "MY_DEFINE_TWO" ] } } } } ``` For more details, see the [Pony Zed extension project documentation](https://github.com/orien/pony-zed). # Testing Pony’s standard library includes PonyTest, which provides both unit testing and property-based testing. ## Unit Testing [PonyTest](https://stdlib.ponylang.io/pony_test--index/) is Pony’s testing framework. Each unit test is a class that implements `UnitTest`. You provide a `name()` and an `apply(h: TestHelper)` function that contains your assertions. ``` use "pony_test" class iso _TestAdd is UnitTest fun name(): String => "addition" fun apply(h: TestHelper) => h.assert_eq[U32](4, 2 + 2) ``` `TestHelper` provides assertion functions like `assert_eq`, `assert_true`, `assert_error`, and others. By default, log messages only appear for failing tests. Tests can optionally define `set_up(h: TestHelper)?` and `tear_down(h: TestHelper)` for environment setup and cleanup. `set_up` runs before the test; `tear_down` runs after, regardless of pass or fail. See the [PonyTest stdlib docs](https://stdlib.ponylang.io/pony_test--index/) for the full API. ## Property-Based Testing Instead of specifying individual examples, you define a property that should hold for all inputs and let the framework generate random test data. This is effective at finding edge cases you wouldn’t write by hand. A property test implements `Property`. You provide a `name()`, a `gen()` that returns a `Generator` for your input type, and a `property()` function that asserts the property. ``` use "collections" use "pony_test" class iso _ListReverseProperty is Property[List[USize]] fun name(): String => "list/reverse" fun gen(): Generator[List[USize]] => Generators.list_of[USize](Generators.usize()) fun ref property(arg1: List[USize], ph: PropertyHelper) => ph.assert_array_eq[USize](arg1, arg1.reverse().reverse()) ``` When a property fails, PonyTest shrinks the failing input to find the smallest counterexample, making failures easier to diagnose. You can also run properties inline within a `UnitTest` using `h.for_all`: ``` use "collections" use "pony_test" class iso _TestListReverse is UnitTest fun name(): String => "list/reverse/inline" fun apply(h: TestHelper) ? => let gen = recover val Generators.list_of[USize](Generators.usize()) end h.for_all[List[USize]](gen)( {(sample, ph) => ph.assert_array_eq[USize](sample, sample.reverse().reverse()) })? ``` See the [PonyTest stdlib docs](https://stdlib.ponylang.io/pony_test--index/) for the full set of generators and configuration options. ## Testing Async Code Pony tests run concurrently by default, but a simple test completes when `apply` returns. For tests that involve actors, you need the test to stay alive until async work finishes. Call `h.long_test(timeout)` to indicate the test should not complete when `apply` returns. The timeout (in nanoseconds) acts as a safety net for hung tests. When your async work finishes, call `h.complete(success)` to signal completion. For tests with multiple independent async operations, use actions. Call `h.expect_action("name")` for each operation you’re waiting on, then `h.complete_action("name")` as each one finishes. The test completes automatically when all expected actions are done. Tests that create TCP listeners, connections, timers, or other I/O resources must clean them up. Call `h.dispose_when_done(actor)` to register actors for disposal when the test finishes. Without this, the test program will hang after all tests pass because the runtime won’t exit while actors hold live I/O resources. ## Test Project Structure Pony projects use a single top-level `_test.pony` whose `Main` actor orchestrates all tests. Each submodule has its own `_test.pony` with a `Main is TestList` actor that provides two constructors: - `create(env: Env)` — for running the submodule’s tests directly - `make()` — for aggregation into the top-level runner The top-level `_test.pony` imports submodules via aliased `use` statements and delegates to their test lists: ``` use "pony_test" use foo = "foo" use bar = "bar" actor Main is TestList new create(env: Env) => PonyTest(env, this) new make() => None fun tag tests(test: PonyTest) => foo.Main.make().tests(test) bar.Main.make().tests(test) ``` Only the top-level module gets compiled and run. The `ponyc/packages/stdlib/` directory in the Pony compiler source is a good example of this pattern in practice. ## Coverage Reports Pony supports generating test coverage reports through LLVM’s source-based code coverage tooling. See [Coverage Reports](https://www.ponylang.io/use/testing/coverage-reports/index.md) for setup instructions. # Custom ponyc Builds for Debugging ponyc supports several build-time options that instrument the compiler and runtime for debugging. These require building ponyc from source with specific options. All commands here are for the Unix build. ## Build Workflow Every option follows the same pattern: 1. Clone ponyc and build its dependencies (one-time): ``` git clone https://github.com/ponylang/ponyc.git cd ponyc cmake -P lib/build-libs.cmake ``` 1. Configure with the desired option: ``` cmake --preset release -DPONY_USES=