duct

Run child processes and shell-like pipelines in Rust, correctly and portably

Library
Cargo
v1.1.1
1,039stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
33/100Needs Attention
Development Activity0
Maintenance0
Community44
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture86
Code Quality86
Innovation74
Learning Curve84

duct is a Rust library for running child processes. It makes it easy to build pipelines and redirect IO like a shell, while helping you write correct, portable code: whitespace is never significant, errors from child processes are reported by default, and a long list of cross-platform gotchas and bugs are handled for you the right way.

With a concise cmd! macro you can run commands, capture their output as a String, chain them into pipelines, redirect stdin/stdout/stderr, set environment variables, and stream output incrementally through a reader. duct mirrors the design of its well-known Python sibling and is widely used for scripting-style automation in Rust.

What You Get

  • A cmd! macro for building commands from a program and its arguments
  • Pipeline construction via .pipe() that connects one command’s output to another’s input
  • IO redirection helpers: capture, stdin/stdout/stderr redirection, and stderr-to-stdout merging
  • Incremental output streaming through a Reader implementing std::io::Read
  • Default error checking so non-zero exit codes surface as Rust errors

Common Use Cases

  • Scripting and build automation that shells out to external tools
  • Composing multi-stage command pipelines in a portable way
  • Capturing or streaming a subprocess’s output for further processing
  • Replacing fragile std::process::Command boilerplate with concise, correct code

Under The Hood

Architecture - The core lives in src/lib.rs, which models an Expression tree: leaf cmd! nodes and combinators (pipe, redirections, env changes) compose into an immutable expression that is executed lazily by run, read, start, or reader. Platform-specific process handling is isolated in unix.rs and other modules, and env_name_str.rs normalizes environment-variable name casing across platforms. A companion duct_sh crate adds shell-string parsing.

Tech Stack - Pure Rust over the standard library’s process and IO facilities, licensed MIT. It uses shared_child and os_pipe (from the same author) to manage child processes and pipes safely across Unix and Windows, and includes an extensive test module in src/test.rs.

Code Quality - duct is a mature, popular crate (over a thousand GitHub stars) backed by a detailed gotchas document shared with its Python counterpart, showing deliberate attention to correctness. It carries a thorough test suite and encodes fixes for many subtle process and IO edge cases so users don’t have to rediscover them.

API Design - The API is deliberately expression-oriented and immutable: you build a description of what to run, then choose how to execute it. The cmd! macro keeps call sites terse, method chaining reads like a pipeline, and safe defaults (error-on-failure, no shell word-splitting) make the easy path the correct one.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search