Introducing Sheru
Sheru — シェル, Japanese for shell — is a new file manager for macOS built on the oldest idea in Unix, carried all the way: everything is a file. Your local disk, a dev box over SSH, an S3 bucket, the phone on your desk, a GitHub issue thread — one browsable surface, one set of habits, and a real terminal one keystroke away.
Download it for macOS, or keep reading for the story and the architecture.

One surface, every file#
Look at the sidebar in the screenshot above. Next to the usual folders there's
a GitHub connector, an Android device, and an SSH box called
hetzner-test-1. All of them browse like folders, because to Sheru they are
folders:
- Remote filesystems — S3-compatible object storage (R2 included), WebDAV, SFTP, FTP, and SMB connect with an endpoint and credentials and behave like plain directories. Nothing is mounted into macOS — no kernel extensions, no system changes; credentials stay on your machine. SFTP goes all the way: rename, move, edit in place, like local disk.
- Services as file trees — connectors project GitHub, Linear, and Notion as
read-only folders. A repository contains
Issues/, an issue containsissue.mdand acomments/folder, and you can run real actions — comment, close — right from the browser. - Devices — an Android phone plugged in over
adbshows up in the sidebar and browses like a disk. - A real shell, ⌘J away — press ⌘J and a genuine
zshslides up, already sitting in the folder you're looking at. Browse, and the shell follows;cd, and the browser follows. On an SSH connector the same keystroke opens a shell on the remote machine.
Wear any decade#
Sheru ships with two interchangeable view engines. Native mode is built entirely from AppKit controls — fast, fluid, indistinguishable from a first-party Mac app. Web mode renders every window — chrome included — with the system WebView, which is what makes pluggable OS-retro themes possible: Aqua, Windows 98, Windows XP, Windows 7, and XFCE ship built in.
The same home folder, the same live terminal — different decades. A theme in
Sheru is a pure-data plugin: a JSON-serializable object that binds a
schema of 88 design tokens and styles a documented set of data-part hooks.
No code ships inside a theme, a validator rejects one that misses a required
token, and the app even bakes a matching Dock icon for every theme
automatically. If you want to go deeper, the whole contract is
documented.
A native app that uses web for its UI#
When the Raycast team published their technical deep dive on rebuilding Raycast for multiple platforms, one line stuck with us:
We're not a web app with some native hooks sprinkled on top. We're a native app that uses web for its UI.
That's Sheru's conviction too, taken one step further: in Sheru, web is optional. There is no Electron and no Tauri — the app is a plain AppKit application either way. Native mode paints with AppKit views; web mode swaps the paint layer for WKWebView windows running our UI. View ▸ Use Web Interface replaces every open window in place, frames preserved. What never changes is everything underneath: windows, menus, Quick Look, the menu bar, and the shared core that does the actual work.
That second renderer is why Sheru became cross-platform before it had a second
operating system. AppKit and WKWebView needed to share file operations,
connectors, terminal sessions, preferences, and navigation without duplicating
product logic, so the first macOS release put both engines on one set of domain
services. That battle-tested boundary later became the platform-neutral
protocol served by sheru-core. macOS was the first shell; the architecture
already had room for the next one.
Raycast's stack mixes TypeScript, Swift, C#, Rust, Node, and React across a native shell, a system WebView, a Node backend, and a Rust core. Sheru's mix is deliberately smaller — three languages, three responsibilities.
Three languages, one core#
Rust owns the decisions. sheru-core is a single Rust crate that serves a
platform-neutral, JSON-speaking protocol. Everything with cross-platform
semantics lives there: the file-operation engine with Finder-grade naming and
trash-backed undo; the node system that treats local disk, rclone-backed
remotes (S3, WebDAV, SFTP…), service projections (GitHub, Linear, Notion),
and plugged-in devices as one provider model; search; directory watching; PTY
terminal sessions with flow control and cwd tracking; preferences. Remote
credentials are passed as connection strings at runtime — never written to a
config file on disk.
Swift owns the OS. The macOS shell is a thin AppKit app: windows and menus, Quick Look, the two view engines — and a small host SPI the core calls upward for the few things it refuses to fake, like the system trash (with put-back) and the clipboard. The whole C ABI between them is three entry points:
SheruCore *sheru_core_new(config_json, host_callbacks);
char *sheru_core_dispatch(core, request_json); // any thread
void sheru_core_close(core);TypeScript owns the pixels — and the contract. The web UI is a React SPA;
the headless component layer and the theme token schema live beside it. But
the most important TypeScript file in the repository is protocol.ts: the
single source of truth for every method on the wire, annotated with its owner
— [core] or [shell]. A generator derives the Swift routing table and the
Rust test manifest from it, and the build gate fails if either mirror is
stale. The three languages can't quietly disagree about the protocol, because
two of them are generated from the third.
The placement rule for every new feature is three questions:
- Could you write it without importing AppKit or another host SDK? → core.
- Is "what to do" the same sentence on every OS ("move to trash")? → host SPI.
- Does even the intent differ per platform (window management)? → shell.
If a platform conditional shows up inside the core, it belongs in the SPI. If two shells grow the same logic, it belongs in the core.
The core is the port#
This is what the Rust core buys us: porting Sheru is writing a shell, not rewriting an app. A new platform needs windows, menus, a system WebView, and a dozen host-SPI verbs — file operations, remotes, connectors, search, terminals, undo, preferences all already exist, in a crate with no UI dependencies.
Two things keep us honest about that claim:
- The golden tests. The core's test suite drives it exactly the way a shell does — JSON requests in, JSON responses out, against a real temporary filesystem and a mock host. Those tests are the behavior spec any port must preserve, byte for byte.
- The core already runs without the Mac. The same crate compiles into a headless server that speaks the same protocol over WebSocket — a cloud VM can host a full Sheru core next to the storage it mounts — and cores federate: one core can mount another as a node, capabilities only attenuating across the hop. The core genuinely does not care who is talking to it.
None of that is a product announcement — it's an architecture property. But it means the interesting part of bringing Sheru somewhere new is the part that should be platform-specific: making it feel native there.
One historical note we like: the core's API was not designed on paper. It was rehearsed in Swift first — the macOS app consolidated both view engines onto one set of domain services, in production — and then ported to Rust against the golden tests. Every method had a battle-tested wire shape before it had a Rust implementation.
Get it#
Sheru requires macOS 26 (Tahoe) or later, and it's free — native mode and the theme engine alike.
- Download for macOS
- Getting started
- Theming · Extensions
- Follow along on X
イン・ザ・シェル — see you in the shell.