Quick Start
Open shiro.computer and start typing. The terminal is a full Unix shell with 220+ commands, persistent files, WASM runtimes, and Spirit AI.
# Create files and directories mkdir -p ~/project/src echo 'Hello from Shiro' > ~/project/README.md # List and search ls -la ~/project find ~/project -name "*.md" # Pipes and redirects echo "hello world" | sed 's/hello/goodbye/' | wc -c # Files persist across reloads cat ~/project/README.md
Everything runs in the browser. Files are stored in IndexedDB and survive page reloads. No server needed.
Filesystem
Shiro has an IndexedDB-backed POSIX filesystem. Files persist across sessions. The root is / with standard directories.
Key Paths
| Path | Purpose |
|---|---|
/home/user | Home directory (~) |
/tmp | Temporary files (not cleared automatically) |
/usr/local/bin | Global binaries (npm -g installs here) |
/usr/local/lib | Global node_modules |
File Operations
# Create, copy, move, remove touch file.txt cp file.txt backup.txt mv backup.txt renamed.txt rm renamed.txt # Directory operations mkdir -p deep/nested/path rmdir empty-dir rm -r deep # Permissions (stored but not enforced) chmod 755 script.sh ls -l script.sh # Symbolic links ln -s /home/user/target /home/user/link readlink /home/user/link # Disk usage du -sh /home/user
Shell
The shell is bash-compatible with pipes, redirects, variables, arrays, arithmetic, functions, process substitution, extended globbing, traps, and programmable tab completion.
Pipes and Redirects
# Pipe output between commands ls -la | grep ".js" | wc -l # Redirect to file echo "hello" > output.txt echo "more" >> output.txt # append # Input redirect cat < output.txt # Stderr redirect command-that-fails 2> errors.txt
Variables
# Set and use variables NAME="Shiro" echo "Welcome to $NAME" echo "Home is ${HOME}" # Built-in variables echo $HOME # /home/user echo $SHELL # /bin/sh echo $? # last exit code # Export for child processes export API_KEY=abc123
Compound Commands
# AND — run next only if previous succeeds mkdir -p /tmp/test && echo "created" # OR — run next only if previous fails cat /nonexistent 2>/dev/null || echo "file not found" # Semicolons — run sequentially regardless echo "first" ; echo "second" ; echo "third"
Quoting
# Single quotes — literal, no expansion echo '$HOME is not expanded' # Double quotes — variables expanded echo "Home is $HOME" # Backslash escapes echo "line one\nline two"
npm & Node.js
Install real npm packages from the registry. require() resolves from node_modules. Node.js scripts run with CommonJS and ES module support.
# Initialize a project mkdir -p ~/myapp && cd ~/myapp npm init -y # Install packages (real tarballs from registry.npmjs.org) npm install lodash npm install -g prettier # Use in scripts node -e "console.log(require('lodash').uniq([1,1,2,3]))" # Run a script file echo 'const _ = require("lodash"); console.log(_.chunk([1,2,3,4,5,6], 2));' > app.js node app.js # npm scripts npm run start # Package management npm list npm uninstall lodash # npx — run package binaries (auto-installs if needed) npx prettier --write app.js npx typescript --version npx @scope/pkg arg1 arg2
esbuild Bundler
# Bundle TypeScript/JavaScript
build src/app.ts --bundle --outfile=dist/app.jsSpirit (AI)
Built-in AI assistant powered by Claude. Pipe data through it, generate code, or ask questions. Requires an Anthropic API key.
# Set your API key export ANTHROPIC_API_KEY=sk-ant-... # Ask a question spirit "explain how DNS works" # Pipe data through AI cat data.csv | spirit "summarize this data" # Generate code spirit "write an Express API with /users endpoint" > server.js # Use a specific model spirit --model claude-opus-4-20250514 "review this code" < app.js # Set a system prompt spirit --system "You are a bash expert" "how do I find large files?" # List available models spirit --list-models
WASM Runtimes
Six language runtimes compiled to WebAssembly, lazy-loaded on first use (~1MB each, cached in IndexedDB).
C Compiler (xcc)
echo '#include <stdio.h>
int main() { printf("Hello from C!\\n"); return 0; }' > hello.c
cc hello.c -o hello
./helloSQLite (sql.js)
sqlite3 app.db "CREATE TABLE users (name TEXT, age INTEGER);"
sqlite3 app.db "INSERT INTO users VALUES ('Alice', 30), ('Bob', 25);"
sqlite3 app.db "SELECT * FROM users WHERE age > 28;"
sqlite3 app.db ".tables"Python (Pyodide)
python3 -c "print('Hello from Python!')"
python3 -c "import json; print(json.dumps({'key': 'value'}, indent=2))"
# Run a script
echo 'for i in range(5): print(f"Count: {i}")' > count.py
python3 count.pyLua (Fengari)
lua -e "print('Hello from Lua!')"
lua -e "for i=1,5 do print(i) end"jq (JSON processor)
echo '{"name":"Alice","scores":[95,87,92]}' | jq '.scores | add / length'
echo '[1,2,3,4,5]' | jq 'map(. * 2)'Git
Full client-side git via isomorphic-git. init, add, commit, diff, log, clone, push, and remote operations all work.
# Initialize and make commits git init echo "# My Project" > README.md git add . git commit -m "Initial commit" # Make changes and diff echo "Updated" >> README.md git diff git add . && git commit -m "Update readme" # View history git log --oneline git status # Clone a repo (HTTP only, needs CORS proxy) git clone https://github.com/user/repo.git # Push (needs GITHUB_TOKEN) GITHUB_TOKEN=$GITHUB_TOKEN git push origin main
Claude Code
The real @anthropic-ai/claude-code CLI runs inside Shiro's Node.js runtime. It can read, write, edit, and search files in the virtual filesystem.
Setup
Run setup to sign in with your Anthropic account via OAuth. Your credentials persist in IndexedDB.
# Sign in (opens OAuth flow) setup # Print mode — one-shot code generation claude -p "Write a function that checks if a number is prime" # Pipe input for analysis cat app.js | claude -p "Review this code for bugs" # Interactive mode (opens in a terminal window) sc
What Works
- Print mode (
claude -p "...") and interactive mode (claude) - File tools: Read, Write, Edit, Glob, Grep
- Bash tool: runs commands in the virtual shell
- Stdin piping:
echo "text" | claude -p "analyze"
Limitations
- Tree-sitter WASM doesn't load (syntax highlighting disabled)
- No native binary execution (ripgrep is shimmed to Shiro's
rg) - API calls route through a CORS proxy on shiro.computer
Editors & Viewers
Shiro includes rich code editors and file viewers. The open command uses file associations to pick the right tool automatically.
Code Editors
# CodeMirror editor (lightweight) code app.js # Monaco editor (VS Code engine) monaco app.ts # Auto-detect: open picks editor by extension open app.js # opens in code editor
Markdown Viewer
The mdview command renders markdown as formatted HTML with syntax-highlighted code blocks, tables, and dark-theme styling.
# View a markdown file mdview README.md # Pipe markdown content echo '# Hello World - item one - item two ```js console.log("highlighted!") ```' | mdview # open auto-detects .md files open notes.md # renders with mdview
HTML & Images
# Render HTML in a window echo '<h1>Hello</h1>' | html html page.html # Display an image img screenshot.png
Web APIs
Browser-native capabilities exposed as Unix commands. Pipe them together with standard shell tools.
# Text-to-speech echo "Hello world" | speak speak -r 1.5 "Fast speech" speak --list # list voices # Speech-to-text listen # single utterance to stdout listen | sh # speak a command to execute it listen -c >> notes.txt # dictate continuously # Desktop notifications build && notify "Build complete" notify -t "Alert" "Check this" # Webcam snapshot camera -o selfie.png camera && img camera-*.png # Computer vision (camera → Claude AI) camera | cv "describe this" cv -f photo.png "what's in this image?" # Process monitor top # interactive TUI (q to quit) top -b -n 1 # batch mode, one snapshot # Manual pages man grep # full man page in less pager man -k search # search all descriptions
Virtual Servers
Serve web apps from the virtual filesystem using a Service Worker. Interact with them from the shell using page commands.
# Start a server serve /tmp/myapp 3000 # Interact with the page page :3000 text "body" # read text page :3000 click "#button" # click an element page :3000 input "#name" "Alice" # type into input page :3000 eval "document.title" # run JavaScript # Split view — dock app beside the terminal serve /tmp/myapp 3000 --split right serve open 3000 --split bottom serve unsplit # Full-screen app mode become 3000 myapp # URL becomes /myapp unbecome # return to terminal
Remote Control
An outer Claude Code instance can control Shiro remotely via MCP tools over WebRTC. Peer-to-peer with no data going through the server after signaling.
In Shiro (browser)
remote start # Generate connection code remote status # Check connection remote stop # End session
In Claude Code (desktop)
Add to ~/.claude.json:
{
"mcpServers": {
"shiro": { "command": "shiro-mcp" }
}
}Then use tools: shiro:connect, shiro:exec, shiro:read, shiro:write, shiro:list, shiro:eval.
Node.js Compatibility
Shiro shims ~50 Node.js modules to run in the browser. Most are functional for common use cases. Some are stubs that satisfy import checks without full behavior.
| Module | Status | Notes |
|---|---|---|
fs | Works | readFile, writeFile, stat, mkdir, readdir, unlink, rename, existsSync, promises |
path | Works | join, resolve, basename, dirname, extname, relative, parse, format, sep |
buffer | Works | Buffer.from, alloc, toString, slice, concat, compare |
events | Works | EventEmitter: on, once, emit, removeListener |
process | Works | env, cwd, exit, nextTick, argv, platform, version, stdout, stderr |
child_process | Works | exec, execSync route through the virtual shell |
crypto | Works | createHash (sha256, sha1, md5), randomBytes, randomUUID |
os | Works | platform, arch, homedir, tmpdir, cpus, EOL |
url | Works | URL class, parse, format |
util | Works | promisify, format, inspect, types, parseArgs |
stream | Partial | Readable, Writable, Transform constructors exist; no full piping |
http | Partial | createServer for virtual servers; no outgoing HTTP |
https | Partial | Same as http; uses fetch() internally |
net | Stub | Socket constructor exists; no TCP |
tls | Stub | Satisfies imports; no real TLS |
dns | Stub | resolve/lookup return mock results |
zlib | Partial | gzip/gunzip via DecompressionStream |
readline | Partial | createInterface works for stdin reading |
string_decoder | Works | StringDecoder UTF-8 |
querystring | Works | parse, stringify, encode, decode |
assert | Works | ok, equal, deepEqual, throws, strict |
module | Partial | createRequire, _resolveFilename |
worker_threads | Stub | isMainThread = true; no real threads |
cluster | Stub | isMaster/isPrimary = true |
vm | Stub | runInNewContext wraps eval |
async_hooks | Stub | createHook returns no-op |
perf_hooks | Partial | performance.now() works |
Works = most APIs functional Partial = core APIs work, edge cases may fail Stub = satisfies imports, limited functionality
Command List
220+ commands, 2250+ tests. Core coreutils are loaded at boot. Large commands (build, python, sqlite3, etc.) are lazy-loaded on first use.
Core
ls cat echo mkdir rm cp mv touch pwd cd head tail wc sort uniq tee tr cut paste yes true false rev tac shuf split csplit
Search & Text
grep sed awk find rg diff xargs glob basename dirname realpath cmp dos2unix unix2dos
Archives & Compression
tar gzip gunzip zip unzip
Math & Data
dc factor numfmt cksum base32 base64 xxd dd
Dev Tools
node npm npx git build vi nano ed cc gcc python3 pip sqlite3 lua jq
Network & Servers
fetch curl wget serve page become unbecome remote mcp group
System
env export which type uname hostname whoami date uptime free ps kill sleep clear history help top w who users lsof nice man
Web APIs
speak listen notify camera cv
Editors & Viewers
code monaco less mdview html img open
AI
spirit claude sc cv
Shiro-specific
setup seed image spawn hud js-eval