Skip to content

isene/bare

Repository files navigation

bare - Pure Assembly Shell

Version Assembly License Platform Dependencies Binary Startup Stay Amazing

Interactive shell written in x86_64 Linux assembly. No libc, no runtime, pure syscalls. Single static binary, 126KB. 9 microsecond startup.

Pure syscalls, zero overhead. No interpreter, no runtime, no garbage collector. Just your keystrokes and the kernel.

This is my login shell. It is not released for your use. It is released for inspiration. This is how you can benefit: 1) Clone this repo, 2) Fire up Claude Code, 3) Prompt it to make it into what you want or need.


bare in glass under tile

bare behind every > in the CHasm desktop. Every binary on screen is x86_64 assembly — tile owns the layout, strip drives the status row, glass renders the terminals, show paints the syntax-highlighted source, bare is the shell.

Install

From source (requires nasm and ld)

git clone https://github.com/isene/bare.git
cd bare
make
sudo make install

Arch Linux (AUR)

yay -S bare-shell

Debian/Ubuntu

curl -LO https://github.com/isene/bare/releases/latest/download/bare_0.2.21-1_amd64.deb
sudo dpkg -i bare_0.2.21-1_amd64.deb

Set as default shell

# Add to allowed shells
sudo sh -c 'echo /usr/local/bin/bare >> /etc/shells'

# Set as default terminal shell (wezterm)
# In ~/.config/wezterm/wezterm.lua:
config.default_prog = { '/usr/local/bin/bare', '-l' }

Setup

# Install AI plugins (optional, needs Anthropic API key)
make install-plugins

# Create login profile
cat > ~/.bare_profile << 'EOF'
export PATH=/usr/local/bin:/usr/bin:/bin:$HOME/bin:$HOME/.local/bin
export EDITOR=vim
export PAGER=less
EOF

Benchmark

Two numbers worth quoting separately, since "shell startup" can mean different things and the smaller number tells you nothing about the bigger one.

Interactive prologue — cost from execve to "ready to handle the first keystroke" with all interactive features (history, tab completion, syntax-highlighted prompt) initialised lazily on the path that actually needs them:

$ ./bare --bench
bare startup: 9 microseconds

Non-interactive whole-process — cost of echo cmd | bare > /dev/null, i.e. spawn shell, parse one line, fork-exec the command, wait, exit. This is the right number for bare as a script interpreter or pipe target. Both shells running on the same machine, 1000 iterations:

shell echo true | shell echo ls | shell syscalls/invocation
bash 2.5s 4.5s 26
bare 2.1s 4.5s 14

Bare wins the minimal benchmark (~17% faster) and ties on the realistic one where the spawned command's own work dominates. Half the syscalls per invocation, no dynamic linker, no .bashrc parse.

Both numbers reflect the same binary; bare detects isatty(0) at startup and gates history loading, PATH exec-cache build, and prompt-state init behind it. Without that gate, the bench-vs-real gap was ~2 orders of magnitude (h/t @romforth and @Corbin on lobste.rs for prodding).

Features

