mirror of
https://github.com/nicoburns/blessed-rs
synced 2024-11-10 06:14:15 +00:00
1269 lines
66 KiB
JSON
1269 lines
66 KiB
JSON
{
|
|
"crate_groups": [
|
|
{
|
|
"slug": "tooling",
|
|
"name": "Tooling",
|
|
"description": "Developer tools for working with Rust projects.",
|
|
"subgroups": [],
|
|
"purposes": [
|
|
{
|
|
"name": "Toolchain Management",
|
|
"recommendations": [{
|
|
"name": "rustup",
|
|
"link": "https://rustup.rs",
|
|
"notes": "Install, manage, and upgrade versions of rustc, cargo, clippy, rustfmt and more."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Linting",
|
|
"recommendations": [{
|
|
"name": "clippy",
|
|
"link": "https://github.com/rust-lang/rust-clippy#usage",
|
|
"notes": "The official Rust linter."
|
|
}, {
|
|
"name": "cargo-semver-checks",
|
|
"link": "https://github.com/obi1kenobi/cargo-semver-checks",
|
|
"notes": "Lint your crate releases for semantic versioning violations."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Code Formatting",
|
|
"recommendations": [{
|
|
"name": "rustfmt",
|
|
"link": "https://github.com/rust-lang/rustfmt#rustfmt----",
|
|
"notes": "The official Rust code formatter."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Cross Compilation",
|
|
"recommendations": [{
|
|
"name": "cross",
|
|
"link": "https://github.com/cross-rs/cross#cross",
|
|
"notes": "Seamless cross-compiling using Docker containers."
|
|
}, {
|
|
"name": "cargo-zigbuild",
|
|
"link": "https://github.com/rust-cross/cargo-zigbuild",
|
|
"notes": "Easily cross-compile using Zig as the linker."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Managing Dependencies",
|
|
"recommendations": [{
|
|
"name": "cargo-edit",
|
|
"link": "https://github.com/killercup/cargo-edit",
|
|
"notes": "Adds 'cargo upgrade' and 'cargo set-version' commands to cargo"
|
|
}, {
|
|
"name": "cargo-outdated",
|
|
"link": "https://github.com/kbknapp/cargo-outdated#cargo-outdated",
|
|
"notes": "Finds dependencies that have available updates"
|
|
}, {
|
|
"name": "cargo-audit",
|
|
"link": "https://github.com/RustSec/rustsec/tree/main/cargo-audit#rustsec-cargo-audit",
|
|
"notes": "Check dependencies for reported security vulnerabilities"
|
|
}, {
|
|
"name": "cargo-license",
|
|
"link": "https://github.com/onur/cargo-license#cargo-license",
|
|
"notes": "Lists licenses of all dependencies"
|
|
}, {
|
|
"name": "cargo-deny",
|
|
"link": "https://github.com/EmbarkStudios/cargo-deny#-cargo-deny",
|
|
"notes": "Enforce policies on your code and dependencies."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Testing",
|
|
"recommendations": [{
|
|
"name": "cargo-nextest",
|
|
"link": "https://nexte.st",
|
|
"notes": "Faster, better test runner"
|
|
},
|
|
{
|
|
"name": "insta",
|
|
"link": "https://insta.rs",
|
|
"notes": "Snapshot testing with inline snapshot support"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Benchmarking",
|
|
"recommendations": [{
|
|
"name": "criterion",
|
|
"notes": "Statistically accurate benchmarking tool for benchmarking libraries"
|
|
}, {
|
|
"name": "divan",
|
|
"notes": "Simple yet powerful benchmarking library with allocation profiling"
|
|
}, {
|
|
"name": "hyperfine",
|
|
"link": "https://github.com/sharkdp/hyperfine#hyperfine",
|
|
"notes": "Tool for benchmarking compiled binaries (similar to unix time command but better)"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Performance",
|
|
"recommendations": [{
|
|
"name": "cargo-flamegraph",
|
|
"link": "https://github.com/flamegraph-rs/flamegraph#cargo-flamegraph",
|
|
"notes": "Execution flamegraph generation"
|
|
}, {
|
|
"name": "dhat",
|
|
"notes": "Heap memory profiling"
|
|
}, {
|
|
"name": "cargo-show-asm",
|
|
"notes": "Print the generated assembly for a Rust function"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Debugging Macros",
|
|
"notes": "<a href=\"https://github.com/rust-lang/rust-analyzer\">Rust Analyzer</a> also allows you to <a href=\"https://rust-analyzer.github.io/manual.html#expand-macro-recursively\">expand macros directly in your editor</a>",
|
|
"recommendations": [{
|
|
"name": "cargo-expand",
|
|
"link": "https://github.com/dtolnay/cargo-expand#cargo-expand",
|
|
"notes": "Allows you to inspect the code that macros expand to"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Release Automation",
|
|
"recommendations": [{
|
|
"name": "cargo-release",
|
|
"link": "https://github.com/crate-ci/cargo-release#cargo-release",
|
|
"notes": "Helper for publishing new crate versions."
|
|
}, {
|
|
"name": "Release-plz",
|
|
"link": "https://release-plz.ieni.dev/",
|
|
"notes": "Release Rust crates from CI with a Release PR."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Continuous Integration",
|
|
"recommendations": [{
|
|
"name": "rust-toolchain (github action)",
|
|
"link": "https://github.com/dtolnay/rust-toolchain#install-rust-toolchain",
|
|
"notes": "Github action to install Rust components via rustup"
|
|
}, {
|
|
"name": "rust-cache (github action)",
|
|
"link": "https://github.com/Swatinem/rust-cache#rust-cache-action",
|
|
"notes": "Github action to cache compilation artifacts and speed up subsequent runs."
|
|
}, {
|
|
"name": "install-action (github action",
|
|
"link": "https://github.com/taiki-e/install-action",
|
|
"notes": "GitHub Action for installing development tools (mainly from GitHub Releases)."
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "rand",
|
|
"notes": "De facto standard random number generation library split out from the standard library"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Time & Date",
|
|
"notes": "Unfortunately there is no clear answer as to which is best between time and chrono.<br />Evaluate for yourself between these two, but be resassured that both are trusted and well-maintained.",
|
|
"recommendations": [{
|
|
"name": "time",
|
|
"notes": "A smaller, simpler library. Preferrable if covers your needs, but it's quite limited in what it provides."
|
|
}, {
|
|
"name": "chrono",
|
|
"notes": "The most comprehensive and full-featured datetime library, but more complex because of it."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Serialization (JSON, YAML, etc)",
|
|
"notes": "See <a href=\"https://docs.rs/serde/latest/serde/#data-formats\">here</a> for supported formats.",
|
|
"recommendations": [{
|
|
"name": "serde",
|
|
"notes": "De facto standard serialization library. Use in conjunction with sub-crates like serde_json for the specific format that you are using."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Regular Expressions",
|
|
"recommendations": [{
|
|
"name": "regex",
|
|
"notes": "De facto standard 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": "UUIDs",
|
|
"recommendations": [{
|
|
"name": "uuid",
|
|
"notes": "Implements generating and parsing UUIDs and a number of utility functions"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Temporary files",
|
|
"recommendations": [{
|
|
"name": "tempfile",
|
|
"notes": "Supports both temporary files and temporary directories"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Gzip (de)compression",
|
|
"recommendations": [{
|
|
"name": "flate2",
|
|
"notes": "Uses a pure-Rust implementation by default. Use feature flags to opt in to system zlib."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Insertion-ordered map",
|
|
"recommendations": [{
|
|
"name": "indexmap",
|
|
"notes": "A HashMap that seperately keeps track of insertion order and allows you to efficiently iterate over its elements in that order"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Stack-allocated arrays",
|
|
"recommendations": [{
|
|
"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",
|
|
"notes": "See the HTTP section below for server-side libraries",
|
|
"recommendations": [{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "anyhow",
|
|
"notes": "Provides a boxed error type that can hold any error, and helpers for generating an application-level stack trace."
|
|
}, {
|
|
"name": "color-eyre",
|
|
"notes": "A fork of anyhow that gives you more control over the format of the generated error messages. Recommended if you intend to present error messages to end users. Otherwise anyhow is simpler."
|
|
}]
|
|
},
|
|
{
|
|
"name": "For libraries",
|
|
"notes": "See also: <a href=\"https://mmapped.blog/posts/12-rust-error-handling.html\">Designing error types in Rust</a>",
|
|
"recommendations": [{
|
|
"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",
|
|
"recommendations": [{
|
|
"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": "Structured logging",
|
|
"recommendations": [{
|
|
"name": "tracing",
|
|
"notes": "Tracing is now the go-to crate for logging."
|
|
}, {
|
|
"name": "slog",
|
|
"notes": "Structured 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",
|
|
"notes": "The core functionality of once_cell is now <a href=\"https://doc.rust-lang.org/stable/std/cell/struct.OnceCell.html\">included in the standard library</a> with the remaining parts <a href=\"https://github.com/rust-lang/rust/issues/109736\">on track</a> to be stabilised in future.",
|
|
"recommendations": [{
|
|
"name": "once_cell",
|
|
"notes": "Newer crate with more ergonomic API. 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",
|
|
"recommendations": [{
|
|
"name": "itertools",
|
|
"notes": "A bunch of useful methods on iterators that aren't in the stdlib"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Macro helpers",
|
|
"recommendations": [{
|
|
"name": "syn",
|
|
"notes": "Parse rust source code"
|
|
}, {
|
|
"name": "quote",
|
|
"notes": "Quasi quoting rust (useful for interpolating generated code with literal code)"
|
|
}, {
|
|
"name": "paste",
|
|
"notes": "Concatenating and manipulating identifiers"
|
|
}, {
|
|
"name": "darling",
|
|
"notes": "Derive macro to easily parse derive macro inputs"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Safe type casts",
|
|
"recommendations": [{
|
|
"name": "bytemuck"
|
|
}, {
|
|
"name": "zerocopy"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Bitflags",
|
|
"recommendations": [{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "memmap2",
|
|
"notes": "The older memmap crate is unmaintained."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Libc",
|
|
"recommendations": [{
|
|
"name": "libc",
|
|
"notes": "Bindings for directly calling libc functions."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Windows (OS)",
|
|
"recommendations": [{
|
|
"name": "windows",
|
|
"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"
|
|
}]
|
|
},
|
|
{
|
|
"name": "*nix (OSs)",
|
|
"recommendations": [{
|
|
"name": "rustix",
|
|
"notes": "Efficient and safe POSIX / *nix / Winsock syscall-like APIs. It uses idiomatic Rust types: refs, slices, Results instead of raw pointers, safe wrappers around raw file descriptors, bitflags instead of bare integer flags, and several other conveniences."
|
|
}, {
|
|
"name": "nix",
|
|
"notes": "Bindings to the various *nix system functions. (Unix, Linux, MacOS, etc.)"
|
|
}]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "math-scientific",
|
|
"name": "Math / Scientific",
|
|
"description": "The <a href=\"https://lib.rs/crates/num\">num</a> crate is trusted and has a variety of numerical functionality that is missing from the standard library.",
|
|
"subgroups": [],
|
|
"purposes": [
|
|
{
|
|
"name": "Abstracting over different number types",
|
|
"recommendations": [{
|
|
"name": "num-traits",
|
|
"notes": "Traits like Number, Add, etc that allow you write functions that are generic over the specific numeric type"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Big Integers",
|
|
"recommendations": [
|
|
{ "name": "num-bigint", "notes": "It's not the fastest, but it's part of the trusted num library." },
|
|
{ "name": "rug", "notes": "LGPL licensed. Wrapper for GMP. Much faster than num-bigint." }
|
|
]
|
|
},
|
|
{
|
|
"name": "Big Decimals",
|
|
"recommendations": [
|
|
{ "name": "rust_decimal", "notes": "The binary representation consists of a 96 bit integer number, a scaling factor used to specify the decimal fraction and a 1 bit sign." }
|
|
]
|
|
},
|
|
{
|
|
"name": "Sortable Floats",
|
|
"recommendations": [
|
|
{ "name": "ordered-float", "notes": "Float types that don't allow NaN and are therefore orderable. You can also use the <code>total_cmp</code> method from the standard library like <code>.sort_by(|a, b| a.total_cmp(&b))</code>." }
|
|
]
|
|
},
|
|
{
|
|
"name": "Linear Algebra",
|
|
"recommendations": [
|
|
{ "name": "nalgebra", "notes": "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices. However it supports only vectors (1d) and matrices (2d) and not higher-dimensional tensors." },
|
|
{ "name": "ndarray", "notes": "Less featureful than nalgebra but supports arbitrarily dimensioned arrays" }
|
|
]
|
|
},
|
|
{
|
|
"name": "DataFrames",
|
|
"recommendations": [
|
|
{ "name": "polars", "notes": "Similar to the Pandas library in Python but in pure Rust. Uses the Apache Arrow Columnar Format as the memory model." },
|
|
{ "name": "datafusion", "notes": "<a href=\"https://arrow.apache.org/datafusion\">Apache DataFusion</a> is an in-memory query engine that uses Apache Arrow as the memory model" }
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "ffi",
|
|
"name": "FFI / Interop",
|
|
"description": "Crates that allow Rust to interact with code written in other languages.",
|
|
"subgroups": [],
|
|
"purposes": [
|
|
{
|
|
"name": "C",
|
|
"recommendations": [
|
|
{ "name": "bindgen", "notes": "Generate Rust bindings to C libraries" },
|
|
{ "name": "cbindgen", "notes": "Generate C bindings to Rust libraries" }
|
|
]
|
|
},
|
|
{
|
|
"name": "C++",
|
|
"recommendations": [
|
|
{ "name": "cxx", "notes": "Safe C++ <-> Rust interop by generating code for both sides." }
|
|
]
|
|
},
|
|
{
|
|
"name": "Python",
|
|
"recommendations": [
|
|
{ "name": "pyo3", "notes": "Supports both calling python code from Rust and exposing Rust code to Python" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Node.js",
|
|
"recommendations": [
|
|
{ "name": "napi", "notes": "is a framework for building pre-compiled Node.js addons in Rust." },
|
|
{ "name": "neon", "notes": "Slower than napi, but also widely used and well-maintained" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Ruby",
|
|
"recommendations": [
|
|
{ "name": "rutie", "notes": "Supports both embedding Rust into Ruby applications and embedding Ruby into Rust applications" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Objective-C",
|
|
"recommendations": [
|
|
{ "name": "objc", "notes": "Interop with the Objective-C runtime" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Java/JVM",
|
|
"recommendations": [
|
|
{ "name": "jni", "notes": "Implement Java methods for JVM and Android in Rust. Call Java code from Rust. Embed JVM in Rust applications." }
|
|
]
|
|
},
|
|
{
|
|
"name": "Lua",
|
|
"recommendations": [
|
|
{ "name": "mlua", "notes": "Bindings to Lua 5.4, 5.3, 5.2, 5.1 (including LuaJIT)" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Dart/Flutter",
|
|
"recommendations": [
|
|
{ "name": "flutter_rust_bridge", "notes": "Works with Dart with or without Flutter" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Erlang/Elixir",
|
|
"recommendations": [
|
|
{ "name": "rustler", "notes": "Safe Rust bridge for creating Erlang NIF functions" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Kotlin/Swift/Python/Ruby",
|
|
"recommendations": [
|
|
{ "name": "uniffi", "notes": "Share Rust codebase to create cross-platform apps (also 3rd party support for Kotlin Multiplatform, Go, C#, Dart)" }
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "cryptography",
|
|
"name": "Cryptography",
|
|
"description": "Crates that provide implementations of cryptographic algorithms. This section attempts to list the best crates for the listed algorithms, but does not intend to make recommendations for the algorithms themselves.<br />",
|
|
"subgroups": [],
|
|
"purposes": [
|
|
{
|
|
"name": "Password Hashing",
|
|
"notes": "For more algorithms, see <a href=\"https://github.com/RustCrypto/password-hashes#rustcrypto-password-hashes\">Rust Crypto Password Hashes</a>.",
|
|
"recommendations": [
|
|
{ "name": "argon2" },
|
|
{ "name": "scrypt" },
|
|
{ "name": "bcrypt" }
|
|
]
|
|
},
|
|
{
|
|
"name": "General Purpose Hashing",
|
|
"notes": "For more algorithms, see <a href=\"https://github.com/RustCrypto/hashes#rustcrypto-hashes\">Rust Crypto Hashes</a>.",
|
|
"recommendations": [
|
|
{ "name": "sha2" },
|
|
{ "name": "sha1" },
|
|
{ "name": "md-5" }
|
|
]
|
|
},
|
|
{
|
|
"name": "AEAD Encryption",
|
|
"notes": "For more algorithms, see <a href=\"https://github.com/RustCrypto/AEADs#rustcrypto-authenticated-encryption-with-associated-data-aead-algorithms\">Rust Crypto AEADs</a>.",
|
|
"recommendations": [
|
|
{ "name": "aes-gcm-siv" },
|
|
{ "name": "aes-gcm" },
|
|
{ "name": "chacha20poly1305" }
|
|
]
|
|
},
|
|
{
|
|
"name": "RSA",
|
|
"recommendations": [
|
|
{ "name": "rsa" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Digital Signatures",
|
|
"notes": "For more algorithms, see <a href=\"https://github.com/RustCrypto/signatures#rustcrypto-signatures--\">Rust Crypto Signatures</a>.",
|
|
"recommendations": [
|
|
{ "name": "ed25519", "notes": "Use in conjunction with the ed25519-dalek crate." },
|
|
{ "name": "ecdsa" },
|
|
{ "name": "dsa" }
|
|
]
|
|
},
|
|
{
|
|
"name": "Certificate Formats",
|
|
"notes": "For more formats, see <a href=\"https://github.com/RustCrypto/formats#rustcrypto-formats--\">Rust Crypto Formats</a>.",
|
|
"recommendations": [
|
|
{ "name": "der" },
|
|
{ "name": "pem-rfc7468" },
|
|
{ "name": "pkcs8" },
|
|
{ "name": "x509-cert" }
|
|
]
|
|
},
|
|
{
|
|
"name": "TLS / SSL",
|
|
"recommendations": [{
|
|
"name": "rustls",
|
|
"notes": "A portable pure-rust high-level implementation of TLS. Implements TLS 1.2 and higher."
|
|
}, {
|
|
"name": "native-tls",
|
|
"notes": "Delegates to the system TLS implementations on windows and macOS, and uses OpenSSL on linux."
|
|
}],
|
|
"see_also": [{
|
|
"name": "webpki",
|
|
"notes": "X.509 Certificate validation. Builds on top of ring."
|
|
}, {
|
|
"name": "ring",
|
|
"notes": "Fork of BoringSSL. Provides low-level cryptographic primitives for TLS/SSL"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Utilities",
|
|
"recommendations": [{
|
|
"name": "subtle",
|
|
"notes": "Utilities for writing constant-time algorithms"
|
|
},
|
|
{
|
|
"name": "zeroize",
|
|
"notes": "Securely erase memory"
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
|
|
{
|
|
"slug": "networking",
|
|
"name": "Networking",
|
|
"description": "TCP, HTTP, GRPc, etc. And the executors required to do asynchronous networking.",
|
|
"subgroups": [
|
|
{
|
|
"slug": "async-foundations",
|
|
"name": "Async Foundations",
|
|
"description": "To do async programming using the async-await in Rust you need a runtime to execute drive your Futures.",
|
|
"purposes": [
|
|
{
|
|
"name": "General Purpose Async Executors",
|
|
"recommendations": [{
|
|
"name": "tokio",
|
|
"notes": "The oldest async runtime in the Rust ecosystem and still the most widely supported. Recommended for new projects."
|
|
}, {
|
|
"name": "futures-executor",
|
|
"notes": "A minimal executor. In particular, the <a href=\"https://docs.rs/futures-executor/latest/futures_executor/fn.block_on.html\">block_on</a> function is useful if you want to run an async function synchronously in codebase that is mostly synchronous."
|
|
}],
|
|
"see_also": [{
|
|
"name": "async-std",
|
|
"notes": "A newer option that is very similar to tokio. Its API more closely mirrors the std library, but it doesn't have as much traction or ecosystem support as Tokio."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Async Utilities",
|
|
"recommendations": [{
|
|
"name": "futures",
|
|
"notes": "Utility functions for working with Futures and Streams"
|
|
}, {
|
|
"name": "async-trait",
|
|
"notes": "Provides a workaround for the lack of language support for async functions in traits"
|
|
}]
|
|
},
|
|
{
|
|
"name": "io_uring",
|
|
"recommendations": [{
|
|
"name": "glommio",
|
|
"notes": "Use if you need io_uring support. Still somewhat experimental but rapidly maturing."
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "http-foundations",
|
|
"name": "HTTP",
|
|
"description": "HTTP client and server libraries, as well as lower-level building blocks.",
|
|
"purposes": [
|
|
{
|
|
"name": "Types & Interfaces",
|
|
"recommendations": [{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "hyper",
|
|
"notes": "A low-level HTTP implementation (both client and server). Implements HTTP/1, and HTTP/2. Works best with the tokio async runtime, but can support other runtimes."
|
|
}]
|
|
},
|
|
{
|
|
"name": "HTTP Client",
|
|
"recommendations": [{
|
|
"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."
|
|
}],
|
|
"see_also": [{
|
|
"name": "surf",
|
|
"notes": "Client that uses the async-std runtime rather than the tokio runtime. Not well maintained."
|
|
}]
|
|
},
|
|
{
|
|
"name": "HTTP Server",
|
|
"recommendations": [{
|
|
"name": "axum",
|
|
"notes": "A minimal and ergonomic framework. An official part of the tokio project. Recommend for most new projects."
|
|
}, {
|
|
"name": "actix-web",
|
|
"notes": "A performance focussed framework. All Rust frameworks are fast, but choose actix-web if you need the absolutely maximum performance."
|
|
}],
|
|
"see_also": [{
|
|
"name": "rocket",
|
|
"notes": "Has an excellent API and a solid implementation. However development has been intermittent."
|
|
}, {
|
|
"name": "poem",
|
|
"notes": "Automatically generates OpenAPI definitions."
|
|
}, {
|
|
"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 particularly like the API"
|
|
}, {
|
|
"name": "tide",
|
|
"notes": "Similar to Axum, but based on async-std rather than tokio"
|
|
}]
|
|
},
|
|
{
|
|
"name": "GraphQL Server",
|
|
"recommendations": [{
|
|
"name": "async-graphql",
|
|
"notes": "A high-performance graphql server library that's fully specification compliant. Integrates with actix-web, axum, poem, rocket, tide, warp."
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "tungstenite",
|
|
"notes": "Low-level crate that others build on"
|
|
}]
|
|
},
|
|
{
|
|
"name": "General Purpose",
|
|
"recommendations": [{
|
|
"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",
|
|
"purposes": [
|
|
{
|
|
"name": "General Purpose",
|
|
"recommendations": [{
|
|
"name": "tonic",
|
|
"notes": "gRPC over HTTP/2 with full support for asynchronous code. Works with tokio"
|
|
}]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "databases",
|
|
"name": "Databases",
|
|
"subgroups": [
|
|
{
|
|
"slug": "sql-databases",
|
|
"name": "SQL Databases",
|
|
"description": "The multi-database options (SQLx and Diesel) are generally quite good, and worth considering even if you only need support for a single database.",
|
|
"purposes": [
|
|
{
|
|
"name": "Multi Database",
|
|
"recommendations": [{
|
|
"name": "sqlx",
|
|
"notes": "Works with Postgres, MySQL, SQLite, and MS SQL.<br />Supports compile time checking of queries. Async: supports both tokio and async-std."
|
|
}]
|
|
},
|
|
{
|
|
"name": "ORMs",
|
|
"recommendations": [
|
|
{
|
|
"name": "diesel",
|
|
"notes": "Has excellent performance and takes an approach of strict compile time guarantees. The main crate is Sync only, but <a href=\"https://lib.rs/crates/diesel-async\">diesel-async</a> provides an async connection implementation."
|
|
}, {
|
|
"name": "sea-orm",
|
|
"notes": "Built on top of sqlx (see above). There is also a related sea-query crate that provides a query builder without full ORM functionality."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Postgres",
|
|
"recommendations": [{
|
|
"name": "tokio-postgres",
|
|
"notes": "Postgres-specific library. Performs better than SQLx"
|
|
}]
|
|
},
|
|
{
|
|
"name": "MySQL",
|
|
"recommendations": [{
|
|
"name": "mysql_async",
|
|
"notes": "Has a poorly designed API. Prefer SQLx or Diesel for MySQL"
|
|
}]
|
|
},
|
|
{
|
|
"name": "SQLite",
|
|
"recommendations": [{
|
|
"name": "rusqlite",
|
|
"notes": "Provides a sync API to SQLite + provides access to advanced sqlite features."
|
|
}]
|
|
},
|
|
{
|
|
"name": "MS SQL",
|
|
"recommendations": [{
|
|
"name": "tiberius",
|
|
"notes": "MS SQL specific library. Has better support for advanced column types than SQLx."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Oracle",
|
|
"recommendations": [{
|
|
"name": "diesel-oci",
|
|
"notes": "Diesel backend and connection implementation for oracle databases"
|
|
}, {
|
|
"name": "oracle",
|
|
"notes": "Rust bindings to ODPI-C"
|
|
}, {
|
|
"name": "sibyl",
|
|
"notes": "An OCI-based interface supporting both blocking (threads) and nonblocking (async) AP"
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "other-databases",
|
|
"name": "Other Databases",
|
|
"purposes": [
|
|
{
|
|
"name": "Redis",
|
|
"recommendations": [{
|
|
"name": "redis"
|
|
}]
|
|
},
|
|
{
|
|
"name": "MongoDB",
|
|
"recommendations": [{
|
|
"name": "mongodb"
|
|
}]
|
|
},
|
|
{
|
|
"name": "ElasticSearch",
|
|
"recommendations": [{
|
|
"name": "elasticsearch"
|
|
}]
|
|
},
|
|
{
|
|
"name": "LMDB",
|
|
"notes": "<a href=\"https://github.com/mozilla/rkv\">The rkv crate</a> depends on <a href=\"https://github.com/mozilla/lmdb-rs\">the lmdb-rkv dependency</a> which is archived and is inactive.",
|
|
"recommendations": [{
|
|
"name": "heed",
|
|
"notes": "A fully typed LMDB wrapper with minimum overhead."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Rocks DB",
|
|
"recommendations": [{
|
|
"name": "rocksdb"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Cassandra",
|
|
"recommendations": [{
|
|
"name": "cassandra-protocol",
|
|
"notes": "Low-level Cassandra protocol implementation."
|
|
}, {
|
|
"name": "cdrs-tokio",
|
|
"notes": "High-level async Cassandra driver."
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "sql-utilities",
|
|
"name": "Utilities",
|
|
"purposes": [
|
|
{
|
|
"name": "Connection pool",
|
|
"recommendations": [{
|
|
"name": "deadpool",
|
|
"notes": "A dead simple async pool for connections and objects of any type."
|
|
}]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "cli-tools",
|
|
"name": "CLIs",
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "clap",
|
|
"notes": "Ergonomic, battle-tested, includes the kitchen sink, and is fast at runtime. However compile times can be slow"
|
|
}],
|
|
"see_also": [{
|
|
"name": "bpaf",
|
|
"notes": "Faster compile times than clap while still being featureful. But still has some rough edges, and the API can be confusing at times."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Minimal",
|
|
"recommendations": [{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "globset",
|
|
"link": "https://crates.io/crates/globset",
|
|
"notes": "High-performance globbing that allows multiple globs to be evaluated at once"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Directory walking",
|
|
"recommendations": [{
|
|
"name": "walkdir",
|
|
"link": "https://crates.io/crates/walkdir",
|
|
"notes": "Basic recursive filesystem walking."
|
|
}, {
|
|
"name": "ignore",
|
|
"link": "https://crates.io/crates/ignore",
|
|
"notes": "Recursive filesystem walking that respects ignore files (like .gitignore)"
|
|
}]
|
|
},
|
|
{
|
|
"name": "File watching",
|
|
"recommendations": [{
|
|
"name": "notify",
|
|
"notes": "Watch files or directories and execute a function when they change"
|
|
}]
|
|
},
|
|
{
|
|
"name": "User directories",
|
|
"recommendations": [{
|
|
"name": "dirs",
|
|
"notes": "Provide platform-specific locations for configuration, cache, and other data"
|
|
}, {
|
|
"name": "directories",
|
|
"notes": "A higher-level library that can also compute paths for applications"
|
|
}],
|
|
"see_also": [{
|
|
"name": "etcetera",
|
|
"notes": "An alternative with a different license"
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"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",
|
|
"recommendations": [{
|
|
"name": "termcolor",
|
|
"notes": "Cross-platform terminal colour output"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Progress indicators",
|
|
"recommendations": [{
|
|
"name": "indicatif",
|
|
"notes": "Progress bars and spinners"
|
|
}]
|
|
},
|
|
{
|
|
"name": "TUI",
|
|
"recommendations": [{
|
|
"name": "ratatui",
|
|
"notes": "A high-level TUI library with widgets, layout, etc. "
|
|
}, {
|
|
"name": "crossterm",
|
|
"notes": "Low-level cross-platform terminal rendering and event handling"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Interactive prompts",
|
|
"recommendations": [{
|
|
"name": "inquire",
|
|
"notes": "Ask for confirmation, selection, text input and more"
|
|
}]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "concurrency",
|
|
"name": "Concurrency",
|
|
"subgroups": [
|
|
{
|
|
"slug": "data-structures",
|
|
"name": "Data Structures",
|
|
"purposes": [
|
|
{
|
|
"name": "Mutex",
|
|
"recommendations": [{
|
|
"name": "parking_lot",
|
|
"notes": "std::sync::Mutex also works fine. But Parking Lot is faster."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Atomic pointer swapping",
|
|
"recommendations": [{
|
|
"name": "arc-swap",
|
|
"notes": "Useful for sharing data that has many readers but few writers"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Concurrent HashMap",
|
|
"notes": "See <a target=\"_blank\" href=\"https://github.com/xacrimon/conc-map-bench\">conc-map-bench</a> for comparative benchmarks of concurrent HashMaps.",
|
|
"recommendations": [{
|
|
"name": "dashmap",
|
|
"notes": "The fastest for general purpose workloads"
|
|
}, {
|
|
"name": "flurry",
|
|
"notes": "Particularly good for read-heavy workloads."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Channels",
|
|
"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.",
|
|
"recommendations": [
|
|
{
|
|
"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": "tokio",
|
|
"notes": "Tokio's sync module provides channels for using in async code"
|
|
}, {
|
|
"name": "postage",
|
|
"notes": "Channels that integrate nicely with async code, with different options than Tokio"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Parallel computation",
|
|
"recommendations": [
|
|
{
|
|
"name": "rayon",
|
|
"notes": "Convert sequential computation into parallel computation with one call - `par_iter` instead of `iter`"
|
|
}]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "graphics",
|
|
"name": "Graphics",
|
|
"subgroups": [
|
|
{
|
|
"slug": "gui",
|
|
"name": "GUI",
|
|
"purposes": [
|
|
{
|
|
"name": "GTK",
|
|
"recommendations": [{
|
|
"name": "gtk4",
|
|
"notes": "Rust bindings to GTK4. These are quite well supported, although you'll often need to use the C documentation."
|
|
}, {
|
|
"name": "relm4",
|
|
"notes": "A higher-level library that sits on top of gtk4-rs"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Web-based GUI",
|
|
"recommendations": [{
|
|
"name": "tauri",
|
|
"notes": "Electron-like web-based UI. Except it uses system webviews rather than shipping chromium, and non-UI code is written in Rust rather than node.js"
|
|
}, {
|
|
"name": "dioxus",
|
|
"notes": "A very nice API layer that has Tauri, Web, and TUI renderers. A native renderer is coming soon."
|
|
}]
|
|
},
|
|
{
|
|
"name": "Immediate Mode Native GUI",
|
|
"recommendations": [{
|
|
"name": "egui",
|
|
"notes": "Immediate-mode UI. Lots of widgets. The most useable out of the box if your needs are simple and you don't need to customise of the look and feel"
|
|
}]
|
|
},
|
|
{
|
|
"name": "Retained Mode Native GUI",
|
|
"recommendations": [{
|
|
"name": "iced",
|
|
"notes": "Retained mode UI with a nice API. It's useable for basic apps, but has a number of missing features including multiple windows, layers, and proper text rendering."
|
|
}, {
|
|
"name": "floem",
|
|
"link": "https://github.com/lapce/floem",
|
|
"notes": "Inspired by Xilem, Leptos and rui, floem is currently more complete than any of them for native UI. Used by the Lapce text editor."
|
|
}, {
|
|
"name": "vizia",
|
|
"link": "https://github.com/vizia/vizia",
|
|
"notes": "Fairly complete with sophisticated layout and text layout, but has yet to make a stable release."
|
|
}],
|
|
"see_also": [{
|
|
"name": "xilem",
|
|
"link": "https://github.com/linebender/xilem",
|
|
"notes": "The replacement for Druid based on the more interoperable Vello and Glazier crates. However, it's currently not complete enough to be usable."
|
|
}, {
|
|
"name": "freya",
|
|
"link": "https://github.com/marc2332/freya",
|
|
"notes": "Dioxus-based GUI framework using Skia for rendering."
|
|
}, {
|
|
"name": "slint",
|
|
"notes": "Possibly the most complete rust-native UI library. But note that it's dual GPL3/commercial licensed."
|
|
}, {
|
|
"name": "druid",
|
|
"notes": "Druid is a relatively mature alternative to Iced/Slint, however it has been discontinued in favour of Xilem so it's use for new projects is discouraged."
|
|
}, {
|
|
"name": "gpui",
|
|
"link": "https://github.com/zed-industries/zed/tree/main/crates/gpui",
|
|
"notes": "High performance framework used in the Zed text editor. Now available on macOS and linux."
|
|
}, {
|
|
"name": "makepad",
|
|
"link": "https://makepad.dev/",
|
|
"notes": "Makepad has a strong focus on performance and minimising bloat but is consequently less feature complete in areas such as accessibility and system integration."
|
|
}, {
|
|
"name": "ribir",
|
|
"link": "https://ribir.org/"
|
|
},
|
|
{ "name": "cushy" },
|
|
{ "name": "rui" },
|
|
{ "name": "concoct" },
|
|
{ "name": "kas" }]
|
|
}, {
|
|
"name": "Window creation",
|
|
"recommendations": [{
|
|
"name": "winit",
|
|
"notes": "The defacto standard option. Uses an event loop based architecture. Widely used and should probably be the default choice."
|
|
}, {
|
|
"name": "tao",
|
|
"notes": "A fork of winit by the Tauri project which adds support for things like system menus that desktop apps need."
|
|
}, {
|
|
"name": "glazier",
|
|
"link": "https://github.com/linebender/glazier",
|
|
"notes": "A new competitor to winit based on the old druid-shell. Has a callback that may be better than the event loop architecture for some tasks. Doesn't yet have a stable release."
|
|
}, {
|
|
"name": "baseview",
|
|
"link": "https://github.com/RustAudio/baseview",
|
|
"notes": "Specialized window creation library targetting windows to be embedded in other applications (e.g. DAW plugins)"
|
|
}]
|
|
}, {
|
|
"name": "2D Renderers",
|
|
"recommendations": [{
|
|
"name": "femtovg",
|
|
"notes": "OpenGL based. Offers a simple API. Probably the easiest to get started with."
|
|
}, {
|
|
"name": "skia-safe",
|
|
"notes": "Bindings to the Skia C++ library. The most complete option with excellent performance. However, it can be difficult to get it to compile."
|
|
}, {
|
|
"name": "vello",
|
|
"link": "https://github.com/linebender/vello",
|
|
"notes": "WGPU based and uses cutting edge techniques to render vector paths using the GPU. Still somewhat immature and hasn't yet put out a stable release."
|
|
}, {
|
|
"name": "vger",
|
|
"notes": "A simpler WGPU based option which is less innovative but currently more stable than vello."
|
|
}, {
|
|
"name": "webrender",
|
|
"notes": "OpenGL based. Mature with production usage in Firefox but documentation and OSS maintenance are lacking."
|
|
}]
|
|
}, {
|
|
"name": "UI layout",
|
|
"recommendations": [{
|
|
"name": "taffy",
|
|
"notes": "Supports Flexbox and CSS Grid algorithms."
|
|
}, {
|
|
"name": "morphorm",
|
|
"notes": "Implements it's own layout algorithm based on Subform layout"
|
|
}]
|
|
}, {
|
|
"name": "Text layout",
|
|
"recommendations": [{
|
|
"name": "cosmic-text",
|
|
"notes": "Full text layout including rich text and support for BiDi and non-latin scripts. The best option for now."
|
|
}, {
|
|
"name": "parley",
|
|
"link": "https://github.com/dfrg/parley",
|
|
"notes": "Another very accomplished text layout library used by Druid/Xilem."
|
|
}]
|
|
}, {
|
|
"name": "Accessibility",
|
|
"recommendations": [{
|
|
"name": "accesskit",
|
|
"notes": "Allows you to export a semantic tree representing your UI to make accessible to screen readers and other assistive technologies"
|
|
}]
|
|
}, {
|
|
"name": "Clipboard",
|
|
"recommendations": [{
|
|
"name": "arboard",
|
|
"notes": "A fork of rust-clipboard that supports copy and pasting of both text and images on Linux (X11/Wayland), MacOS and Windows."
|
|
}]
|
|
}, {
|
|
"name": "File Dialogs",
|
|
"recommendations": [{
|
|
"name": "rfd",
|
|
"notes": "Platform-native open/save file dialogs. Can be used in conjunction with other UI libraries."
|
|
}]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "game-development",
|
|
"name": "Game Development",
|
|
"purposes": [
|
|
{
|
|
"name": "Game Engines",
|
|
"notes": "",
|
|
"recommendations": [{
|
|
"name": "bevy",
|
|
"notes": "An ECS based game engine, good for 3D but also capable of 2D."
|
|
}, {
|
|
"name": "fyrox",
|
|
"notes": "An OOP-focused game engine with 3D and 2D support and a full GUI scene editor."
|
|
}, {
|
|
"name": "ggez",
|
|
"notes": "A simpler option for 2d games only."
|
|
}, {
|
|
"name": "macroquad",
|
|
"notes": "A simple and easy to use 2d game library, great for beginners."
|
|
}]
|
|
},
|
|
{
|
|
"name": "3D Math",
|
|
"recommendations": [{
|
|
"name": "glam",
|
|
"notes": "Fast math library optimised for game development use cases"
|
|
}]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|