A local git repository viewer that gives you a GitHub-like browsing experience — without leaving your machine. Built for non-developers who use tools like Claude Code to work in git repositories and want a clean way to read, navigate, and review their code without a full IDE. Everything runs locally, there are no accounts or telemetry, and any clone, fetch, pull, or push action goes through your installed git only when you choose it.
| Dependency | Version |
|---|---|
| Node.js | 22+ |
| git | 2.22+ |
Choose the workflow that fits how you want to use GitLocal:
npm install -g gitlocalnpx gitlocalgit clone https://github.com/ehud-am/gitlocal.git
cd gitlocal
npm ci
npm --prefix ui ci
npm run buildRun the built CLI from the repository root:
# Open the current repository
node dist/cli.js .
# Open a specific repository
node dist/cli.js ~/projects/my-app
# Open the folder picker
node dist/cli.jsGitLocal starts a local HTTP server on a random available port, prints the URL, and opens your default browser automatically.
gitlocal listening on http://localhost:54321
Press Ctrl+C to stop the server.
gitlocal <path-to-git-repo>Examples:
# View this repo
gitlocal .
# View a project by absolute path
gitlocal ~/projects/my-app
# View any path — GitLocal shows an error screen if it's not a git repo
gitlocal /tmp/not-a-repoWhen a repository opens, GitLocal shows the README immediately if one is found.
Run gitlocal with no arguments:
gitlocalIf your current shell is already inside a git repository, GitLocal opens that repository immediately instead of showing the picker.
From the picker you can:
- double-click a folder row to move deeper into it
- double-click a detected git repository row to open it immediately
- use the folder actions menu to create a subfolder, run
git init, or clone into a child folder
GitLocal also clears stale saved branch and path state when you switch repositories, so reopening the app does not strand you on an invalid branch or file from a previous repo.
- Browse the file tree — expand and collapse folders lazily, just like GitHub
- Read files beautifully — Markdown renders with GitHub-like typography and tables; code files get syntax highlighting; images display inline
- Reference code precisely — code-oriented views include left-side line numbers for easier review and discussion
- Track file sync state — file rows show when content changed locally, exists in local-only commits, changed upstream, or diverged between local and remote history
- Make local file edits — create, edit, and delete files from the viewer when you are on the repository's working branch
- Commit and sync safely — create local commits, push ahead branches, and fast-forward pull behind branches from the repository header
- Switch branches safely — checkout local or remote-tracking branches, with commit/discard confirmation when the working tree is dirty
- Manage repo identity locally — update the repository-specific git
user.nameanduser.emailwithout touching your global git config - See repo context clearly — GitHub-like header with branch, local path, remote path, remote linkage, and repo-local identity
- Search deliberately — repository-wide search opens only from the header search button, while file-level
Find in filesearches just the file you are currently viewing - Auto-opens README — when you open a repo, the README is shown immediately if one exists
- Folder picker — run
gitlocalwith no arguments to open a browser-based folder picker - Smart startup detection — running
gitlocalinside a repo opens that repo immediately; otherwise GitLocal starts in the folder picker - Clear folder actions — non-git folders can be browsed deeper, initialized as git repos, or used as clone targets
- Light and dark themes — GitHub-inspired light mode with matching dark mode support
- Local-first, remote optional — core browsing and editing stay local-first, while remote clone and sync actions use the local
gitexecutable when a repo has a remote configured
The fixed footer now shows the actual running GitLocal release version instead of a placeholder value, so support and release verification can rely on what the UI displays.
Repository-wide search no longer takes over Cmd/Ctrl+F, so the browser's native page find stays available while GitLocal offers its own explicit repository search and current-file find tools.
- Node.js 22+
# Terminal 1: backend with auto-restart on changes
npm run dev:server
# Terminal 2: Vite dev server for the frontend
npm run dev:uiUse both commands together during development:
npm run dev:serverstarts the backend in watch modenpm run dev:uistarts the Vite frontend with hot reload
npm testRuns backend tests (Vitest + coverage) and frontend tests. All source files must maintain ≥90% branch coverage per file. Frontend component tests also include automated accessibility checks for key browsing surfaces.
npm run test:servernpm run buildBuilds the React frontend and compiles the Node.js CLI into dist/cli.js.
npm run verifyRuns tests, builds, and dependency audits for both the root package and the UI package.
GitLocal is a Node.js CLI that serves a React SPA:
gitlocal/
├── src/
│ ├── cli.ts — entry point: arg parsing, server start, browser open
│ ├── server.ts — Hono app, route registration, static serving + SPA fallback
│ ├── git/
│ │ ├── repo.ts — repo metadata, branch/sync actions, commit helpers, README lookup, and file sync state
│ │ └── tree.ts — listDir (git ls-tree wrapper, sorted dirs-first)
│ ├── services/
│ │ └── repo-watch.ts — working-tree revision and sync status snapshots for the UI
│ └── handlers/
│ ├── git.ts — /api/info, /api/readme, /api/branches, /api/commits, /api/git/commit, /api/git/sync
│ ├── files.ts — /api/tree, /api/file
│ ├── sync.ts — /api/sync
│ └── pick.ts — /api/pick and /api/pick/browse for the folder picker
└── ui/src/
├── App.tsx — layout, repo sync polling, dialogs, README auto-load, picker mode
├── components/
│ ├── FileTree/ — lazy expand/collapse tree
│ ├── Breadcrumb/ — path navigation
│ ├── ContentPanel/ — Markdown, code, image, binary rendering, and local file editing
│ ├── RepoContext/ — branch switcher, sync summary, repo metadata, identity editing, commit/sync actions
│ └── Picker/ — PickerPage table browser with setup actions
└── services/api.ts — typed fetch wrappers for all endpoints
Key design decisions:
- No external runtime dependencies beyond Node.js — all git operations shell out to the local
gitbinary viachild_process.spawnSync - Single npm toolchain — build, test, and install all via
npm; no Go, no Makefile, no shell scripts - Hash-based routing —
HashRoutermeans the server only needs to serveindex.htmlfor all non-asset routes - Local-first editing and sync awareness — GitLocal can create, update, and delete working-tree files locally while using git commands for branch, commit, and remote-aware repository actions
All endpoints are served under /api/:
| Endpoint | Description |
|---|---|
GET /api/info |
Repository metadata (name, branch, isGitRepo, pickerMode) |
GET /api/readme |
Detects and returns the README filename for the current repo |
GET /api/branches |
List of branches with isCurrent flag |
POST /api/branches/switch |
Switch branches with dirty-tree confirmation flows |
POST /api/git/commit |
Stage all current changes and create a local commit |
POST /api/git/sync |
Push ahead branches or fast-forward pull behind branches |
PUT /api/git/identity |
Update user.name and user.email in the current repo's local git config |
GET /api/tree?path=&branch= |
Directory listing (dirs first, alphabetical) |
GET /api/file?path=&branch= |
File content with type and language detection |
GET /api/search?query=&branch=&mode=&caseSensitive= |
Repository search across file names, file contents, or both |
POST /api/file |
Create a new file in the current repository working tree |
PUT /api/file |
Update an existing file using its revision token |
DELETE /api/file |
Delete an existing file using its revision token |
GET /api/commits?branch=&limit= |
Recent commits (default 10, max 100) |
GET /api/sync?path=&branch= |
Working-tree and upstream sync summary for the current path and branch |
GET /api/pick/browse?path= |
Folder-picker directory listing with git-repo detection |
POST /api/pick |
Set the repo path from the picker UI (body: {"path":"..."}) |
POST /api/pick/create-folder |
Create a child folder from the picker setup flow |
POST /api/pick/init |
Initialize git in the selected picker folder |
POST /api/pick/clone |
Clone a repository into a child folder from the picker |
MIT — see LICENSE.
Issues and pull requests are welcome. This project follows the GitLocal constitution — all changes must maintain ≥90% branch coverage per file.