Prompt and Navigation

  • Dynamic prompt: user@host: ~/cwd/ (git-branch) > with configurable colors
  • Git dirty indicator: green dot (clean) / red dot (uncommitted changes)
  • Git branch display (toggleable via show_git_branch)
  • Root user detection: separate colors for sudo sessions
  • Bookmarks with tags (:bm name [path] [#tags]), tag search (:bm ?tag)
  • Auto-cd from bookmark names and bare directory names
  • Directory history (:dirs), cd N to jump, cd - for previous
  • pushd/popd directory stack
  • Pointer/RTFM file manager auto-cd on exit

Command Execution

  • Multi-pipe (up to 16 segments): cmd1 | cmd2 | cmd3
  • Redirections: >, >>, <
  • Command chaining: ;, &&, ||
  • Command substitution: $(cmd) with nesting
  • Background execution: &
  • Per-command env prefix: VAR=val [VAR2=val2 ...] cmd args (POSIX-style temporary env)
  • time builtin: time sleep 1 shows elapsed with ms precision
  • Login shell (-l), command mode (-c "cmd")
  • Foreground job control with proper setpgid + tcsetpgrp so signals reach the job

Expansion

  • Brace expansion: file.{txt,md,rs} -> file.txt file.md file.rs
  • Tilde, variable ($VAR, ${VAR}, $?, $$), glob (*, ?, [a-z], [!x])
  • History expansion: !!, !N, !-N
  • Global nick expansion anywhere in line

Aliases and Abbreviations

  • :nick ls = ls --color -F (expand at execution, self-referencing works)
  • :gnick G = | grep (expand anywhere in line)
  • :abbrev gst = git status (expand live on space)
  • NAME? (e.g. s?, show?, gs?, home?, :nick?) — inline help: prints what the name resolves to (nick / gnick / abbrev / bookmark / builtin / exe). If a name matches several categories, every match is printed so shadowing is visible.

Line Editing and Completion

  • Interactive tab cycling with LS_COLORS (dirs blue, symlinks gray)
  • Tab completion list rendered visibly below the prompt (no overwrite)
  • Tab completion for :commands (:th<TAB> -> :theme)
  • $VAR tab completion, subcommand completion (git, apt, cargo)
  • Bare path to a non-executable file (e.g. notes.md) auto-opens in $EDITOR
  • Ctrl-R reverse incremental history search
  • Inline history suggestions (grayed preview, right-arrow to accept)
  • Prefix history search: type text, press Up/Down to filter
  • Alt-F / Alt-B: word movement forward/backward
  • Ctrl-G edit in $EDITOR, Ctrl-Y copy to clipboard, Ctrl-X delete current history entry (browse via Up, or whichever entry the inline suggestion came from)
  • Syntax highlighting: valid commands (green), nicks (cyan), colon commands, switches
  • Multi-line editing: continuation on \, |, &&, ||, unclosed quotes
  • Auto-pairing brackets and quotes (configurable)

Job Control

  • Ctrl-Z suspend, :jobs, :fg [N], :bg [N]

Themes and Colors

  • 6 themes: default, solarized, dracula, gruvbox, nord, monokai
  • 18 individual color settings including root-specific colors
  • Companion TUI configurator: bareconf

Configuration

  • ~/.barerc: auto-saved on exit, line-based key=value format (multi-terminal safe)
  • ~/.bare_profile: login profile (simple export lines)
  • ~/.bare_history: capped at 1000 entries, smart deduplication
  • Runtime changes: :config key value
  • Toggles: show_tips, auto_correct, auto_pair, rprompt, show_git_branch, completion_fuzzy

Plugins

Plugins are executables in ~/.bare/plugins/. Any unknown colon command runs the matching plugin.

make install-plugins    # installs :ask and :suggest (AI via Anthropic API)
  • :ask <question> - ask AI a question
  • :suggest <task> - get a shell command suggestion

See plugins/README.md for setup and writing your own.

Other Builtins

  • cd, pwd, exit, export, unset, history, pushd, popd, time
  • :calc, :stats, :validate, :save_session, :load_session
  • :save, :backup [name], :restore [name] (config/history snapshots)
  • :env, :rehash, :reload, :rmhistory, :info, :version, :help
  • Auto-correct suggestions on command not found
  • Startup tips (configurable)

Part of CHasm (CHange to ASM)

The same shell, three languages:

Shell Language Startup Suite
bare x86_64 Assembly 9us CHasm
rush Rust ~26ms Fe2O3
rsh Ruby ~300ms

Companion: bareconf (TUI configurator, built on crust)

License

Unlicense - public domain.

Credits

Created by Geir Isene (https://isene.org) with extensive pair-programming with Claude Code.

About

Interactive shell in x86_64 Linux assembly. No libc, no runtime, pure syscalls.

Resources

License

Stars

44 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages