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.

Sheru in web mode wearing the Windows XP theme, with the ⌘J terminal open

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:

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 window wearing the Windows 98 theme The same window wearing the Aqua theme

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.

Sheru's native view engine, rendered with AppKit
Native engine · AppKit
Sheru's WebView engine, rendered with the Aqua theme
Web engine · WKWebView

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.

Native AppKit and WebView engines converging through CoreHub into the shared sheru-core, with a future platform shell using the same protocol

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:

  1. Could you write it without importing AppKit or another host SDK? → core.
  2. Is "what to do" the same sentence on every OS ("move to trash")? → host SPI.
  3. 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:

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.

イン・ザ・シェル — see you in the shell.