2022-03-13 21:43:04 +00:00
{
"crate_groups" : [
{
2022-04-18 16:06:35 +00:00
"slug" : "common" ,
"name" : "Common" ,
"description" : "Very commonly used crates that everyone should know about" ,
2022-04-27 17:08:49 +00:00
"subgroups" : [
2022-03-13 21:43:04 +00:00
{
2022-04-27 17:08:49 +00:00
"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"
} ]
} ,
2022-04-27 17:12:01 +00:00
{
"name" : "UUIDs" ,
"crates" : [ {
"name" : "uuid" ,
"notes" : "Implements generating and parsing UUIDs and a number of utility functions"
} ]
} ,
2022-04-27 17:08:49 +00:00
{
"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"
} ]
} ,
2022-05-02 13:54:15 +00:00
{
"name" : "Temporary files" ,
"crates" : [ {
"name" : "tempfile" ,
"notes" : "Supports both temporary files and temporary directories"
} ]
} ,
2022-04-27 17:08:49 +00:00
{
"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."
} ]
} ,
2022-05-01 23:57:46 +00:00
{
"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"
} , {
2022-05-02 00:03:25 +00:00
"name" : "smallvec" ,
"notes" : "Arrays that are stack-allocated with fallback to the heap if the fixed stack capacity is exceeded"
2022-05-01 23:57:46 +00:00
} , {
"name" : "tinyvec" ,
"notes" : "Stack allocated arrays in 100% safe Rust code but requires items to implement the Default trait."
} ]
} ,
2022-04-27 17:08:49 +00:00
{
"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."
} ]
}
]
2022-03-13 21:43:04 +00:00
} ,
{
2022-04-27 17:08:49 +00:00
"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."
} ]
}
]
2022-03-13 21:43:04 +00:00
} ,
{
2022-04-27 17:08:49 +00:00
"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."
} ]
} ,
{
2022-11-04 16:16:30 +00:00
"name" : "Structured logging" ,
2022-04-27 17:08:49 +00:00
"crates" : [ {
"name" : "tracing" ,
"notes" : "Tracing is now the go-to crate for logging."
} , {
"name" : "slog" ,
2022-11-04 16:16:30 +00:00
"notes" : "Structured logging"
2022-04-27 17:08:49 +00:00
} ]
}
]
2022-03-13 21:43:04 +00:00
} ,
{
2022-04-27 17:08:49 +00:00
"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"
} ]
}
]
2022-04-27 17:18:09 +00:00
} ,
{
"slug" : "system" ,
"name" : "System" ,
"description" : "For low-level interaction with the underling platform / operating system" ,
"purposes" : [
{
"name" : "Memory mapping files" ,
"crates" : [ {
2022-11-04 16:18:12 +00:00
"name" : "memmap2" ,
"notes" : "The older memmap crate is unmaintained."
2022-04-27 17:18:09 +00:00
} ]
} ,
{
"name" : "Libc" ,
"crates" : [ {
"name" : "libc" ,
"notes" : "Bindings for directly calling libc functions."
} ]
} ,
{
"name" : "Windows (OS)" ,
"crates" : [ {
2022-11-05 16:30:16 +00:00
"name" : "windows" ,
2022-04-27 17:18:09 +00:00
"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"
} ]
}
]
2022-03-13 21:43:04 +00:00
}
]
2022-04-27 17:53:10 +00:00
} ,
{
"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" ,
2022-05-02 12:05:31 +00:00
"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 <a target=\"_blank\" href=\"https://github.com/rust-cli/argparse-benchmarks-rs\">argparse-benchmarks-rs</a> 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"
2022-04-27 17:53:10 +00:00
} ]
}
]
2022-05-02 14:32:46 +00:00
} ,
{
"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"
} ]
}
]
2022-04-27 17:53:10 +00:00
}
]
2022-05-02 13:52:48 +00:00
} ,
{
"slug" : "concurrency" ,
"name" : "Concurrency" ,
"description" : "" ,
"subgroups" : [
{
"slug" : "data-structures" ,
"name" : "Data Structures" ,
2022-05-10 10:57:40 +00:00
"description" : "" ,
2022-05-02 13:52:48 +00:00
"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" ,
2022-05-10 10:57:40 +00:00
"notes" : "See <a target=\"_blank\" href=\"https://github.com/xacrimon/conc-map-bench\">conc-map-bench</a> for comparative benchmarks of concurrent HashMaps." ,
2022-05-02 13:52:48 +00:00
"crates" : [ {
"name" : "dashmap" ,
"notes" : "The fastest for general purpose workloads"
} , {
"name" : "flurry" ,
"notes" : "Particularly good for read-heavy workloads."
} ]
} ,
{
"name" : "Channels" ,
2022-05-06 10:32:05 +00:00
"notes" : "See <a href=\"https://docs.rs/tokio/latest/tokio/sync/mpsc/index.html#communicating-between-sync-and-async-code\">communicating-between-sync-and-async-code</a> for notes on when to use async-specific channels vs general purpose channels." ,
2022-05-10 10:57:40 +00:00
"crates" : [
{
2022-05-02 13:52:48 +00:00
"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"
2022-05-10 10:57:40 +00:00
} ,
{
2022-05-02 13:52:48 +00:00
"name" : "postage" ,
"notes" : "Channels that integrate nicely with async code"
} ]
2022-11-04 14:41:12 +00:00
} ,
{
"name" : "Parallel computation" ,
"crates" : [
{
"name" : "rayon" ,
"notes" : "Convert sequential computation into parallel computation with one call - `par_iter` instead of `iter`"
} ]
2022-05-02 13:52:48 +00:00
}
]
}
]
2022-03-13 21:43:04 +00:00
}
]
2022-11-04 14:41:12 +00:00
}