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