{ "crate_groups": [ { "slug": "common", "name": "Common", "description": "Very commonly used crates that everyone should know about", "subgroups": [ { "slug": "general", "name": "General", "description": "General purpose ", "purposes": [ { "name": "Random numbers", "crates": [{ "name": "rand", "notes": "De facto random number generation library split out from the standard library" }] }, { "name": "UUIDs", "crates": [{ "name": "uuid", "notes": "Implements generating and parsing UUIDs and a number of utility functions" }] }, { "name": "Serialization (JSON, YAML, etc)", "crates": [{ "name": "serde", "notes": "De facto serialization library. Use in conjunction with sub-crates like serde_json for the specific format that you are using." }] }, { "name": "Regular Expressions", "crates": [{ "name": "regex", "notes": "De facto regex library. Very fast, but does not support fancier features such as backtracking." }, { "name": "fancy_regex", "notes": "Use if need features such as backtracking which regex doesn't support" }] }, { "name": "Temporary files", "crates": [{ "name": "tempfile", "notes": "Supports both temporary files and temporary directories" }] }, { "name": "Gzip (de)compression", "crates": [{ "name": "flate2", "notes": "Uses a pure-Rust implementation by default. Use feature flags to opt in to system zlib." }] }, { "name": "Time & Date", "crates": [{ "name": "time", "notes": "The original datetime crate which was split out of std pre-rust-1.0. Preferrable if covers your needs, but it's quite limited in what it provides." }, { "name": "chrono", "notes": "The most comphrehensive and full-featured datetime library, but more complex because of it." }] }, { "name": "Insertion-ordered map", "crates": [{ "name": "indexmap", "notes": "A HashMap that seperately keeps track of insertion order and allows you to efficiently iterate over it's elements in that order" }] }, { "name": "Stack-allocated arrays", "crates": [{ "name": "arrayvec", "notes": "Arrays that are ONLY stack-allocated with fixed capacity" }, { "name": "smallvec", "notes": "Arrays that are stack-allocated with fallback to the heap if the fixed stack capacity is exceeded" }, { "name": "tinyvec", "notes": "Stack allocated arrays in 100% safe Rust code but requires items to implement the Default trait." }] }, { "name": "HTTP Requests", "crates": [{ "name": "reqwest", "notes": "Full-fat HTTP client. Can be used in both synchronous and asynchronous code. Requires tokio runtime." }, { "name": "ureq", "notes": "Minimal synchronous HTTP client focussed on simplicity and minimising dependencies." }] } ] }, { "slug": "error-handling", "name": "Error Handling", "description": "Crates for more easily handling errors", "purposes": [ { "name": "For applications", "crates": [{ "name": "anyhow", "notes": "Provides a boxed error type that can hold any error, and helpers for generating an application-level stack trace." }] }, { "name": "For libraries", "crates": [{ "name": "thiserror", "notes": "Helps with generating boilerplate for enum-style error types." }] } ] }, { "slug": "logging", "name": "Logging", "description": "Crates for logging. Note that in general you will need a seperate crate for actually printing/storing the logs", "purposes": [ { "name": "Text-based logging", "crates": [{ "name": "tracing", "notes": "Tracing is now the go-to crate for logging." }, { "name": "log", "notes": "An older and simpler crate if your needs are simple and you are not using any async code." }] }, { "name": "Structed logging", "crates": [{ "name": "tracing", "notes": "Tracing is now the go-to crate for logging." }, { "name": "slog", "notes": "Structed logging" }] } ] }, { "slug": "lang-extensions", "name": "Language Extensions", "description": "General purpose utility crates that extend language and/or stdlib functionality.", "purposes": [ { "name": "Lazy static variable initialization", "crates": [{ "name": "once_cell", "notes": "Newer crate with more ergonomic API. On track to be incorporated into the standard library. Should be preferred for all new projects." }, { "name": "lazy_static", "notes": "Older crate. API is less convenient, but crate is stable and maintained." }] }, { "name": "Iterator helpers", "crates": [{ "name": "itertools", "notes": "A bunch of useful methods on iterators that aren't in the stdlib" }] }, { "name": "Abstracting over different number types", "crates": [{ "name": "num", "notes": "Traits like Number, Add, etc that allow you write functions that are generic over the specific numeric type" }] }, { "name": "Endian conversion", "crates": [{ "name": "byteorder", "notes": "Utility functions to convert between different endianness or read/write data with a specific endianness" }] }, { "name": "Bitflags", "crates": [{ "name": "bitflags", "notes": "Strongly typed bitflag types" }] } ] }, { "slug": "system", "name": "System", "description": "For low-level interaction with the underling platform / operating system", "purposes": [ { "name": "Memory mapping files", "crates": [{ "name": "memmap", "notes": "" }] }, { "name": "Libc", "crates": [{ "name": "libc", "notes": "Bindings for directly calling libc functions." }] }, { "name": "Windows (OS)", "crates": [{ "name": "windows-rs", "notes": "The official Microsoft-provided crate for interacting with windows APIs" }, { "name": "winapi", "notes": "Older binding to the windows APIs. Unofficial, but more complete than windows-rs" }] } ] } ] }, { "slug": "networking", "name": "Networking", "description": "TCP, HTTP, GRPc, etc. And the executors required to do asynchronous networking.", "subgroups": [ { "slug": "async-executors", "name": "Async Executors", "description": "To do async programming using the async-await in Rust you need a runtime to execute drive your Futures.", "purposes": [ { "name": "General purpose", "crates": [{ "name": "tokio", "notes": "The oldest async runtime in the Rust ecosystem and still the most widely supported. Recommended for new projects." }, { "name": "async-std", "notes": "A newer option that is very similar to tokio. It's API more closely mirrors the std library, but it doesn't have as much traction as Tokio." }] }, { "name": "io_uring", "crates": [{ "name": "glommio", "notes": "Use if you need io_uring support. Still somewhat experimental but rapidly maturing." }] } ] }, { "slug": "http-foundations", "name": "HTTP", "description": "To do async programming using the async-await in Rust you need a runtime to execute drive your Futures.", "purposes": [ { "name": "Types & Interfaces", "crates": [{ "name": "http", "notes": "The `http` crate doesn't actually contain an HTTP implementation. Just types and interfaces to help interoperability." }] }, { "name": "Low-level HTTP Implementation", "crates": [{ "name": "hyper", "notes": "A low-level HTTP implementation (both client and server). Implements HTTP 1, 2, and 3. Requires the tokio async runtime." }] }, { "name": "TLS / SSL", "crates": [{ "name": "rustls", "notes": "A portable pure-rust implementation of TLS" }, { "name": "rust-native-tls", "notes": "Delegates to the system TLS implementations on windows and macOS, and uses OpenSSL on linux." }] }, { "name": "HTTP Client", "crates": [{ "name": "reqwest", "notes": "Full-fat HTTP client. Can be used in both synchronous and asynchronous code. Requires tokio runtime." },{ "name": "surf", "notes": "Client that uses the async-std runtime rather than the tokio runtime." }, { "name": "ureq", "notes": "Minimal synchronous HTTP client focussed on simplicity and minimising dependencies." }] }, { "name": "HTTP Server", "crates": [{ "name": "axum", "notes": "A minimal and ergonomic framework. An official part of the tokio project. Recommend for most new projects." }, { "name": "tide", "notes": "Similar to Axum, but based on async-std rather than tokio" }, { "name": "actix-web", "notes": "A performance focussed framework. All Rust frameworks are fast, but choose actix-web if you need the absolutely maximum performance." }, { "name": "poem", "notes": "Automatically generates OpenAPI defintions." }, { "name": "warp", "notes": "Very similar to axum but with a quirkier API. This is a solid framework, but you should probably prefer Axum unless you particular like the API" }, { "name": "rocket", "notes": "Focussed on ergonomics. This is a solid framework, however development has stalled. Avoid for new projects." }] } ] }, { "slug": "websockets", "name": "Websockets", "description": "This section includes libraries for you to use just websockets. However note that many of the HTTP server frameworks in the section above also support websockets", "purposes": [ { "name": "Low-level", "crates": [{ "name": "tungstenite-rs", "notes": "Low-level crate that others build on" }] }, { "name": "General Purpose", "crates": [{ "name": "tokio-tungstenite", "notes": "If you are using the tokio executor" }, { "name": "async-tungstenite", "notes": "If you are using the async-std executor" }] } ] }, { "slug": "grpc", "name": "gRPC", "description": "", "purposes": [ { "name": "General Purpose", "crates": [{ "name": "tonic", "notes": "gRPC over HTTP/2 with full support for asynchronous code. Works with tokio" }] } ] } ] }, { "slug": "cli-tools", "name": "CLIs", "description": "", "subgroups": [ { "slug": "argument-parsing", "name": "Argument Parsing", "description": "See argparse-benchmarks-rs for a full comparison of the crates mentioned here and more.", "purposes": [ { "name": "Fully-featured", "crates": [{ "name": "clap", "notes": "Ergonomic, supports everything, and is fast at runtime. However compile times can be slow" }] }, { "name": "Minimal", "crates": [{ "name": "lexopt", "notes": "Fast compile times, fast runtime, pedantic about correctness. API is less ergonomic" }, { "name": "pico-args", "notes": "Fast compile times, fast runtime, more lax about correctness. API is more ergonomic" }] } ] }, { "slug": "utility", "name": "Utility", "description": "Helpers that are often useful when implementing CLIs", "purposes": [ { "name": "Globbing", "crates": [{ "name": "globset", "notes": "High-performance globbing that allows multiple globs to be evaluated at once" }] }, { "name": "Directory walking", "crates": [{ "name": "walkdir", "notes": "Basic recursive filesystem walking." }, { "name": "ignore", "notes": "Recursive filesystem walking that respects ignore files (like .gitignore)" }] }, { "name": "File watching", "crates": [{ "name": "watchexec", "notes": "Watch files or directories and execute a function when they change" }] } ] }, { "slug": "rendering", "name": "Terminal Rendering", "description": "For fancy terminal rendering and TUIs. The crates recommended here work cross-platform (including windows).", "purposes": [ { "name": "Coloured Output", "crates": [{ "name": "termcolor", "notes": "Cross-platform terminal colour output" }] }, { "name": "Full TUI library", "crates": [{ "name": "crossterm", "notes": "Cross-platform terminal rendering and event handling" }] } ] } ] }, { "slug": "concurrency", "name": "Concurrency", "description": "", "subgroups": [ { "slug": "data-structures", "name": "Data Structures", "description": "See conc-map-bench for benchmarks of concurrent HashMaps.", "purposes": [ { "name": "Mutex", "crates": [{ "name": "parking_lot", "notes": "std::mutex also works fine. But Parking Lot is faster." }] }, { "name": "Atomic pointer swapping", "crates": [{ "name": "arc_swap", "notes": "Useful for sharing data that has many readers but few writers" }] }, { "name": "Concurrent HashMap", "crates": [{ "name": "dashmap", "notes": "The fastest for general purpose workloads" }, { "name": "flurry", "notes": "Particularly good for read-heavy workloads." }] }, { "name": "Channels", "crates": [{ "name": "crossbeam_channel", "notes": "The absolute fastest channel implementation available. Implements Go-like 'select' feature." }, { "name": "flume", "notes": "Smaller and simpler than crossbeam_channel and almost as fast" }, { "name": "postage", "notes": "Channels that integrate nicely with async code" }] } ] } ] } ] }