El Remoto

El Remoto - browse any GitHub repository in Emacs without cloning it.

What

remoto.el registers a virtual filesystem via file-name-handler-alist that translates standard Emacs file operations into GitHub API calls via the gh CLI. The result: find-file , dired , tab-completion, dired-subtree - all standard Emacs file tooling works against a remote GitHub repo. Read-only.

Why

Sometimes you just want to look at code. Check a function signature, read a README, browse a project structure. Cloning a repo for that is overkill - it takes disk space, creates another directory to manage, and breaks your flow.

Where

For now it works only with GitHub repos. Future plans include support for other forges - GitLab, Codeberg, etc.

How

use-package + straight

You need to load the package so it can register its file handler and advice.

( use-package remoto :straight ( :host github :repo " agzam/remoto.el " ) :demand t )

The package is not on MELPA yet. Maybe upvote the submission PR, who knows, perhaps it gets accepted faster.

Usage

The main entry point. Accepts any GitHub URL format:

M-x remoto-browse RET https://github.com/torvalds/linux RET M-x remoto-browse RET git@github.com:torvalds/linux.git RET M-x remoto-browse RET torvalds/linux RET

C-x d / C-x C-f

GitHub URLs are detected automatically in dired and find-file :

C-x d /github.com/torvalds/linux RET C-x C-f https://github.com/torvalds/linux/blob/master/README RET

Canonical paths

The virtual filesystem uses paths of the form:

/github:OWNER/REPO@REF:/PATH

REF is optional - omitting it uses the repo’s default branch.

Commands

Command Description remoto-browse Prompt for a repo, open dired at root remoto-refresh Clear tree cache for current repo, re-fetch remoto-copy-github-url Copy github.com URL for current file/line to kill ring

How it works

On first access to any file in a repo, the full directory tree is fetched via the Git Trees API (one HTTP call). Directory listings, file-exists-p , completions - all served from the cached tree in memory. File contents are fetched on demand when you actually open a file. Content is cached by SHA, so re-opening the same file is instant. Authentication, SSO, private repos - all handled transparently by gh .

FAQ

Why this isn’t a TRAMP backend?

TRAMP fundamentally is a shell-over-transport abstraction. Every TRAMP backend assumes a remote shell on the other end, remoto.el has no remote shell.

TRAMP’s backend API is large. You’d need to implement or stub dozens of operations, many of which assume concepts that don’t map to a REST API (process execution, file ownership, symlink resolution, timestamps).

TRAMP’s connection management (open/close/reuse) is built around persistent sessions. The GitHub API is stateless HTTP - there’s no connection to manage.

TRAMP’s caching layer is path-based and per-connection. remoto’s tree cache (one API call fetches the entire repo tree, then everything is served from memory) is a fundamentally different - and much more efficient - model for a read-only tree-structured API.

file-name-handler-alist IS the same mechanism TRAMP uses. Registering there directly gives you the same integration (dired, find-file, completions) without the framework overhead.

For a read-only tree browser backed by a REST API, a direct file-name-handler is the simpler, more natural fit

Limitations