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/workflows uses purcell/setup-emacs@master. A moved tag can execute arbitrary code with your token. Fix: pin to commit SHA with # vN comment, let Dependabot bump.
  • Medium - Missing least-privilege permissions: .github/workflows/run-tests.yml declares no permissions, so the token inherits repo defaults. Fix: add permissions: contents: read at workflow level.
  • Low - No job timeouts: .github/workflows/run-tests.yml lacks timeout-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.