A minimal open-source Postgres visualizer with AI-powered SQL generation, built with React, Next.js, and Tailwind CSS. Inspired by Supabase SQL Editor and Navicat.
- SQL Editor: Monaco Editor with syntax highlighting and Shift+Enter execution
- Query Results: Paginated table view (50 rows/page) with JSON fallback
- AI Assistant: Natural language to SQL conversion powered by Gemini 2.0 Flash
- Schema Explorer: Auto-fetch and display database tables and columns
- Resizable Panels: Drag the divider to adjust AI panel width
- Dark Mode: Supabase-inspired dark theme
- Read-Only Mode: Blocks destructive operations (DROP, DELETE, UPDATE, INSERT)
- Frontend: Next.js 14 (App Router), React 18, TypeScript
- Styling: Tailwind CSS
- Editor: Monaco Editor
- Database: PostgreSQL (pg library)
- AI: Google Gemini 2.0 Flash
- Node.js 18+ and npm
- PostgreSQL database access
- Gemini API key (get from https://ai.google.dev/)
npm installCreate a .env.local file and add your credentials:
# PostgreSQL Database
DB_HOST=your-database-host.rds.amazonaws.com
DB_PORT=5432
DB_NAME=your-database-name
DB_USER=your-database-user
DB_PASSWORD=your-database-password
DB_SSL=true
# Gemini API
GEMINI_API_KEY=your-gemini-api-key-hereImportant: Replace all placeholder values with your actual database credentials and API key. You can reference .env.example for the template.
npm run devOpen http://localhost:3000 in your browser.
npm run build
npm start- Type SQL queries in the Monaco Editor (left panel)
- Press Shift + Enter to execute
- View results in the bottom panel
- Type a natural language request in the AI Assistant (right panel)
- Click Send to generate SQL
- Click Copy to Editor to insert generated SQL into the editor
- Press Shift + Enter to run the query
- View all database tables and columns
- Expand/collapse tables to see column details
- Schema is automatically provided to AI for context-aware SQL generation
- Drag the vertical divider between the main panel and AI panel to adjust width
- Right panel width ranges from 300px to 800px
- Width preference is maintained during the session
-- Get first 10 rows from users table
SELECT * FROM users LIMIT 10;
-- Count total users
SELECT COUNT(*) as total_users FROM users;
-- Get users created in last 7 days
SELECT id, email, created_at
FROM users
WHERE created_at >= NOW() - INTERVAL '7 days'
ORDER BY created_at DESC;Input: "Show me all users who signed up in the last month"
Output:
SELECT * FROM users
WHERE created_at >= NOW() - INTERVAL '1 month'
ORDER BY created_at DESC
LIMIT 100;Input: "Count users by country"
Output:
SELECT country, COUNT(*) as user_count
FROM users
GROUP BY country
ORDER BY user_count DESC
LIMIT 100;Input: "Find users with email containing 'gmail'"
Output:
SELECT id, email, created_at
FROM users
WHERE email ILIKE '%gmail%'
LIMIT 100;postgres-ai/
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Main visualizer page
│ │ ├── globals.css # Tailwind + custom styles
│ │ └── api/
│ │ ├── sql/route.ts # Execute SQL queries
│ │ ├── ai/route.ts # Generate SQL from NL
│ │ └── schema/route.ts # Fetch database schema
│ ├── components/
│ │ ├── SQLEditor.tsx # Monaco editor wrapper
│ │ ├── ResultsPanel.tsx # Query results display
│ │ ├── AIAssistant.tsx # Gemini chat interface
│ │ └── SchemaExplorer.tsx # Database schema browser
│ ├── lib/
│ │ ├── db.ts # Postgres connection pool
│ │ └── gemini.ts # AI integration
│ └── types/
│ └── index.ts # TypeScript types
├── .env.local # Environment variables
├── package.json
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
└── README.md
- Read-Only Mode: Blocks DROP, DELETE, UPDATE, INSERT, ALTER, CREATE operations
- Parameterized Queries: Prevents SQL injection
- Connection Pooling: Singleton pattern with max 20 connections
- SSL Support: Secure database connections
- Query Timeout: 5 seconds connection timeout
- Server-Side API: Database credentials never exposed to client
- Shift + Enter: Execute SQL query in the editor
- Drag divider: Resize the AI panel width (between main and right panel)
If you see "Failed to fetch schema" or query execution errors:
- Verify database credentials in
.env.local - Check if database allows connections from your IP
- Ensure PostgreSQL is running
- Verify SSL settings (
DB_SSL=truefor RDS)
If AI generation fails:
- Verify
GEMINI_API_KEYin.env.local - Check API quota at https://ai.google.dev/
- Ensure you're using
gemini-2.0-flashmodel
- Clear
.nextcache:rm -rf .next - Reinstall dependencies:
rm -rf node_modules && npm install - Restart dev server
- Monaco Editor runs client-side (
"use client"directive) - API routes are server-side with database access
- Hot reload preserves pg Pool singleton
- Dark mode is default (no toggle needed)
MIT
Contributions welcome! Open issues or submit PRs.