The Problem
Browsing a GitHub repository usually means cloning it first. That costs disk space, creates directory clutter, and breaks flow when you only need to check a function signature or read a README. remoto.el removes that friction by making remote repos browsable directly in Emacs, as if they were local directories.
What This Does
remoto.el registers a virtual filesystem via file-name-handler-alist that translates standard Emacs file operations into GitHub API calls through the ghub library. The result: find-file, dired, tab-completion, and dired-subtree all work against a remote GitHub repo, read-only. The main entry point is remoto-browse, which accepts any GitHub URL format: full URLs, SSH-style git@github.com:owner/repo.git, or shorthand owner/repo. The virtual filesystem uses canonical paths like /github:OWNER/REPO@REF:/PATH, with REF optional (defaults to the repo's default branch). Issue and PR browsing is built in—opening /github:owner/repo#42 shows a dedicated buffer with body, comments, and for PRs, diff stats and merge status.
How It Is Wired
The core logic lives in remoto.el, with remoto-embark.el providing Embark integration and remoto-topic.el handling issue/PR display buffers. The package registers a file handler that intercepts standard file operations and routes them through ghub to GitHub's API. When you invoke remoto-browse or use the /github: prefix in find-file, the handler resolves the path, makes API calls, and presents the result as a virtual file or directory listing. The completion system supports multi-level navigation: /github:owner/repo/ for files, @ for branches/tags, # for issues/PRs. Each level shows annotations—repo descriptions, commit messages, issue titles—which works with vanilla completion, Vertico, and Corfu.
The wiring is straightforward: no background processes, no daemons, just API calls on demand. The package depends on ghub for authentication and API access, and the file-name-handler-alist mechanism does the heavy lifting. Tests in test/ cover core functionality, integration, and Embark integration.
How To Use It
Setup: The package is not on MELPA yet. Install via use-package + straight:
(use-package remoto
:straight (:host github :repo "agzam/remoto.el")
:demand t)
Configuration: Requires GitHub authentication via ghub—set up a token or use gh auth login if you have the GitHub CLI installed.
Running it:
M-x remoto-browse RET https://github.com/torvalds/linux RET
C-x C-f /gh:torvalds/linux RET
Real-World Use
A developer investigating a bug in an unfamiliar library can C-x C-f /gh:owner/repo/src/ and browse the file tree, open files, and read commit messages—all without leaving Emacs or touching disk. The # delimiter lets them jump straight to related issues or PRs to check context. For code review, the PR display buffer gives diff stats and review summaries without opening a browser.
Code Health & Issues
Static analysis found 3 issues (0 critical, 1 high, 1 medium, 1 low):
- High - Unpinned GitHub Actions:
.github/workflowsusespurcell/setup-emacs@master. A moved tag can execute arbitrary code with your token. Fix: pin to commit SHA with# vNcomment, let Dependabot bump. - Medium - Missing least-privilege permissions:
.github/workflows/run-tests.ymldeclares nopermissions, so the token inherits repo defaults. Fix: addpermissions: contents: readat workflow level. - Low - No job timeouts:
.github/workflows/run-tests.ymllackstimeout-minutes. A wedged step runs to the 6-hour platform default. Fix: add realistic bounds per job.
The repo has tests, CI, a license, and no committed secrets. The Makefile suggests a make test target exists but its contents weren't analyzed.
The Bottom Line
remoto.el solves a real annoyance cleanly: it makes remote repo browsing feel native in Emacs without cloning. The architecture is sound—virtual filesystem via file-name-handler-alist is the right Emacs idiom. The CI hygiene issues are minor and easily fixed. Worth adopting if you frequently peek at unfamiliar repos and live in Emacs.