xeq
Run sequences of shell commands with a single word.
Define your commands once in a TOML file. Run them from anywhere, on any OS, without rewriting them every time.
Table of Contents
- Why xeq?
- Installation
- Quick Start
- Commands
- TOML File Format
- Features
- How It Works
- Examples
- Roadmap
- Contributing
- License
Why xeq?
Every project has a setup ritual — install dependencies, build, run tests, configure things. You either memorize the steps, paste them from a notes file, or write a shell script that only works on your machine.
xeq gives you a better option. Write your commands in a xeq.toml file, commit it to your repo, and anyone on the team can run the exact same steps with one command — on Linux, macOS, or Windows.
Installation
macOS / Linux
|
Windows (PowerShell)
iwr https://raw.githubusercontent.com/opmr0/xeq/main/install.ps1 -UseBasicParsing | iex
Via cargo
Quick Start
1. Create a xeq.toml in your project:
[]
= [
"npm install",
"npm run build"
]
[]
= ["npm run dev"]
2. Tell xeq where the file is (one time only):
3. Run any script by name:
That's it. xeq remembers the file path — you don't need to pass it every time.
Commands
xeq config [path]
Point xeq at your TOML file. This is saved globally so you only need to do it once per project (or when you move the file).
xeq run <script> [flags]
Run a script from your TOML file. Commands in the script run one at a time in order. If a command fails, xeq stops — unless you use --continue-on-err.
Available flags:
| Flag | Short | Description |
|---|---|---|
--continue-on-err |
-C |
Keep going even if a command fails |
--quiet |
-q |
Hide xeq's own log messages, only show command output |
--clear |
-c |
Clear the terminal before each command |
--parallel |
-p |
Run all commands at the same time instead of one by one |
--allow-recursion |
Let a script call itself (disabled by default to prevent infinite loops) | |
--args <values...> |
-a |
Pass arguments into the script |
--global |
-g |
Use the globally saved path instead of the local xeq.toml |
xeq init
Generate a starter xeq.toml in the current directory:
This creates a xeq.toml with a sample script to get you started. If a xeq.toml already exists, xeq will not overwrite it.
xeq list
Show all scripts in your TOML file along with their commands and options.
build runs: --- options: ["quiet", "parallel"]
cargo fmt
cargo clippy
cargo build --release
TOML File Format
A xeq.toml file is a list of named scripts. Each script has a run array of shell commands:
[]
= ["quiet"]
= "A simple description"
= [
"command one",
"command two",
"command three"
]
Scripts are case-sensitive. You can define as many as you want in a single file.
descriptions felid doesn't affect the script, it just appear in xeq list
Features
Script Options
Scripts can have default options baked in, so you don't have to pass flags every time. Add an options array to any script:
[]
= ["quiet", "parallel"]
= ["cargo build", "cargo test"]
Now xeq run build always runs quietly and in parallel — no flags needed.
Available options: quiet, clear, parallel, continue_on_err, allow_recursion
Note: Invalid options will cause a parse error before any commands run.
Toggling: CLI flags toggle options. If quiet is set in TOML and you pass --quiet on the CLI, it turns quiet off for that run. This lets you override script defaults without editing the file.
Nested Scripts
Call other scripts from within a script using the xeq:// prefix:
[]
= ["npm install"]
[]
= ["npm run build"]
[]
= [
"xeq://install", # runs the install script first
"xeq://build", # then the build script
"npm run deploy" # then this command
]
Running xeq run deploy automatically runs install and build first.
Circular dependency protection: xeq tracks which scripts are currently running. If a script tries to call itself (directly or through a chain), xeq exits with an error. Pass
--allow-recursionor add it tooptionsif you intentionally want recursive behavior.
Local Configuration
xeq automatically looks for a xeq.toml in the current directory. If none is found, it falls back to the globally saved path.
To always use the global path, pass -g / --global:
Arguments
Reference arguments in commands using {{1}}, {{2}}, etc., then pass them with --args:
[]
= [
"npm create vite@latest {{1}} -- --template react",
"cd {{1}}",
"npm install"
]
This creates a new Vite project called my-app, changes into it, and installs dependencies.
If a script uses
{{placeholders}}but no--argsare provided, xeq exits with an error instead of passing the raw placeholder to the shell.
Parallel Execution
Run all commands in a script simultaneously instead of one by one:
[]
= ["parallel"]
= [
"cargo test",
"cargo clippy",
"cargo fmt --check"
]
Note: In parallel mode,
cdcommands andxeq://calls are skipped — only plain shell commands are spawned as parallel threads.
How It Works
- xeq stores your TOML file path globally using the system config directory
- Commands run through
sh -con Linux/macOS andcmd /Con Windows cdcommands update the working directory for all subsequent commands in that script- On failure, xeq exits with the same exit code as the failed command
- Script names are case-sensitive:
Buildandbuildare different scripts
Examples
The examples/ folder has ready-to-use TOML files for common workflows:
| File | What it does |
|---|---|
react-tailwind.toml |
Scaffold a React + Tailwind CSS project |
nextjs.toml |
Set up a Next.js project with TypeScript |
rust-project.toml |
Format, lint, test, and release a Rust project |
docker-app.toml |
Start, stop, rebuild, and tail logs for Docker Compose |
git-workflow.toml |
Sync, push, and stash/pop git operations |
scripts-nesting.toml |
Example of calling scripts from within scripts |
Contributing
Contributions are welcome — whether it's a bug fix, a new feature, or an improvement to the docs Open an issue.
Getting started:
Before submitting a PR:
- Run
cargo fmtto format your code - Run
cargo clippyand fix any warnings - Run
cargo testand make sure all tests pass - If you're adding a new feature, add tests for it
Project structure:
src/
main.rs # CLI parsing and command dispatch
config.rs # Path saving/loading and TOML reading
runner.rs # Script execution logic
types.rs # Shared types (Script, Scripts, SavedPath)
macros.rs # log! and err! macros
examples/ # Ready-to-use TOML files
If you're unsure whether a change fits the project, open an issue first to discuss it before writing code.
License
MIT — LICENSE