nix-rust/nix
Rust friendly bindings to *nix APIs
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3w ago
- ✓37+ active contributors
- ✓Distributed ownership (top contributor 21% of recent commits)
Show all 6 evidence items →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/nix-rust/nix)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/nix-rust/nix on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: nix-rust/nix
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/nix-rust/nix shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 3w ago
- 37+ active contributors
- Distributed ownership (top contributor 21% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live nix-rust/nix
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/nix-rust/nix.
What it runs against: a local clone of nix-rust/nix — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in nix-rust/nix | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 51 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of nix-rust/nix. If you don't
# have one yet, run these first:
#
# git clone https://github.com/nix-rust/nix.git
# cd nix
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of nix-rust/nix and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "nix-rust/nix(\\.git)?\\b" \\
&& ok "origin remote is nix-rust/nix" \\
|| miss "origin remote is not nix-rust/nix (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "src/lib.rs" \\
&& ok "src/lib.rs" \\
|| miss "missing critical file: src/lib.rs"
test -f "src/sys/mod.rs" \\
&& ok "src/sys/mod.rs" \\
|| miss "missing critical file: src/sys/mod.rs"
test -f "src/unistd.rs" \\
&& ok "src/unistd.rs" \\
|| miss "missing critical file: src/unistd.rs"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "build.rs" \\
&& ok "build.rs" \\
|| miss "missing critical file: build.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 51 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~21d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/nix-rust/nix"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
nix is a Rust library providing safe, ergonomic bindings to POSIX and Linux system APIs exposed by libc. Instead of unsafe raw FFI calls, it wraps lower-level system functions with type-safe abstractions that enforce legal usage patterns—for example, converting the unsafe gethostname(name: *mut c_char, len: size_t) → c_int into a safe fn gethostname() → Result<OsString>. It covers 40+ subsystems (socket, epoll, ptrace, mount, mqueue, fcntl, pty, sched, etc.) across Linux, macOS, FreeBSD, OpenBSD, and other Unix-like platforms. Modular architecture with src/ split into per-subsystem modules: src/sys/ (aio, epoll, event, eventfd...), src/net/ (socket, network interfaces), src/mount/, src/fcntl.rs, src/pty.rs, src/sched.rs, etc. Each subsystem is optionally feature-gated (e.g., aio requires pin-utils, socket requires memoffset). The crate uses build.rs for platform detection and conditional compilation via cfg-if. Examples are in examples/ (getifaddrs.rs, ptrace.rs). Tests are co-located with source via #[cfg(test)] modules.
👥Who it's for
Systems programmers, network engineers, and library authors building Rust applications that need direct access to *nix kernel APIs (e.g., daemon processes, container tools, embedded systems, low-level networking stacks) without writing unsafe code themselves. Contributors are typically platform-level Rust developers who understand libc semantics and Unix system calls.
🌱Maturity & risk
Production-ready and actively developed. The crate is at version 0.31.2 with MSRV 1.69, published on crates.io with high download volume. CI runs across 15+ Tier 1 and Tier 2 platforms in Cirrus CI. The repository shows active maintenance with structured changelog procedures, contributing guidelines, and release procedures documented. The codebase (~1.6M lines of Rust) indicates substantial maturity and real-world usage.
Low risk for a mature systems library, but platform-specific complexity exists: each Unix variant (Linux, macOS, BSD, Android, iOS) has subtly different syscall signatures and availability, requiring conditional compilation (cfg gates across 40+ feature flags). Dependency footprint is minimal (libc 0.2.183, bitflags, cfg-if, memoffset optional) which is good. The single-maintainer risk is mitigated by the structured contribution and release process documented in CONTRIBUTING.md and RELEASE_PROCEDURE.md. Breaking changes are managed through semantic versioning and changelog discipline.
Active areas of work
The project is actively maintained at v0.31.2 with structured CI/CD (Cirrus CI in .cirrus.yml, GitHub Actions in .github/workflows/). A changelog/ directory with .keep suggests a changelog process (likely towncrier or similar changelog fragment workflow). The repository enforces PR template checks (check_new_changelog.yml action) to ensure all PRs document changes. Recent work appears focused on expanding platform coverage and refining feature-gated APIs across Linux, macOS, and BSD variants.
🚀Get running
git clone https://github.com/nix-rust/nix.git
cd nix
cargo build
cargo test --all-features
cargo run --example getifaddrs
Daily commands:
# Build all features
cargo build --all-features
# Run tests on current platform
cargo test --all-features
# Run a specific example
cargo run --example getifaddrs --all-features
# Check formatting (uses rustfmt.toml)
cargo fmt
# Lint
cargo clippy --all-features
🗺️Map of the codebase
src/lib.rs— Main crate entry point that re-exports all public APIs and defines feature gates; essential for understanding the public surface.src/sys/mod.rs— Core system API module aggregating low-level Unix bindings; foundational to all platform-specific abstractions.src/unistd.rs— Standard POSIX API wrappers (process management, file descriptors, environment); heavily used across the codebase.Cargo.toml— Defines feature flags and MSRV (1.69); critical for understanding platform support and conditional compilation.build.rs— Build script that configures conditional compilation per platform; determines what APIs are available on each target.src/errno.rs— Error handling abstraction wrapping libc errno; used throughout for safe error propagation in FFI calls.CONVENTIONS.md— Documents naming, safety, and API design patterns all contributors must follow.
🛠️How to make changes
Add a new system call wrapper
- Create the FFI binding in the appropriate module under src/sys/ (e.g., src/sys/resource.rs for resource limits) (
src/sys/resource.rs) - Define a safe Rust wrapper function that calls libc::*, handles errno via src/errno.rs, and returns Result<T, Errno> (
src/errno.rs) - Add #[cfg(...)] guards if the syscall is platform-specific (see src/sys/ptrace/linux.rs for example) (
src/sys/ptrace/linux.rs) - Re-export the new function in the parent module's mod.rs (e.g., src/sys/mod.rs) (
src/sys/mod.rs) - Write tests in test/sys/test_*.rs following the pattern in test/common/mod.rs (
test/common/mod.rs) - Document safety requirements and examples in doc comments; reference CONVENTIONS.md for style (
CONVENTIONS.md)
Add a new platform-specific module
- Create a new file under src/ with the module name (e.g., src/myfeature.rs) (
src/lib.rs) - Add platform guards in the new file: #[cfg(target_os = "linux")] or similar (
src/mount/linux.rs) - Add a feature flag in Cargo.toml and conditionally gate the module in src/lib.rs (
Cargo.toml) - Update build.rs if compile-time detection is needed beyond Cargo features (
build.rs) - Create corresponding test file in test/ with conditional compilation matching the feature (
test/sys/test_inotify.rs)
Ensure safe FFI pattern
- Wrap all libc calls with explicit error checking; return Result<T, Errno> from errno.rs (
src/errno.rs) - Use newtypes (e.g., Pid, Uid) to prevent accidental type confusion; see src/unistd.rs for examples (
src/unistd.rs) - Document SAFETY requirements and invariants in /// Safety: doc comments per CONVENTIONS.md (
CONVENTIONS.md) - Test both success and error paths; use test/common/mod.rs utilities for process management in tests (
test/common/mod.rs)
🔧Why these technologies
- Rust + libc crate — Provides memory safety guarantees around inherently unsafe FFI bindings; newtypes and Result enforce correct usage patterns.
- Conditional compilation (#[cfg]) — Different Unix variants (Linux, BSD, macOS) have divergent syscall sets; compile-time gates ensure only valid APIs are exposed per platform.
- Newtype pattern (Pid, Uid, Errno) — Prevents type confusion (e.g., mistaking Uid for Gid); adds semantic clarity and zero-cost type safety.
- Result<T, Errno> error model — Recovers errno from libc calls safely and forces callers to handle errors; avoids silent failures common in C.
⚖️Trade-offs already made
-
No 100% unified cross-platform API; platform-specific submodules allowed
- Why: Unix variants differ significantly; forcing a uniform API would either omit features or require expensive adapters.
- Consequence: Users must write platform-conditional code for some features; benefits from idiomatic platform access outweigh uniformity cost.
-
Thin wrapper model (minimal abstraction over libc)
- Why: libc is already stable and well-tested; adding heavy abstractions risks both duplication and performance overhead.
- Consequence: API closely mirrors C; users must understand underlying syscalls but gain familiarity and predictability.
-
Require MSRV 1.69 for stable feature support
- Why: Allows use of modern Rust idioms (e.g., const fns, derive_const) without supporting ancient compiler versions.
- Consequence: Excludes projects on older Rust versions; enables cleaner, more maintainable code.
🚫Non-goals (don't propose these)
- Does not provide a portable abstraction hiding platform differences; see README 'unify what can be while still providing platform specific APIs'
- Does not implement high-level concurrency primitives (e.g., async/await); focuses on low-level syscall bindings
- Not a general-purpose networking library; socket APIs are low-level wrappers, not client/server frameworks
- Does not handle Windows APIs; scope strictly limited to POSIX-like Unix systems
🪤Traps & gotchas
Feature gate interdependencies: Some features depend on others (e.g., dir requires fs, socket requires memoffset, aio requires pin-utils). Building without required features will fail at compile time. Platform-specific failures: Tests pass on Tier 1 platforms but may fail on Tier 2/3; always test locally on your target. Unsafe blocks: All FFI calls in src/sys/ are unsafe; incorrect argument passing can cause UB. Always read the man pages for the wrapped syscall. Changelog requirement: PRs without a changelog fragment in changelog/ are blocked by CI (check_new_changelog.yml action). MSRV: Rust 1.69 minimum; code must remain compatible with that version. libc version coupling: pinned to 0.2.183; newer libc versions may change type definitions and require auditing.
🏗️Architecture
💡Concepts to learn
- errno and Error Wrapping — Understanding how nix converts C errno codes into Rust Result types is essential for writing safe error-handling code; src/errno.rs is the core of this pattern
- FFI (Foreign Function Interface) and Safety Invariants — Every binding in src/sys/ is an unsafe block wrapping libc calls; you must understand when it's safe to call each syscall and what pre/post-conditions exist
- Feature Gates and Conditional Compilation — nix uses 40+ Cargo features (aio, socket, ptrace, etc.) to control which syscalls are compiled in; understanding cfg attributes is required to navigate the codebase
- POSIX and Linux Syscall Semantics — Every function in src/sys/ maps to a specific man7.org syscall; you must understand the underlying kernel API semantics to use nix correctly and spot safety issues
- Platform Abstraction (Linux vs BSD vs macOS Divergence) — The mount/ and net/ submodules show how nix handles APIs that differ significantly across Unix variants (e.g., mount flags, ioctl codes); critical for cross-platform development
- Lifetime and Ownership in Rust Wrappers — Many nix types (Fd, Pid) encode invariants about resource lifetime; understanding when a syscall result can be dropped or mutated is essential to avoid double-free or use-after-close bugs
- Zero-Copy Abstractions (bitflags, wrapper newtypes) — nix avoids allocations by using bitflags enums and newtype wrappers (e.g., Fd(i32)) that compile to no-ops; understanding this pattern is key to nix's performance guarantees
🔗Related repos
rust-lang/libc— Upstream raw FFI definitions; nix wraps this crate's unsafe bindings with safe abstractionstokio-rs/tokio— Async runtime that uses nix-style safe wrappers for syscalls internally; nix is a lower-level complement for synchronous or custom-async codesfackler/rust-openssl— Similar safety-wrapper pattern applied to OpenSSL FFI; demonstrates how to safely bind C libraries from RustDioxusLabs/dioxus— Example major Rust project that uses nix bindings for platform-level operations (PTY, process spawning)containerd/rust-libcontainer— Heavy user of nix for container runtime syscalls (mount, cgroups, namespaces); real-world production usage pattern
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for src/sys/ioctl/ platform-specific implementations
The ioctl module has platform-specific implementations (bsd.rs, linux.rs, mod.rs) but lacks dedicated integration tests. Given that ioctl is a notoriously platform-specific API with many subtle differences between Linux and BSD variants, adding tests would significantly improve reliability. This is especially valuable since the module is exposed publicly and used by downstream crates.
- [ ] Create tests/sys_ioctl.rs with platform-conditional tests using #[cfg(target_os = "...")] for Linux and BSD-specific ioctl operations
- [ ] Add tests for common ioctl patterns (terminal control, device manipulation) that work across platforms where applicable
- [ ] Reference the existing examples/getifaddrs.rs pattern to ensure tests compile and run on CI via Cirrus
- [ ] Add tests that validate error handling for invalid ioctl calls and verify errno is set correctly
Add missing tests for src/sys/ptrace/ across all supported platforms
The ptrace module has separate implementations for Linux (linux.rs) and BSD (bsd.rs), but there are no dedicated integration tests in the test suite. Given that ptrace is critical for debugging tools and has significant platform differences, comprehensive tests would catch regressions early. The examples/ptrace.rs exists but is not a test suite.
- [ ] Create tests/sys_ptrace.rs with conditional platform-specific tests using #[cfg(all(test, target_os = "..."))]
- [ ] Add tests for core ptrace operations (PTRACE_ATTACH, PTRACE_DETACH, PTRACE_CONT) with proper process cleanup
- [ ] Test BSD-specific ptrace variants (e.g., PT_ATTACH vs PTRACE_ATTACH differences) separately from Linux tests
- [ ] Ensure tests handle permission requirements and skip gracefully on systems where ptrace is restricted
Implement missing socket feature flag bindings for src/net/if_.rs address filtering
The src/net/if_.rs module provides interface enumeration but the CONTRIBUTING.md and feature matrix suggest socket-related address filtering operations lack proper feature-gating. Cross-referencing with the feature list, there's room to add conditional bindings for advanced socket filtering (SO_REUSEADDR, SO_REUSEPORT variants) that are platform-specific and currently missing explicit wrappers.
- [ ] Review libc definitions in net/if_.rs and identify missing socket option constants (e.g., SO_REUSEPORT for platforms that support it)
- [ ] Add new feature gates in Cargo.toml for advanced network features (e.g., "net_advanced_socket_opts") if needed
- [ ] Create wrappers in src/net/if_.rs or src/sys/socket.rs for platform-conditional socket options with proper cfg attributes
- [ ] Add integration tests in tests/net.rs validating socket option setting on supported platforms
🌿Good first issues
- Add missing documentation tests for examples/ (getifaddrs.rs, ptrace.rs) demonstrating real use cases. Currently they run but lack doc comments explaining syscall purpose and safety notes.: Improves onboarding and ensures examples compile in CI
- Expand platform-specific coverage in src/mount/: currently has mount/linux.rs, mount/apple.rs, mount/bsd_without_apple.rs. Add conditional module tests or docs clarifying which mount flags are supported on which platforms.: Prevents user confusion about API availability on their target OS
- Review src/sys/event.rs (kqueue/epoll) and add feature interaction tests confirming that event and poll features compose correctly (e.g., polling an event fd). Currently feature tests are sparse.: Validates feature flag combinations don't break at runtime on real systems
⭐Top contributors
Click to expand
Top contributors
- @SteveLauC — 21 commits
- @asomers — 12 commits
- @devnexen — 12 commits
- @xtqqczze — 9 commits
- @3v1n0 — 4 commits
📝Recent commits
Click to expand
Recent commits
69c0505— doc: add documentation and examples for SigHandler and SigAction (#2755) (Moayad717)d32aad9— fix(ci): temporarily disable armv7-unknown-linux-uclibceabihf (#2764) (xtqqczze)8c393dc— ci: update FreeBSD image to 14.4 (#2757) (xtqqczze)7204bd8— Revert "fix(ci): add pkg installation for ca_root_nss in FreeBSD 14 setup (#2756)" (#2761) (xtqqczze)e9c43d0— fix(ci): add pkg installation for ca_root_nss in FreeBSD 14 setup (#2756) (xtqqczze)8dff4e7— unistd: remove gate from mkfifo (#2749) (cakebaker)46c2e6d— time: Add netbsdlike support for several ClockID constants (#2716) (xtqqczze)84f922b— chore(ci): upgrade macOS runner to 26 (#2753) (xtqqczze)962d80c— ioctl: add support for cygwin (#2715) (500-internal-server-error)0708c8c— fix: sys::signal::SaFlags_t definition on redox (#2751) (xtqqczze)
🔒Security observations
The nix crate demonstrates good security practices as a systems library with safe wrappers around unsafe FFI bindings. No critical vulnerabilities were identified. Primary concerns are: (1) dependency management with pinned versions requiring regular updates, (2) need for enhanced documentation of safety invariants in unsafe code, particularly for powerful features like ptrace, and (3) missing MSRV enforcement in CI. The codebase follows Rust safety principles and appropriately uses unsafe abstractions for low-level system calls. As a foundational library, maintaining rigorous unsafe code review and security updates is essential.
- Medium · Outdated libc Dependency with Known Vulnerabilities —
Cargo.toml - libc = { version = "0.2.183", features = ["extra_traits"] }. The libc dependency version 0.2.183 is pinned to a specific version. While libc is actively maintained, using pinned versions without regular updates can lead to exposure to known vulnerabilities. The project should implement a regular dependency update schedule. Fix: Implement automated dependency scanning using tools like cargo-audit or dependabot. Consider using version ranges (e.g., "0.2") to receive patch updates automatically while maintaining compatibility. - Low · Broad Feature Exposure in Documentation Build —
Cargo.toml - [package.metadata.docs.rs] with all-features = true. The docs.rs configuration enables all features for documentation builds, which exposes platform-specific and potentially sensitive API bindings in public documentation. This includes low-level system calls and ptrace functionality that could be misused. Fix: Consider selectively enabling only stable, widely-used features for documentation. Document security implications of low-level features like ptrace and provide usage guidelines. - Low · Unsafe FFI Bindings Without Explicit Documentation —
src/ directory - Multiple files containing unsafe FFI calls. As a *nix bindings library, this crate wraps unsafe libc calls. While the README indicates safe wrappers are provided, the extensive use of system calls (ptrace, socket operations, mount, etc.) requires careful validation of unsafe code boundaries. Fix: Ensure all unsafe blocks have comprehensive documentation explaining safety invariants. Conduct regular audits of unsafe code sections, particularly in ptrace (src/sys/ptrace/), socket (src/sys/socket/), and mount modules. - Low · Missing MSRV Update Enforcement —
Cargo.toml and .github/workflows/. The project specifies rust-version = "1.69" in Cargo.toml, but there is no CI enforcement visible to prevent merging code that breaks MSRV compatibility. Fix: Add CI checks to verify MSRV compliance (e.g., cargo +1.69 check) and ensure this runs on all pull requests.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.