ReviewOS

den-shell/den

public
Clone

Push over the same URL. A password will not work: create a token under access tokens and use it in place of one.

main
· 2 branches · 599 commits

Mirrored from den-shell/den · syncing is switched off

README.md

Den Shell

A modern, POSIX-compliant shell written in Zig — a rich built-in feature set, a single self-contained binary, and memory safety.

Den combines the familiarity of traditional shells with a modern, batteries-included interactive experience. It was originally prototyped in TypeScript/Bun and rewritten in Zig for native code and a self-contained binary.

  • Instant startup — ~4–5 ms cold start; native code, no runtime or VM
  • 📦 Self-contained — a ~1.3 MB binary (on par with bash/zsh) that links only libc — fewer dynamic deps than either
  • 🛡️ Memory safe — Zig's compile-time safety prevents whole classes of bugs
  • 🎯 Feature rich — 58 builtins, job control, history, completion, expansion, and a full line editor — no plugin manager required
  • 🧩 Extensible — WASM plugins, AI-assisted completions, distributed sessions, an LSP server
  • Compatible — POSIX-compliant with a zsh compatibility layer and a bash migration path

📖 Full documentation lives in ./docs — every feature below links to its dedicated page.

Table of Contents

Why Den

Den's draw is what's built in — completion, autosuggestions, syntax highlighting, a git prompt, and a zsh-style feature set with no plugin manager — plus a single self-contained binary and a memory-safe implementation. On raw micro-benchmarks it's competitive with, not dramatically faster than, established shells.

Performance

Measured on an Apple M3 Pro (macOS, arm64) with hyperfine, against the system bash 3.2 and zsh 5.9. Den is the default ReleaseSmall build. These are real numbers from one machine — reproduce them with scripts/bench.sh comparison.

MetricDenBash 3.2Zsh 5.9
Startup, -c true3.9 ms1.3 ms2.1 ms
Command exec (per external cmd)~2.0 ms~1.8 ms~2.0 ms
Idle memory (clean config)4.6 MB2.4 MB2.3 MB
Binary size1.33 MB1.29 MB1.36 MB
Dynamic libraries1 (libc)24

Honest read: Den's binary is now on par with bash/zsh (1.33 MB) and links the fewest libraries. It starts in a few milliseconds (instant in practice) though still a touch behind bash/zsh, and uses somewhat more idle memory — the cost of a much richer built-in experience and memory safety. Further startup/footprint work is on the roadmap.

The engineering behind Den's hot paths is documented in depth:

Quick Start

# Build Den (see Installation for prebuilt binaries / package managers)
zig build -Doptimize=ReleaseSmall

# Start an interactive shell
./zig-out/bin/den

# Run a script
./zig-out/bin/den script.sh

# Run a single command
./zig-out/bin/den -c 'echo "Hello from Den!"'

A first interactive session:

➜  echo "Hello, World!"
Hello, World!

➜  export MY_VAR="test"
➜  echo $MY_VAR
test

➜  ls -la | grep zig
-rw-r--r--  1 user  staff  42627 build.zig
drwxr-xr-x  3 user  staff     96 zig-out

New to Den? Start with the Introduction and the Quick Reference cheat sheet.

Installation

# Homebrew (macOS / Linux)
brew install stacksjs/tap/den

# Install script (downloads the latest release binary)
curl -fsSL https://raw.githubusercontent.com/stacksjs/den/main/scripts/install.sh | bash

# From source
zig build -Doptimize=ReleaseSmall && zig build install --prefix ~/.local

Distribution packages are provided for Debian/Ubuntu (.deb), Fedora/RHEL (.rpm), Arch (PKGBUILD), and Nix (packaging/). To make Den your login shell, add it to /etc/shells and run chsh. Full details — prebuilt binaries, package managers, and login-shell setup — are in the Installation guide.

Already installed? Run den upgrade to install the latest verified GitHub release.

Configuration

Den reads two files at startup:

  • ~/.denrc — a shell script sourced on startup (like .zshrc): set environment, $PATH, aliases, and run commands.
  • ~/.config/den.jsonc — declarative JSONC config for the prompt, history, completion, theme, aliases, and keybindings. A fully-commented example lives at den.jsonc.

Everything you can configure — prompt format, history behaviour, completion, colours/symbols, and keybindings — is documented in the Configuration reference. Prompt styling has its own deep-dive in Themes.

Features

