# pgweb: a single-binary PostgreSQL explorer you open in a browser

> Pgweb is a Go program that serves a web UI for PostgreSQL on Mac, Linux and Windows, with SSH tunnels and CSV/JSON/XML export. It is small, easy to install, and deliberately not a full administration suite.

**sosedoff/pgweb** — Cross-platform client for PostgreSQL databases

- Repository: https://github.com/sosedoff/pgweb
- Website: https://sosedoff.github.io/pgweb
- Stars: 9,520 · Forks: 866
- Language: Go
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/sosedoff-pgweb

## What pgweb solves, and the engineer it is written for

Most PostgreSQL work happens in a terminal or inside an application. Pgweb targets the moment in between: you want to look at a table, run one query, export the result, and close the tab. The README calls it a "Simple web-based and cross platform PostgreSQL database explorer", distributed as a single binary with zero dependencies, and that framing is the whole product thesis. It is not a schema migration tool, not a monitoring dashboard, and not a replacement for psql when you need scripted, repeatable work.

The audience is narrow and identifiable. You run PostgreSQL 9.6 or newer, you work on a laptop or a jump host, and you would rather not install a desktop client or stand up a server-side admin panel. The README lists the features that follow from that: multiple database sessions, native SSH tunnels, server bookmarks, query history, and export to CSV, JSON or XML. Each of those is a read-and-inspect concern. Nothing in the feature list is about altering server configuration, managing roles, or scheduling jobs.

## How pgweb is put together: Go binary, embedded UI, one HTTP server

The repository layout makes the architecture legible without running anything. main.go sits at the root, pkg/ holds the application packages, and static/ holds the front-end assets that the Dockerfile copies into the build stage. The dependency list in go.mod confirms the shape: gin-gonic/gin for HTTP routing, jmoiron/sqlx and lib/pq for database access, jessevdk/go-flags for the command-line interface, BurntSushi/toml for configuration files, sirupsen/logrus for logging, and prometheus/client_golang for metrics. There is also ScaleFT/sshkeys, which lines up with the advertised SSH tunnel support.

The data flow is the ordinary one for this class of tool. The Go process opens a connection pool to PostgreSQL, serves an HTTP API and static assets, and the browser talks to that server rather than to the database. The Dockerfile finishes with `ENTRYPOINT ["/usr/bin/pgweb", "--bind=0.0.0.0", "--listen=8081"]` and `EXPOSE 8081`, so in the container image the process binds all interfaces on port 8081. That is a deliberate choice for containers and a poor default for a laptop on an untrusted network, which is why the bind and listen flags exist as flags at all.

The build stage sets `ARG CGO_ENABLED=0`, which is how the project produces a static binary that runs without a libc dependency. That single build argument is the reason the README can promise zero dependencies, and it is worth understanding before you assume the binary will link against anything on the host.

## Installing pgweb and running a first query

The README points to precompiled binaries on the GitHub releases page for supported operating systems, and to the wiki for more installation options. If you have a Go toolchain, the Makefile exposes an install target that builds with version metadata injected through ldflags:

```bash
make install
```

After that the README says you can execute `pgweb`. With no arguments, the server starts and you open the printed address in a browser. To skip the connection form and go straight to a database, pass flags:

```bash
pgweb --host localhost --user myuser --db mydb
```

The README also documents a connection URL, which is the form to use when you need SSL modes or a Unix socket:

```bash
pgweb --url postgres://user:password@host:port/database?sslmode=[mode]
pgweb --url "postgres:///database?host=/absolute/path/to/unix/socket/dir"
```

If you would rather not install anything, the repository ships a docker-compose.yml that starts PostgreSQL 18 on host port 5433 and pgweb on port 8081, wired together over a private network. The pgweb service reads its connection string from the PGWEB_DATABASE_URL environment variable and waits for the database healthcheck before starting:

```bash
docker compose up
```

Once the UI is open, the README's feature list is the tour: browse tables, run a custom SQL query, and export the result set as CSV, JSON or XML. Query history and server bookmarks persist the things you would otherwise retype. For more than one database at a time, start the server with `pgweb --sessions` or set `PGWEB_SESSIONS=1` in the environment.

## Where pgweb stops: authentication, exposure and scale

The README documents no authentication for the pgweb HTTP server. There is no login flag, no user database, and no mention of TLS on the listening side. The application is a thin client for a database connection you supply, and the security boundary it assumes is the network you put it on. The bundled Dockerfile binds `0.0.0.0` on port 8081, which is correct inside a container network and wrong the moment that port is published to a hostile network. If you deploy pgweb anywhere reachable, put it behind a reverse proxy that terminates TLS and enforces authentication, or leave it bound to localhost and reach it over an SSH port forward. The README does not describe either pattern, so treat this as a gap you fill yourself.

The second boundary is scope. Pgweb explores data; it does not administer a cluster. There is no documented support for managing replication, roles, extensions, or server parameters, and no backup or restore workflow. If your task is "add a column across three environments with a rollback plan", pgweb is the wrong tool and psql or a migration framework is the right one. Pgweb is also a single-user-shaped tool by design. Multiple sessions means multiple databases in one browser, not multiple authenticated users sharing a server.

