Blog

Zyne -- devlog 0

Posted on June 12, 2026

I started a new project called Zyne – a minimal shell written in Zig, with its own syntax ideas.

Why

I wanted to understand how shells work from the ground up – fork, execve, waitpid, raw terminal mode, line editing. Writing it yourself is the only way to really get it.

Also, I had some syntax ideas I haven’t seen elsewhere.

The [] operator

The main syntax idea so far is the [] list operator – it expands a command across multiple arguments:

git [ add . ; commit -m "Update, and add the []"; push ]

expands to:

git add .
git commit -m "Update, and add the []"
git push

Items are separated by ; inside the brackets. The parser builds a cartesian product when multiple [] appear in one command, so things like:

cp [file.txt; backup.txt] /dst/

expand correctly to separate commands. This already works and I used it to make the last two git commits from inside zyne itself.

What’s implemented

  • Interactive loop – prompt, raw mode, flush
  • Raw modetcgetattr / tcsetattr, reads byte by byte
  • Line editing – cursor movement with arrow keys, backspace with correct redraw
  • History – arrow up/down cycles through last 10 commands
  • [] spreading – full parser with cartesian product expansion, nested brackets, quoted strings
  • Command executionfork + execve via std.process.spawn
  • Builtinscd, exit, :q
  • CLI skeletonzn run, zn plugin, zn path, zn help

Stack

  • Zig 0.17-dev – using the new std.Io, std.process.Init, std.process.spawn APIs
  • No libc dependencies, no external libraries
  • Linux for now, macOS support planned

What’s next

  • @ async operator – run commands asynchronously
  • {} block syntax for scripts
  • plugins.conf – declarative plugin list with git and path sources
  • User-friendly path config
  • Customization – prompt, aliases, startup scripts
  • Security settings
  • Tab completion
  • Config file at ~/.config/zyne/

Source: zyne