{"id":15178476,"url":"https://github.com/aecsocket/aeronet","last_synced_at":"2026-02-18T17:03:31.902Z","repository":{"id":192249692,"uuid":"686310439","full_name":"aecsocket/aeronet","owner":"aecsocket","description":"Set of Bevy-native networking crates, focused on providing robust and rock-solid data transfer primitives","archived":false,"fork":false,"pushed_at":"2026-01-16T17:06:15.000Z","size":3952,"stargazers_count":114,"open_issues_count":2,"forks_count":15,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-17T05:14:53.909Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aecsocket.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-02T11:18:12.000Z","updated_at":"2026-01-16T17:06:25.000Z","dependencies_parsed_at":"2023-10-03T01:38:12.168Z","dependency_job_id":"232ba8ac-f071-40a5-96dc-8f3a520ee8f6","html_url":"https://github.com/aecsocket/aeronet","commit_stats":{"total_commits":508,"total_committers":2,"mean_commits":254.0,"dds":"0.0059055118110236116","last_synced_commit":"fa86997dec6e004067f81b8f5ddf825fcd4fddf0"},"previous_names":["aecsocket/aeronet"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/aecsocket/aeronet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aecsocket%2Faeronet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aecsocket%2Faeronet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aecsocket%2Faeronet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aecsocket%2Faeronet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aecsocket","download_url":"https://codeload.github.com/aecsocket/aeronet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aecsocket%2Faeronet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29587066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T16:55:40.614Z","status":"ssl_error","status_checked_at":"2026-02-18T16:55:37.558Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-27T15:03:49.047Z","updated_at":"2026-02-18T17:03:31.891Z","avatar_url":"https://github.com/aecsocket.png","language":"Rust","readme":"Set of [Bevy]-native networking crates, focused on providing robust and rock-solid data transfer primitives.\n\n[![crates.io](https://img.shields.io/crates/v/aeronet.svg)](https://crates.io/crates/aeronet)\n[![docs.rs](https://img.shields.io/docsrs/aeronet)](https://docs.rs/aeronet)\n\n![Screenshot From 2025-04-23 17-41-21](https://github.com/user-attachments/assets/bde19d82-4070-46ba-be5b-8946e396c307)\n\n# Goals\n\n- Native to Bevy ECS\n  - Network state is represented as entities, making them easily queryable\n  - React to connections and disconnections via observers\n  - Send and receive data by mutating components\n- Correct and non-panicking\n  - Explicit error handling, where failure conditions are clear and documented\n  - No `unwrap`s - all panicking paths are a bug unless explicitly documented\n- Support for any network topology\n  - Dedicated server/client, listen server, peer-to-peer\n- Swappable IO layer\n  - Use whatever you like as the underlying byte transfer mechanism\n  - You can use multiple IO layers at the same time, e.g. Steam + WebTransport\n  - Supports `no_std` and platforms with limited atomic support via `critical-section`\n\nHigh-level networking features such as replication, rollback, and prediction are explicit **non-goals** for this crate. Instead, this crate aims to provide a solid foundation for implementing these features.\n\n### [📚 Further reading](https://github.com/aecsocket/aeronet/tree/main/crates/aeronet/docs)\n\n- [Changelog](https://github.com/aecsocket/aeronet/blob/main/crates/aeronet/docs/changelog.md)\n- [Design](https://github.com/aecsocket/aeronet/blob/main/crates/aeronet/docs/design.md)\n\n# Crates\n\n## IO layer implementations\n\nBefore writing networking code, you must choose an *IO layer implementation*. This is the crate that forwards bytes between your application and the underlying network link (i.e. socket or channel).\n\n### [`aeronet_channel`]\n\n| ✅ Complete | 🖥️ Native | 🌐 WASM |\n|------------|-----------|--------|\n\nUses in-memory MPSC channels for single-process communication.\n\n```sh\ncargo run --example channel\n```\n\n### [`aeronet_websocket`]\n\n| ✅ Complete | 🖥️ Native | 🌐 WASM |\n|------------|-----------|--------|\n\nUses WebSockets over TCP in a networked environment.\n\nThis example shows how to set up an encrypted server and client with self-signed certificates. WASM will not work with self-signed certificates - you will need a real certificate signed by an authority that your browser trusts.\n\n```sh\ncargo run --example websocket_server -F server\ncargo run --example websocket_client -F client\n\n# WASM\ncargo install wasm-server-runner\ncargo run --example websocket_client -F client --target wasm32-unknown-unknown\n```\n\n### [`aeronet_webtransport`]\n\n| ✅ Complete | 🖥️ Native | 🌐 WASM |\n|------------|-----------|--------|\n\nUses WebTransport over QUIC in a networked environment.\n\nOn WASM, when running the client, you will not be able to paste into the text box using Ctrl+V. To work around this:\n1. click into the text box you want to paste into\n2. click outside of the Bevy app (in the white area)\n3. press Ctrl+V\n\n```sh\ncargo run --example webtransport_server -F server\ncargo run --example webtransport_client -F client,dangerous-configuration\n\n# WASM\ncargo install wasm-server-runner\ncargo run --example webtransport_client -F client --target wasm32-unknown-unknown\n```\n\n### [`aeronet_steam`]\n\n| ✅ Complete | 🖥️ Native |\n|------------|-----------|\n\nUses Steam's [networking sockets](https://partner.steamgames.com/doc/api/ISteamnetworkingSockets)\n\nYou will need Steam running locally on your machine to be able to run the examples. If you want to test out peer-to-peer connections (not socket address connections), you will need to run two separate Steam clients using two separate Steam accounts  - see *Development Environment* for an easy way to achieve this.\n\n```sh\n# run a server which listens on a socket address\ncargo run --example steam_server -F server -- addr\n# run a server which listens for Steam peers\ncargo run --example steam_server -F server -- peer\ncargo run --example steam_client -F client\n```\n\n## Integrations\n\n### [`aeronet_replicon`]\n\nHigh-level ECS replication via [`bevy_replicon`].\n\n```sh\ncargo run --bin move_box_server\ncargo run --bin move_box_client\n```\n\n### [`lightyear`]\n\nHigh-level server-authoritative networking library, using `aeronet` as the underlying IO library.\n\n# Overview\n\n## Quickstart\n\n- Add `aeronet` to your `Cargo.toml`\n- Add your chosen IO layer to your `Cargo.toml`\n- Skim the [`echo_client.rs`] and [`echo_server.rs`] examples to understand how to build a simple client and server\n- Use `docs.rs` to understand the usage of specific types\n  - We guarantee 100% coverage using the `missing_docs` lint\n  - See [`Session`] for a good place to get started\n\n## Layers\n\n`aeronet` is fundamentally split into multiple layers:\n- IO layer (abstraction) - [`aeronet_io`]\n  - Defines what a [`Session`] is, and how it behaves\n  - Handles core dis/connection logic, shared among all IO layer implementations\n  - Performs setup for the layers above\n- IO layer (implementation) - [`aeronet_channel`], [`aeronet_webtransport`], etc.\n  - Establishes and maintains a connection to a peer\n  - Detects connection and disconnection, and reports it to the session layer\n  - Allows sending and receiving packets unreliably\n  - User-swappable - can have multiple in a single app\n- Transport layer - [`aeronet_transport`]\n  - Handles fragmentation, reliability, and ordering of messages\n  - Splits messages into packets, and reassembles packets into messages, which can be used by layers above\n  - Allows receiving acknowledgement of sent message acknowledgements\n  - Technically user-swappable, but most code above this layer relies on [`aeronet_transport`] specifically\n- Component replication, rollback, etc.\n  - This is not provided as part of `aeronet`, but you can use a crate which integrates `aeronet` with one of these e.g. [`aeronet_replicon`], [`lightyear`]\n\n## Writing an IO layer\n\nIf none of the first-party or third-party IO layer implementations suit your needs, you can write your own IO layer implementation for your needs. `aeronet_io` is designed to be as minimal as possible, to make writing your own IO layers simple, and allow them to integrate with higher levels of the stack seamlessly.\n\nYou can use [`aeronet_channel`] as a simple reference implementation of an IO layer - it's [a single file](https://github.com/aecsocket/aeronet/blob/main/crates/aeronet_channel/src/lib.rs). It demonstrates how to poll a channel synchronously from the Bevy event loop, which is useful if your underlying IO layer is not async.\n\nIf you are writing an IO layer which integrates with an async crate, we recommend using [`aeronet_websocket`] and [`aeronet_webtransport`] as reference implementations. They describe how to integrate async code into Bevy's sync event loop.\n\n# Testing\n\n## For `aeronet`\n\n`aeronet` and its subcrates use a combination of:\n- unit tests, using `cargo`, for individual, self-contained features\n- integration tests, using `cargo`, for testing code in the context of a full Bevy app\n- fuzz tests, using [`cargo-fuzz`], for protocol-level features and parsing\n  - used by [`aeronet_transport`]\n\n### Fuzz tests\n\nTo run the fuzz tests:\n```sh\ncd crates/aeronet_transport\ncargo +nightly fuzz run \u003cfuzz target\u003e\n```\n\n## For users\n\n### Visualizer\n\nAs a debug tool, you may want to see the state of your session over time while you are in the app. If using [`aeronet_transport`], you can use the `visualizer` feature to enable an [`egui_plot`] visualizer which displays statistics on sessions. This includes data such as round-trip time and packet loss percentage.\n\n### Conditioning\n\nUsing a conditioner allows you to emulate poor network conditions locally, and see how your app copes with problems such as duplicate or lost packets, delay, and jitter.\n\nSome example tools you may use are:\n- Linux\n  - [`tc`](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_and_managing_networking/linux-traffic-control_configuring-and-managing-networking)\n    - `sudo tc qdisc add dev lo root netem delay 250ms`\n    - `sudo tc qdisc add dev lo root netem delay 200ms 50ms distribution normal`\n    - `sudo tc qdisc add dev lo root netem loss 50%`\n    - `sudo tc qdisc delete dev lo root`\n- MacOS\n  - [`dummynet`](https://superuser.com/questions/126642/throttle-network-bandwidth-per-application-in-mac-os-x)\n- Windows\n  - [`clumsy`](https://github.com/jagt/clumsy)\n\n`aeronet` does not provide support for conditioning within the networking crate itself, since conditioning testing is more effective (and representative of real-world results) when the conditioning is applied at the lowest level possible (the OS layer).\n\n# Contributing\n\nThank you for supporting the development of this project! Before you start writing a contribution, here's some helpful information.\n\n## Development Environment\n\nThis project defines a [dev container], allowing you to set up a Docker container as a development environment. This environment contains all of the tools you need to write and test your code, which you can then remote into via your IDE. If you are on one of the supported platforms, and already have dev container tooling set up (i.e. [VS Code Dev Containers] or [DevPod]), **we recommend using a dev container** to develop in.\n\nCurrently, the dev container requires Linux on Wayland with a GPU, as this is required to run a Bevy app with a GUI. The container also installs Steam for testing `aeronet_steam`, but you will have to log into your own Steam account manually inside the container if you want to test. We also include a `devcontainer-alt.json` - a copy of `devcontainer.json`, but using a different named volume for `/home/dev` - so that you can have two identical containers, but with different Steam accounts running in each one. This can be used to test Steam peer-to-peer connections.\n\n[dev container]: https://containers.dev/\n[VS Code Dev Containers]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers\n[DevPod]: https://devpod.sh/\n\n## Testing\n\nWhen submitting a pull request, make sure that all continuous integration (CI) checks pass. CI is intentionally set to be as strict as reasonably possible, to keep the quality of code in `main` high.\n\n# Versions\n\n| `bevy` | `aeronet`           |\n|--------|---------------------|\n| `0.18` | `0.19.0` - `0.19.1` |\n| `0.17` | `0.17.0` - `0.18.0` |\n| `0.16` | `0.13.0` - `0.16.0` |\n| `0.15` | `0.11.0` - `0.12.0` |\n| `0.14` | `0.9.0`  - `0.10.0` |\n\n[Bevy]: https://bevyengine.org\n[`aeronet_io`]: https://docs.rs/aeronet_io\n[`aeronet_channel`]: https://docs.rs/aeronet_channel\n[`aeronet_websocket`]: https://docs.rs/aeronet_websocket\n[`aeronet_webtransport`]: https://docs.rs/aeronet_webtransport\n[`aeronet_steam`]: https://docs.rs/aeronet_steam\n[`aeronet_replicon`]: https://docs.rs/aeronet_replicon\n[`bevy_replicon`]: https://docs.rs/bevy_replicon\n[`lightyear`]: https://docs.rs/lightyear\n[`aeronet_transport`]: https://docs.rs/aeronet_transport\n[`Session`]: io::Session\n[`echo_client.rs`]: ./examples/src/bin/echo_client.rs\n[`echo_server.rs`]: ./examples/src/bin/echo_server.rs\n[`egui_plot`]: https://docs.rs/egui_plot\n[`cargo-fuzz`]: https://github.com/rust-fuzz/cargo-fuzz\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faecsocket%2Faeronet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faecsocket%2Faeronet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faecsocket%2Faeronet/lists"}