A database visualization tool that connects to running databases and generates interactive ERD (Entity Relationship Diagram) visualizations. Understand your database schema at a glance.
Light mode with hierarchical layout Dark mode with circular layout
- Multi-Database Support - Connect to PostgreSQL, MySQL, SQLite, SQL Server, and MongoDB
- Automatic Schema Introspection - Discovers tables, columns, primary keys, foreign keys, and indexes
- Interactive ERD Visualization - Explore relationships with zoom, pan, and click-to-inspect
- Multiple Layout Algorithms - Grid, hierarchical, force-directed, and circular layouts
- Multi-Format Export - Export diagrams as SVG, PNG, or PDF
- Light/Dark Mode - Theme toggle with system preference detection and persistent user choice
- Minimap Navigation - Overview panel for quick navigation in large schemas
- Table Collapsing - Collapse tables to show only headers for cleaner diagrams
- Isolation Mode - Focus on a single table and its direct relationships
- Keyboard Shortcuts - Full keyboard navigation with undo/redo support
- CLI Tool - Command-line interface for headless schema introspection
- Observability - Prometheus metrics and Grafana dashboards included
- Docker Support - Ready-to-use Docker Compose for local development
- Secure by Design - Credentials encrypted at rest (AES-256-GCM), SSL/TLS support
- Privacy First - Only schema metadata is retrieved; your data never leaves the database
- Go 1.23 or later
- Node.js 20 or later
- npm 10 or later
git clone https://github.com/dshills/visdb.git
cd visdb
# Install all dependencies (Go + Node)
make depsCreate a .env file in the project root:
# Server address
VISDB_ADDR=:8080
# Required: 32-byte hex key for AES-256 encryption
# Generate one with: openssl rand -hex 32
VISDB_ENCRYPTION_KEY=$(openssl rand -hex 32)
# Required: JWT signing secret (use any secure random string)
VISDB_JWT_SECRET=$(openssl rand -base64 32)
# Storage database (SQLite by default)
VISDB_DATABASE_URL=file:visdb.db?mode=rwcOr copy and customize the example:
cp .env.example .env
# Edit .env with your valuesOpen two terminal windows:
# Terminal 1: Start the backend API server
make backend# Terminal 2: Start the frontend dev server
make frontendNavigate to http://localhost:3000 in your browser.
- Click New Connection
- Enter a name for your connection (e.g., "Production DB")
- Select your database type (PostgreSQL, MySQL, SQLite, or SQL Server)
- Fill in the connection details:
- Host: Database server address (e.g.,
localhost) - Port: Database port (defaults are pre-filled)
- Database: Database name
- Username/Password: Your credentials
- Host: Database server address (e.g.,
- Click Test to verify the connection
- Click Create Connection to save
- Click Visualize to generate the ERD
- Pan: Click and drag the canvas
- Zoom: Use mouse wheel or zoom controls (+/−), or
Ctrl++/Ctrl+- - Inspect: Click any table to see column details, types, and constraints
- Collapse: Click the collapse button on a table header to show only the table name
- Isolate: Press
Ior click the isolation button, then click a table to show only it and directly related tables - Search: Use
Ctrl+For/to search and filter tables - Minimap: Use the Overview panel (bottom-right) to navigate large diagrams—click to jump to any area
- Theme: Click the sun/moon icon in the header to toggle light/dark mode
- Undo/Redo: Use
Ctrl+Z/Ctrl+Yto undo/redo position changes - Help: Press
?to see all keyboard shortcuts - Export: Click Export to download as SVG, PNG, or PDF
| Command | Description |
|---|---|
make deps |
Install Go and Node dependencies |
make backend |
Run backend in development mode (port 8080) |
make frontend |
Run frontend dev server (port 3000) |
make build |
Build the backend binary |
make build-prod |
Build optimized backend + frontend |
make test |
Run all Go tests |
make test-coverage |
Run tests with coverage report |
make lint |
Run Go linter |
make clean |
Remove build artifacts |
make build-cli |
Build the CLI tool |
cd web
npm test # Run frontend tests
npm run lint # Lint frontend code
npm run build # Production buildThe CLI provides headless schema introspection without requiring the web interface.
make build-cli# Introspect a database schema
./bin/visdb-cli introspect -type postgres -host localhost -port 5432 -db mydb -user admin -pass secret
# Export schema to file
./bin/visdb-cli export -type postgres -host localhost -port 5432 -db mydb -user admin -pass secret -format json -output schema.json
# Analyze schema for issues
./bin/visdb-cli analyze -type postgres -host localhost -port 5432 -db mydb -user admin -pass secret| Flag | Description |
|---|---|
-type |
Database type (postgres, mysql, sqlite, sqlserver, mongodb) |
-host |
Database host |
-port |
Database port |
-db |
Database name |
-user |
Username |
-pass |
Password |
-format |
Output format: json, markdown (default: json) |
-output |
Output file path (default: stdout) |
Run visDB with Docker Compose for easy local development.
# Start visDB only
docker-compose up visdb
# Start with monitoring (Prometheus + Grafana)
docker-compose --profile monitoring up
# Start with sample databases (Postgres, MySQL, MongoDB)
docker-compose --profile databases up| Service | Port | Description |
|---|---|---|
| visdb | 8080 | Main application |
| prometheus | 9090 | Metrics collection |
| grafana | 3001 | Dashboards (admin/admin) |
| postgres | 5432 | Sample PostgreSQL |
| mysql | 3306 | Sample MySQL |
| mongodb | 27017 | Sample MongoDB |
visDB exposes Prometheus metrics at /metrics:
visdb_requests_total- Total HTTP requestsvisdb_request_duration_seconds- Request latency histogramvisdb_introspection_duration_seconds- Schema introspection timevisdb_active_connections- Number of active DB connections
visDB/
├── api/ # OpenAPI specification
├── cmd/
│ ├── server/ # Application entrypoint
│ └── cli/ # CLI tool
├── internal/
│ ├── api/ # REST API handlers
│ ├── analysis/ # Schema analysis utilities
│ ├── audit/ # Audit logging
│ ├── auth/ # JWT authentication
│ ├── config/ # Environment configuration
│ ├── crypto/ # AES-256 encryption
│ ├── export/ # Export formatters (JSON, Markdown)
│ ├── introspection/ # Database schema extractors
│ ├── metrics/ # Prometheus instrumentation
│ ├── models/ # Domain entities
│ └── storage/ # Data persistence layer
├── web/ # React frontend
│ ├── src/
│ │ ├── components/ # UI components
│ │ ├── context/ # React contexts (Theme)
│ │ ├── hooks/ # Custom hooks (keyboard, history)
│ │ ├── pages/ # Route pages
│ │ ├── services/ # API client, layout algorithms
│ │ └── types/ # TypeScript interfaces
│ └── package.json
├── grafana/ # Grafana dashboard provisioning
├── specs/ # Project specifications
├── docker-compose.yaml # Docker Compose configuration
├── Dockerfile # Multi-stage Docker build
└── Makefile
visDB supports light and dark color schemes:
- Automatic: By default, follows your system preference (light/dark mode)
- Manual: Click the sun/moon icon in the header to toggle themes
- Persistent: Your choice is saved to localStorage and persists across sessions
The Overview panel in the bottom-right corner provides a bird's-eye view of your diagram:
- Navigate: Click anywhere in the minimap to instantly jump to that area
- Drag: Click and drag in the minimap for continuous panning
- Viewport: The white rectangle shows your current visible area
- Toggle: Click the X to collapse the minimap, or the icon to restore it
Choose from multiple automatic layout algorithms via the Layout dropdown:
- Grid: Tables arranged in a uniform grid pattern
- Hierarchical: Tables organized by relationship hierarchy (parent tables at top)
- Force-Directed: Physics-based layout that groups related tables together
- Circular: Tables arranged in a circle
- Select: Click a table to view its details in the side panel
- Drag: Click and drag any table to reposition it manually
- Collapse: Click the minus button on a table header to collapse it (shows only the table name)
- Expand: Click the plus button to expand a collapsed table
Focus on a single table and its directly related tables (1 hop via foreign keys):
- Enter: Press
Ior click the isolation toggle button (concentric circles icon) in the toolbar - Select: Click any table to isolate it—only tables connected by foreign keys remain visible
- Interact: Drag tables, zoom, pan, and export work normally on the isolated view
- Exit: Press
Iagain or click the "Exit" button in the isolation banner
This is useful for exploring complex schemas by focusing on one table's immediate relationships.
Press ? in the visualization canvas to see all shortcuts.
| Shortcut | Action |
|---|---|
Ctrl + + |
Zoom in |
Ctrl + - |
Zoom out |
Ctrl + 0 |
Reset zoom to 100% |
Ctrl + 1 |
Fit diagram to view |
Click + Drag |
Pan canvas |
Scroll |
Zoom in/out |
Click |
Select table |
Ctrl + A |
Select all tables |
Escape |
Deselect all / Close panel |
Ctrl + Z |
Undo |
Ctrl + Shift + Z |
Redo |
Ctrl + Y |
Redo (alternative) |
Ctrl + F |
Focus search |
/ |
Focus search (quick) |
I |
Toggle isolation mode |
? |
Show keyboard shortcuts |
All endpoints require JWT authentication via Authorization: Bearer <token> header.
| Method | Path | Description |
|---|---|---|
| POST | /api/auth/token |
Generate JWT token |
| Method | Path | Description | Role |
|---|---|---|---|
| GET | /api/connections |
List all connections | admin, viewer |
| POST | /api/connections |
Create connection | admin |
| GET | /api/connections/:id |
Get connection by ID | admin, viewer |
| DELETE | /api/connections/:id |
Delete connection | admin |
| POST | /api/connections/:id/test |
Test connection | admin, viewer |
| Method | Path | Description | Role |
|---|---|---|---|
| GET | /api/schema/:connection_id |
Get introspected schema | admin, viewer |
| Method | Path | Description | Role |
|---|---|---|---|
| GET | /api/connections/:id/visualizations |
List saved layouts | admin, viewer |
| POST | /api/visualizations |
Save layout | admin, viewer |
visDB is designed with security as a priority:
- Encryption at Rest: Database credentials are encrypted using AES-256-GCM before storage
- Encryption in Transit: All connections support SSL/TLS
- JWT Authentication: API access requires valid JWT tokens with role-based authorization
- No Data Access: Only schema metadata is retrieved—visDB never reads your actual data
- Input Validation: All form inputs are validated on both client and server
| Variable | Required | Description |
|---|---|---|
VISDB_ADDR |
No | Server listen address (default: :8080) |
VISDB_ENCRYPTION_KEY |
Yes | 32-byte hex key for AES-256 encryption |
VISDB_JWT_SECRET |
Yes | Secret for signing JWT tokens |
VISDB_DATABASE_URL |
No | Storage database URL (default: SQLite) |
| Database | Default Port | SSL Support | Notes |
|---|---|---|---|
| PostgreSQL | 5432 | Yes | Full schema introspection |
| MySQL | 3306 | Yes | Full schema introspection |
| SQLite | N/A | N/A | File-based databases |
| SQL Server | 1433 | Yes | Full schema introspection |
| MongoDB | 27017 | Yes | Document sampling for schema inference |
- Verify the database server is running and accessible
- Check that the host and port are correct
- Ensure your firewall allows connections on the database port
- Double-check your username and password
- Verify the user has permissions to access schema metadata
- For PostgreSQL, ensure the user can query
information_schema
- The database user needs read access to system catalogs
- For MySQL, grant
SELECToninformation_schema - For SQL Server, the user needs
VIEW DEFINITIONpermission
MIT