Core Shell

FeatureDescription
PipelinesMulti-stage cmd1 | cmd2 | cmd3
I/O redirection>, >>, <, 2>, 2>&1, here-docs, here-strings
Boolean operatorsShort-circuit && and ||
Command chainingSequential ; lists
Background jobs&, jobs, fg, bg, wait, disown
Subshells & grouping( … ) and { …; }

Expansion

FeatureDescription
Variable expansion$VAR, ${VAR}, ${VAR:-default}, ${#VAR}, ${VAR#prefix}, special vars ($?, $$, $!, $_, $0$9, $@, $*, $#)
Command substitution$(command) (and backticks)
Arithmetic$(( expr )) with + - * / % **
Brace expansion{1..10}, {a..z}, {foo,bar,baz}
Tilde expansion~, ~/path, ~user
Glob expansion*.zig, **/*.txt, plus zsh glob qualifiers

Interactive Experience

FeatureDescription
Line editorEmacs & Vi keymaps, word motions, kill-ring, multi-line editing
Inline autosuggestionsfish-style suggestions from history as you type
Syntax highlightingLive command highlighting in the prompt
Persistent historyShared, de-duplicated, configurable history file
History substring searchUp/Down filters history by what you've typed
Prompt & themesTwo-line prompt, git status, runtime modules, colours/symbols

Completion

FeatureDescription
Tab completionCommands, files, options, and a navigable grid menu (arrow keys move by row/column)
Mid-word completionExpand abbreviated paths like /u/l/b/usr/local/bin
Git completionBranches, remotes, files, and subcommands for git
Context-aware completionPer-command argument/flag completion (npm, bun, docker, …)

Built-in Commands

Den ships 58 built-in commands. The complete reference — flags, behaviour, and examples for each — is in Builtins (run help inside Den for a quick summary).

  • Core: exit, help, true, false
  • File system: cd, pwd, pushd, popd, dirs, realpath
  • Environment: env, export, set, unset
  • Introspection: alias, unalias, type, which
  • Job control: jobs, fg, bg, kill, wait, disown
  • History & completion: history, complete
  • Scripting: source/., read, test/[, eval, shift, command, return, break, continue, local, declare, readonly, getopts
  • Path utilities: basename, dirname
  • Output: echo, printf
  • System: time, sleep, umask, hash, clear, uname, whoami, times
  • Advanced execution: exec, builtin, trap
  • zsh & extended: setopt, unsetopt, ai, wasm

Den also provides fast built-in implementations of common coreutils (grep, ls, find, date, seq, base64, tree, …). When invoked with options the builtin doesn't implement, Den transparently falls back to the real tool on $PATH, so advanced usage always works.

Scripting

Full POSIX scripting — if/then/else, for, while, until, case, and functions — plus here-documents and traps. See the Scripting guide.

#!/usr/bin/env den

export PROJECT="my-app"

if test -f README.md; then
  echo "$PROJECT: README present"
fi

for file in *.zig; do
  echo "compiling $(basename "$file")"
done

greet() { echo "hello, $1"; }
greet world

Extended Capabilities

FeatureDescription
zsh compatibilitysetopt/unsetopt, %-prompt escapes, glob qualifiers, arrays, associative arrays, named directories, auto-cd
WASM pluginswasm <module.wasm> <export> [args] via a built-in interpreter; write your own
AI-assisted completionsai <describe a command> (OpenAI/Anthropic-compatible)
Distributed sessionsden --serve / den --connect (loopback-only by default)
Language Serverden --lsp for editor integration

Compatibility & Migration

Documentation

Everything is under ./docs. Highlights by audience:

Get started

Use Den

Migrate

Performance

Develop & extend

Building from Source

Requirements: Zig 0.17-dev or later; macOS, Linux, or BSD (Windows support planned).

zig build                            # debug build
zig build -Doptimize=ReleaseSmall    # release build (~1.3MB, stripped — the default)
zig build -Doptimize=ReleaseFast     # release tuned for max speed (larger)
zig build install --prefix ~/.local  # install
zig build test                       # run the test suite

Release builds are stripped automatically; pass -Dstrip=false to keep symbols.

See Architecture for the source layout and Testing for the test framework. The full feature roadmap is in ROADMAP.md.

Contributing

Contributions are welcome! Please read the Contributing guide to get started.

License

MIT License — see LICENSE.

Made with 💙 by the Stacks team.

Community