vlsh is an interactive Unix shell written in V — simple, fast, and hackable, with a clean codebase you can read, modify, and extend.
Features
vlsh ships with the fundamentals done right, then gets out of your way.
Built with V, vlsh compiles to a lean native binary. Cold start is near-instant — no interpreter overhead on every keystroke.
Pipelines (|), file redirection (>, >>, <), and 2>&1 when stdout is captured — plus &&, ||, and ;. Glob expansion (*.v, ~/docs/**), tilde expansion, and parameter expansion ($VAR, ${…}) with session IFS for word splitting.
Shared history file (~/.vlsh_history, last 5 000 entries), arrow keys, and Ctrl+R search. Bash-style history expansion at the interactive prompt: !!, !$, !n, !-n, !prefix, and !?sub.
Files and directories; the first word also completes command names from $PATH. After cd , only directories are suggested. Plugins can register custom completions (for example SSH hostnames).
Fish-style ghost text appears as you type, sourced from command history. Press → or End to accept the suggestion. Includes path validation for cd candidates and a filesystem fallback.
Install from the official repo with plugins install, plugins search, plugins update, plugins delete, or plugins reinstall. Plugins can add commands, prompt lines, pre/post hooks, output_hook, tab completions, mux_status for the multiplexer bar, and help text surfaced via help.
Run mux to split panes (resizable), use the mouse, copy/paste, a status bar, and up to 1 000 lines of scrollback per pane — VT100-friendly so editors like vim and nano work inside panes.
Run .vsh V scripts directly without manually compiling them first. Great for automation that needs performance without the ceremony of a full build.
Configure prompt colors via RGB values in ~/.vlshrc. Manage aliases at runtime or persist them in your config — all without restarting the shell.
POSIX
vlsh is not POSIX-conformant, but it supports commonly used POSIX shell features — with a documented, tested subset growing over time (see posix-inventory.md on GitHub).
| Operator | Behaviour |
|---|---|
&& | Run next command only on success |
|| | Run next command only on failure |
; | Run next command unconditionally |
< | Redirect stdin from a file |
> | Redirect stdout, overwriting the file |
>> | Redirect stdout, appending to the file |
2>&1 | Merge stderr into captured stdout when piping or redirecting |
| Builtin | Description |
|---|---|
export / unset | Set or remove environment variables |
source / . | Execute a script in the current shell context |
cd | Change directory; supports ~, $HOME, and cd - |
exit | Exit the shell with an optional status code |
$? | Expands to the exit status of the last command |
Installation
Latest release v1.2.0 — pre-built packages for 64-bit Linux, or build from source. Full instructions: README on GitHub.
# .deb for v1.2.0 (installs to /usr/bin/vlsh; postinst updates /etc/shells) curl -LO https://github.com/vlshcc/vlsh/releases/download/v1.2.0/vlsh_1.2.0_amd64.deb sudo dpkg -i vlsh_1.2.0_amd64.deb # Set as login shell (optional) chsh -s /usr/bin/vlsh
# RPM for v1.2.0
curl -LO https://github.com/vlshcc/vlsh/releases/download/v1.2.0/vlsh-1.2.0-1.x86_64.rpm
sudo rpm -U vlsh-1.2.0-1.x86_64.rpm
# Standalone 64-bit Linux binary (v1.2.0) curl -LO https://github.com/vlshcc/vlsh/releases/download/v1.2.0/vlsh_1.2.0_amd64_linux chmod +x vlsh_1.2.0_amd64_linux sudo mv vlsh_1.2.0_amd64_linux /usr/local/bin/vlsh # Approve shell and set as default (optional) echo /usr/local/bin/vlsh | sudo tee -a /etc/shells chsh -s /usr/local/bin/vlsh
# Requires V — https://vlang.io git clone https://github.com/vlshcc/vlsh.git cd vlsh v . ./vlsh # Or install into PATH: sudo make install (default PREFIX=/usr/local) # make help — targets; make test — suite; make fuzz — stress parsers
Plugins
Plugins install from the official repository into ~/.vlsh/plugins/<name>/<version>/; vlsh compiles them on startup. The remote catalogue lives at github.com/vlshcc/plugins. Plugins can:
help command
output_hook around every command
mux_status text for the multiplexer status bar
plugins reinstall
// Plugins implement main() and respond to argument tokens module main import os fn main() { arg := if os.args.len > 1 { os.args[1] } else { '' } match arg { 'capabilities' { println('prompt') } 'prompt' { branch := os.execute('git branch --show-current') if branch.exit_code == 0 { print(' (' + branch.output.trim_space() + ')') } } else {} } }
Shows the current branch and short commit hash in your prompt with configurable RGB colours.
Tab-completes SSH hostnames from ~/.ssh/config and known_hosts.
vman — V stdlib docs in the terminal from modules.vlang.io (install as v_man).
Upload a file to dpaste.com and print the URL.
Tracks your emotional state across git commits to see how mood correlates with code quality.
A minimal, commented template — the perfect starting point for writing your first plugin.
Browse the full catalogue and contribute at github.com/vlshcc/plugins
| Command | Description |
|---|---|
plugins list | Show all locally installed plugins with their installed version |
plugins remote | List plugins in the remote repository with version info and available updates |
plugins search <query> | Search available plugins by name or description |
plugins install <name> | Download and install the latest semver version of a plugin |
plugins update [name] | Update one plugin or all installed plugins to their latest version |
plugins reload | Recompile and reload all plugins (run after install or update) |
plugins enable / disable <name> | Activate or deactivate a plugin without deleting it |
plugins enable / disable all | Activate or deactivate all plugins at once |
plugins delete <name> | Remove an installed plugin and its entire directory |
plugins reinstall <name> | Remove the local copy and install the latest from the remote repository |