A third constraint is version floor. The README states PostgreSQL 9.6 or newer, so very old deployments are out of scope, and the project's own test matrix in the Makefile runs against multiple PostgreSQL versions through `make test-all`, which tells you the maintainers care about that range but also that the floor is a real boundary.

## pgweb compared with pgAdmin and Adminer

The honest comparison is about surface area, not features. pgAdmin is a full PostgreSQL administration and development platform: it manages servers, roles, backups and scheduled tasks, and it is the tool the README's own ecosystem implicitly assumes when someone needs more than browsing. Pgweb does none of that. What pgweb offers instead is a single Go binary with zero dependencies that starts in one command and serves a UI on a port you choose. If your job is to operate a PostgreSQL fleet, pgAdmin is the closer fit. If your job is to look at a table on a staging host for two minutes, pgweb gets there with less ceremony.

Adminer is the other common reference point, and the difference is focus rather than size. Adminer is a single PHP file that speaks to many database engines, which makes it attractive when you already run PHP and want one tool for MySQL, PostgreSQL and others. Pgweb speaks only PostgreSQL, and it spends that narrowness on PostgreSQL-specific behaviour: the README calls out PostgreSQL 9.6+ support, native SSH tunnels, and Unix socket connection URLs of the form `postgres:///database?host=/absolute/path/to/unix/socket/dir`. A polyglot shop may prefer Adminer's breadth; a PostgreSQL-only shop gets more relevant connection handling from pgweb.

On distribution, pgweb's Docker image is published as sosedoff/pgweb and the repository includes both a Dockerfile and a compose file, so the container path is first-class rather than an afterthought.

## Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-07-26. Releases are infrequent rather than continuous: v0.17.0 landed on 2025-11-22, v0.16.2 on 2024-11-02, and v0.16.1 on 2024-09-07. That cadence matters for planning. You are adopting a project that ships a new minor version roughly once a year, so pin a version rather than tracking main, and read CHANGELOG.md before upgrading. The upgrade cost itself is low by construction: a single binary or a container image, no database-side components to migrate, and no schema that pgweb owns. Rolling back means running the previous binary or image tag.

Building from source pins Go 1.25 in go.mod with `toolchain go1.25.4`, so a recent Go toolchain is required if you compile it yourself. The Dockerfile uses golang:1.25-trixie for the build stage and debian:trixie-slim for the release stage, installing `postgresql-client` alongside ca-certificates, openssl, netcat-openbsd and curl. The runtime container runs as a non-root user created with `useradd --uid 1000 --no-create-home --shell /bin/false pgweb`, which is a sensible default if you deploy the image.

The licence is MIT, stated in the README and present as a LICENSE file at the repository root. MIT is permissive: it allows commercial and closed-source use with attribution and no warranty. That is a statement about the licence text, not legal advice for your situation; if you redistribute pgweb inside a product, have your own counsel read the LICENSE file.

## Conclusion

Adopt pgweb if you want a local, dependency-free browser for reading tables, running ad hoc SQL and exporting results, and you are comfortable that the README documents no authentication or TLS for the pgweb server itself. Do not adopt it as a replacement for pgAdmin's server administration or for a shared, internet-facing database console. Before you commit, verify two things in your own environment: that a plain `pgweb --url ...` run reaches your database through the SSH tunnel or socket path you actually use, and that the bind address and port you choose are reachable only by the people who should reach them.

## FAQ

### How do I install pgweb?

The README points to precompiled binaries on the GitHub releases page for supported operating systems, and to the project wiki for more installation options. If you have a Go toolchain, the Makefile provides `make install`, after which the README says you can execute `pgweb`.

### Is pgweb easy to learn?

The README describes it as simple, and the interaction model is a browser UI over a database connection you supply. Starting it takes one command, and the documented feature set is limited to browsing, querying, exporting and bookmarks, so there is little surface to learn.

### Does pgweb support SSH tunnels?

Yes. Native SSH tunnels appear in the README's feature list, and go.mod includes the ScaleFT/sshkeys dependency, which is consistent with SSH key handling.

### Can pgweb connect through a Unix socket instead of TCP?

Yes. The README documents a URL form for that case: `pgweb --url "postgres:///database?host=/absolute/path/to/unix/socket/dir"`.

### Which PostgreSQL versions does pgweb support?

The README states PostgreSQL 9.6 or newer. The Makefile also exposes `make test-all`, which the README says runs the test suite against all supported PostgreSQL versions.

## Sources

- [License: MIT](https://github.com/sosedoff/pgweb/blob/main/LICENSE)
- [Project website](https://sosedoff.github.io/pgweb)
- [README](https://github.com/sosedoff/pgweb/blob/main/README.md)
- [Releases](https://github.com/sosedoff/pgweb/releases)
- [sosedoff/pgweb on GitHub](https://github.com/sosedoff/pgweb)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sosedoff-pgweb
