betocmn/widen

Postgres GUI using the LLM already on your Mac. Free, open-source native macOS database GUI using Apple's on-device Foundation Model for text-to-sql.

24

stars

684

commits

Swift

primary language

Sep 2, 2026

updated

widen.dev
apple
database-gui
databases
llms
local-model
postgres
supabase
text-to-sql
Browse cluster: LLM Tool Integration & SDKs

README

Widen

CI CodeQL License: MIT PRs Welcome

Open-source, native Postgres GUI for macOS. Ask questions in English; review the SQL before it runs.

Widen — Postgres SQL agent for macOS

Download for Mac · Build from source · Privacy · Contributing · Security · Release notes

macOS 14+ · Text-to-SQL: beta · Cloud-first text-to-SQL · Optional local AI on macOS 26+ · No backend · No account · MIT · Postgres-only MVP

Widen is an open-source, native Postgres GUI for macOS 14+. It reads your schema and can draft SQL from a question using a cloud model you configure. On eligible macOS 26+ Apple Silicon Macs, Widen can also use Apple's on-device Foundation Model. It shows the SQL before anything runs, so you can review or edit it first.

It is not an autonomous database agent. Widen drafts SQL, validates it, and waits for you to decide whether to run it. Text-to-SQL is beta: it must pass a published release gate before we describe it as production-ready, and that gate currently fails — see why text-to-SQL is beta.

What leaves your Mac?

No Widen backend. No account. No analytics. Out of the box, Widen can browse schemas and run manual SQL with only the PostgreSQL connection you configure. Cloud text-to-SQL requires a provider you configure in Settings; cloud generation is the default text-to-SQL path because it works on older supported Macs and can handle broader schemas.

ModeSchema/questionQuery resultsNotes
Cloud modeQuestion and allowed schema metadata are sent to the provider you chooseStays on your Mac unless cloud data inspection is enabled for that connectionDefault text-to-SQL backend. Fresh installs default to the fixed OpenRouter GPT-5.5 profile (you supply the OpenRouter API key) and schema-tool agent. OpenRouter requests require zero-data-retention endpoints and deny provider data collection.
Local modeStays on your MacStays on your MacOptional on eligible macOS 26+ Apple Silicon Macs with Apple Intelligence enabled. Best suited to narrow requests over simple databases.

Passwords and API keys live in the macOS Keychain, never on disk in plaintext.

Why text-to-SQL is beta (and how we'll know it isn't)

Text-to-SQL ships behind a hard release gate: 60 pinned-model gate results with at least 90% end-to-end semantic pass rate, 100% safety validity, 100% schema validity, 100% clarification decision accuracy, at least 95% transport reliability, and zero repeated-repair failures. The gate currently fails on semantic pass rate, so text-to-SQL stays beta and should not be described as production-ready until it passes.

The cloud model is pinned to the evaluated openai/gpt-5.5 version. If the provider's alias starts resolving to a version Widen has not evaluated, cloud generation fails closed rather than silently running an unevaluated model.

We publish negative results: pre-registered, paid gate experiments that fail their criteria are reverted and documented. See how we gate releases for the design and the experiment log, and the release-gate report for the committed numbers. Run the gate yourself with make eval-release; contributor-facing eval mechanics live in Evals/README.md. Manual SQL editing, schema browsing, and normal database work remain supported independently of AI backend configuration.

Review before run

Every statement, whether typed manually or drafted by the model, goes through the same deterministic safety validator:

  • One statement only.
  • SELECT/WITH reads, or explicit INSERT/UPDATE/DELETE writes.
  • No DDL, transaction keywords, semicolon chains, pg_sleep, dblink, or large-object calls.
  • Statement timeouts and row caps apply at execution time.
  • Writes are never auto-run, and Widen asks for confirmation before DELETE or an UPDATE without a WHERE.

If you only want reads, connect with a read-only Postgres user. The app-level guardrails are useful, but database permissions are the real boundary.

Install

Download the latest signed and notarized DMG:

https://github.com/betocmn/widen/releases/latest/download/Widen.dmg

Open Widen.dmg, drag Widen into Applications, and launch it. Sparkle updates are served from GitHub Releases.

RequirementNotes
macOS 14 or laterRequired to install and launch Widen.
Apple SiliconRequired only for Apple's optional on-device Foundation Model.
Apple Intelligence enabledRequired only for local AI generation. Manual SQL and cloud models still work without it.
PostgreSQLWiden is Postgres-only today. Postgres.app works well for local testing.
Xcode 26Needed when building from source.

Sample database for exploring the app

This is only for trying the app by hand — the integration tests (make test-db) provision and drop their own throwaway databases and do not need it.

With Postgres.app running (its default server on localhost:5432):

createdb widen_test
psql -d widen_test -f scripts/sample_db.sql

If psql is not on your PATH, use the bundled one, e.g. /Applications/Postgres.app/Contents/Versions/17/bin/psql.

The script creates a tiny shop dataset:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  email TEXT NOT NULL,
  name TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id),
  total_cents INTEGER NOT NULL,
  status TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

plus a few rows. Good first questions to try:

  • "Show me all users."
  • "Show the 10 most recent orders."
  • "Which users have spent the most?"
  • "Count orders by status."
  • "Show revenue by day."
  • "Show customers with no orders."

Connecting

On first launch, click Add Database to open Settings › Databases. For a default Postgres.app setup: host localhost, port 5432, database widen_test, username = your macOS username, empty password (Postgres.app uses trust auth locally), SSL mode Disabled. Add as many databases as you like with the "+" button; deleting one warns you first — its sessions are deleted with it.

Postgres.app asks once per client app before allowing a connection. If a connection seems to hang, check Postgres.app's Settings > Client Applications and allow Widen.

Safety tip: Widen runs the SQL you approve, including writes — it never auto-runs a write, and DELETE or UPDATE-without-WHERE asks you to confirm first. If you only want reads, connect with a read-only Postgres user; defense in depth is cheap.

Non-secret connection settings are stored in ~/Library/Application Support/Widen/connections.json; passwords are stored in the macOS Keychain (service Widen).

Built for people who live in Postgres

Widen is a lightweight, native Postgres workbench for browsing schemas, keeping query sessions, and turning questions into SQL:

  • Configure any number of PostgreSQL connections in Settings.
  • Browse the selected database's schemas, tables, columns, types, and foreign keys in the inspector.
  • Keep persistent chat + SQL + results sessions that survive restarts.
  • Switch between Cloud and Local from the toolbar when local AI is available.
  • Use a modern macOS interface with light/dark appearance and Liquid Glass on macOS 26+.

Known limitations

  • PostgreSQL only.
  • Early MVP, not full DataGrip/TablePlus/Postico feature parity.
  • Cloud text-to-SQL is beta and requires your own provider setup. Widen defaults to OpenRouter with the fixed openai/gpt-5.5 profile (you supply the OpenRouter API key). Custom OpenRouter model selection is not exposed; changing the evaluated model version requires a new app release and release-gate evaluation. Apple Private Cloud Compute support is planned when Apple's required OS and SDK support is available.
  • The optional local Foundation Model requires eligible macOS 26+ Apple Silicon hardware and has a small context window; very large schemas are truncated whole-table-at-a-time before prompting.
  • Results are rendered as text values; typed grid behavior is still limited.
  • Export is CSV-only today.
  • No SQL syntax highlighting yet.
  • Query results are not persisted across restarts. Transcripts, SQL text, and generation metadata are persisted; rerun a session's query to repopulate the grid.

Sessions

Each database in the sidebar lists its query sessions. Selecting the database itself opens its schema in the inspector; press the hover "+" (or Cmd+N) to start a session — the database connects lazily, so nothing happens until a session or schema browse needs it. A session keeps its chat transcript (including run records), active SQL, and generation metadata in ~/Library/Application Support/Widen/sessions.json (query results are deliberately not persisted). The local model names the session after your first question; rename it manually (right-click › Rename) and the auto-name never overwrites yours. Right-click › Archive hides a session; restore it or delete it forever from Settings › Archived Sessions.

The schema browser lives in a right-hand inspector — toggle it from the toolbar. The toolbar breadcrumb (database › schema) and the inspector's picker both switch the open schema; the table list and the AI's context are scoped to it. Schema snapshots are cached in ~/Library/Application Support/Widen/schemas.json so the last known schema is available immediately on relaunch; Refresh Schema fetches the live structure and updates that cache. The sun/moon button in the sidebar footer flips light/dark mode; pick "System" in Settings › General to follow macOS again.

How a query runs

  1. You type into the composer: a plain-English question, or raw SQL (SELECT/WITH reads and SQL-shaped INSERT INTO, UPDATE ... SET, or DELETE FROM writes skip the model entirely).
  2. For questions, Widen prompts the selected backend with the open schema's allowed tables, columns, types, and foreign keys (system schemas excluded) plus the safety rules, and gets structured output back: SQL, explanation, assumptions, referenced tables, confidence, and risk level.
  3. The SQL appears in the chat as a dashed card, validated deterministically: only one read or INSERT/UPDATE/DELETE statement, no semicolons, no DDL/transaction keywords, no pg_sleep/dblink/lo_*. Validation issues sit behind the card's status icon. Keep chatting (or paste corrected SQL) until it's right.
  4. Run executes reads in a BEGIN READ ONLY transaction and writes in a normal transaction with SET LOCAL statement_timeout (default 10s). Read queries without a LIMIT are wrapped in a subquery with your default row limit (default 100).
  5. The results flow into the same chat thread: a bordered table card appears where the run happened (first 10 rows, "View more" for the rest), with Copy as CSV and Export CSV. Every run is recorded in the transcript, and the conversation just keeps going underneath.

Keyboard: Enter in the composer submits (Option+Enter for a newline); Cmd+Enter runs the active SQL; Cmd+N starts a new session; Cmd+R refreshes the active database's schema; Cmd+, opens Settings.

Build and run

The Makefile pins DEVELOPER_DIR to /Applications/Xcode-26.app. If your Xcode 26 lives elsewhere (e.g. it is your default /Applications/Xcode.app), override it: make build DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer.

make project   # regenerate Widen.xcodeproj from project.yml (needs xcodegen)
make build     # build the app (Debug)
make run       # build and launch Widen.app
make test      # unit tests
make test-db   # unit + Postgres integration tests (needs a local Postgres server)
make test-fm   # unit + on-device Foundation Models smoke test
make xcode     # open the project in Xcode 26

The committed Widen.xcodeproj is generated - edit project.yml and run make project instead of editing project settings by hand. If you open the project in Xcode directly, make sure it is Xcode 26, not an older default Xcode. Widen targets macOS 14, while optional Foundation Models code is compiled behind macOS 26 availability checks.

Release packaging

Release packaging is automated for Developer ID distribution. Debug stays ad-hoc signed for local development. The release script reads local signing, notarizing, bundle ID, and Sparkle values from environment variables or .env.release.local:

cp .env.release.example .env.release.local
make release-mac

See docs/release.md for the full signed DMG, Sparkle, and static website release runbook.

For codebase onboarding, implementation details, and development caveats (local code signing, sandbox status, SSL modes), see docs/implementation-guide.md.

Open source

Widen is MIT licensed and developed in the open. Start with CONTRIBUTING.md for local setup, testing expectations, and the safety/privacy rules contributors should preserve. See PRIVACY.md for the data-flow summary and SECURITY.md for vulnerability reporting.

License

MIT - see LICENSE.

Contributors

betocmn

684 commits

betocmn/widen

Postgres GUI using the LLM already on your Mac. Free, open-source native macOS database GUI using Apple's on-device Foundation Model for text-to-sql.

24

stars

684

commits

Swift

primary language

Sep 2, 2026

updated

widen.dev
apple
database-gui
databases
llms
local-model
postgres
supabase
text-to-sql
Browse cluster: LLM Tool Integration & SDKs

README

Widen

CI CodeQL License: MIT PRs Welcome

Open-source, native Postgres GUI for macOS. Ask questions in English; review the SQL before it runs.

Widen — Postgres SQL agent for macOS

Download for Mac · Build from source · Privacy · Contributing · Security · Release notes

macOS 14+ · Text-to-SQL: beta · Cloud-first text-to-SQL · Optional local AI on macOS 26+ · No backend · No account · MIT · Postgres-only MVP

Widen is an open-source, native Postgres GUI for macOS 14+. It reads your schema and can draft SQL from a question using a cloud model you configure. On eligible macOS 26+ Apple Silicon Macs, Widen can also use Apple's on-device Foundation Model. It shows the SQL before anything runs, so you can review or edit it first.

It is not an autonomous database agent. Widen drafts SQL, validates it, and waits for you to decide whether to run it. Text-to-SQL is beta: it must pass a published release gate before we describe it as production-ready, and that gate currently fails — see why text-to-SQL is beta.

What leaves your Mac?

No Widen backend. No account. No analytics. Out of the box, Widen can browse schemas and run manual SQL with only the PostgreSQL connection you configure. Cloud text-to-SQL requires a provider you configure in Settings; cloud generation is the default text-to-SQL path because it works on older supported Macs and can handle broader schemas.

ModeSchema/questionQuery resultsNotes
Cloud modeQuestion and allowed schema metadata are sent to the provider you chooseStays on your Mac unless cloud data inspection is enabled for that connectionDefault text-to-SQL backend. Fresh installs default to the fixed OpenRouter GPT-5.5 profile (you supply the OpenRouter API key) and schema-tool agent. OpenRouter requests require zero-data-retention endpoints and deny provider data collection.
Local modeStays on your MacStays on your MacOptional on eligible macOS 26+ Apple Silicon Macs with Apple Intelligence enabled. Best suited to narrow requests over simple databases.

Passwords and API keys live in the macOS Keychain, never on disk in plaintext.

Why text-to-SQL is beta (and how we'll know it isn't)

Text-to-SQL ships behind a hard release gate: 60 pinned-model gate results with at least 90% end-to-end semantic pass rate, 100% safety validity, 100% schema validity, 100% clarification decision accuracy, at least 95% transport reliability, and zero repeated-repair failures. The gate currently fails on semantic pass rate, so text-to-SQL stays beta and should not be described as production-ready until it passes.

The cloud model is pinned to the evaluated openai/gpt-5.5 version. If the provider's alias starts resolving to a version Widen has not evaluated, cloud generation fails closed rather than silently running an unevaluated model.

We publish negative results: pre-registered, paid gate experiments that fail their criteria are reverted and documented. See how we gate releases for the design and the experiment log, and the release-gate report for the committed numbers. Run the gate yourself with make eval-release; contributor-facing eval mechanics live in Evals/README.md. Manual SQL editing, schema browsing, and normal database work remain supported independently of AI backend configuration.

Review before run

Every statement, whether typed manually or drafted by the model, goes through the same deterministic safety validator:

  • One statement only.
  • SELECT/WITH reads, or explicit INSERT/UPDATE/DELETE writes.
  • No DDL, transaction keywords, semicolon chains, pg_sleep, dblink, or large-object calls.
  • Statement timeouts and row caps apply at execution time.
  • Writes are never auto-run, and Widen asks for confirmation before DELETE or an UPDATE without a WHERE.

If you only want reads, connect with a read-only Postgres user. The app-level guardrails are useful, but database permissions are the real boundary.

Install

Download the latest signed and notarized DMG:

https://github.com/betocmn/widen/releases/latest/download/Widen.dmg

Open Widen.dmg, drag Widen into Applications, and launch it. Sparkle updates are served from GitHub Releases.

RequirementNotes
macOS 14 or laterRequired to install and launch Widen.
Apple SiliconRequired only for Apple's optional on-device Foundation Model.
Apple Intelligence enabledRequired only for local AI generation. Manual SQL and cloud models still work without it.
PostgreSQLWiden is Postgres-only today. Postgres.app works well for local testing.
Xcode 26Needed when building from source.

Sample database for exploring the app

This is only for trying the app by hand — the integration tests (make test-db) provision and drop their own throwaway databases and do not need it.

With Postgres.app running (its default server on localhost:5432):

createdb widen_test
psql -d widen_test -f scripts/sample_db.sql

If psql is not on your PATH, use the bundled one, e.g. /Applications/Postgres.app/Contents/Versions/17/bin/psql.

The script creates a tiny shop dataset:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  email TEXT NOT NULL,
  name TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id),
  total_cents INTEGER NOT NULL,
  status TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

plus a few rows. Good first questions to try:

  • "Show me all users."
  • "Show the 10 most recent orders."
  • "Which users have spent the most?"
  • "Count orders by status."
  • "Show revenue by day."
  • "Show customers with no orders."

Connecting

On first launch, click Add Database to open Settings › Databases. For a default Postgres.app setup: host localhost, port 5432, database widen_test, username = your macOS username, empty password (Postgres.app uses trust auth locally), SSL mode Disabled. Add as many databases as you like with the "+" button; deleting one warns you first — its sessions are deleted with it.

Postgres.app asks once per client app before allowing a connection. If a connection seems to hang, check Postgres.app's Settings > Client Applications and allow Widen.

Safety tip: Widen runs the SQL you approve, including writes — it never auto-runs a write, and DELETE or UPDATE-without-WHERE asks you to confirm first. If you only want reads, connect with a read-only Postgres user; defense in depth is cheap.

Non-secret connection settings are stored in ~/Library/Application Support/Widen/connections.json; passwords are stored in the macOS Keychain (service Widen).

Built for people who live in Postgres

Widen is a lightweight, native Postgres workbench for browsing schemas, keeping query sessions, and turning questions into SQL:

  • Configure any number of PostgreSQL connections in Settings.
  • Browse the selected database's schemas, tables, columns, types, and foreign keys in the inspector.
  • Keep persistent chat + SQL + results sessions that survive restarts.
  • Switch between Cloud and Local from the toolbar when local AI is available.
  • Use a modern macOS interface with light/dark appearance and Liquid Glass on macOS 26+.

Known limitations

  • PostgreSQL only.
  • Early MVP, not full DataGrip/TablePlus/Postico feature parity.
  • Cloud text-to-SQL is beta and requires your own provider setup. Widen defaults to OpenRouter with the fixed openai/gpt-5.5 profile (you supply the OpenRouter API key). Custom OpenRouter model selection is not exposed; changing the evaluated model version requires a new app release and release-gate evaluation. Apple Private Cloud Compute support is planned when Apple's required OS and SDK support is available.
  • The optional local Foundation Model requires eligible macOS 26+ Apple Silicon hardware and has a small context window; very large schemas are truncated whole-table-at-a-time before prompting.
  • Results are rendered as text values; typed grid behavior is still limited.
  • Export is CSV-only today.
  • No SQL syntax highlighting yet.
  • Query results are not persisted across restarts. Transcripts, SQL text, and generation metadata are persisted; rerun a session's query to repopulate the grid.

Sessions

Each database in the sidebar lists its query sessions. Selecting the database itself opens its schema in the inspector; press the hover "+" (or Cmd+N) to start a session — the database connects lazily, so nothing happens until a session or schema browse needs it. A session keeps its chat transcript (including run records), active SQL, and generation metadata in ~/Library/Application Support/Widen/sessions.json (query results are deliberately not persisted). The local model names the session after your first question; rename it manually (right-click › Rename) and the auto-name never overwrites yours. Right-click › Archive hides a session; restore it or delete it forever from Settings › Archived Sessions.

The schema browser lives in a right-hand inspector — toggle it from the toolbar. The toolbar breadcrumb (database › schema) and the inspector's picker both switch the open schema; the table list and the AI's context are scoped to it. Schema snapshots are cached in ~/Library/Application Support/Widen/schemas.json so the last known schema is available immediately on relaunch; Refresh Schema fetches the live structure and updates that cache. The sun/moon button in the sidebar footer flips light/dark mode; pick "System" in Settings › General to follow macOS again.

How a query runs

  1. You type into the composer: a plain-English question, or raw SQL (SELECT/WITH reads and SQL-shaped INSERT INTO, UPDATE ... SET, or DELETE FROM writes skip the model entirely).
  2. For questions, Widen prompts the selected backend with the open schema's allowed tables, columns, types, and foreign keys (system schemas excluded) plus the safety rules, and gets structured output back: SQL, explanation, assumptions, referenced tables, confidence, and risk level.
  3. The SQL appears in the chat as a dashed card, validated deterministically: only one read or INSERT/UPDATE/DELETE statement, no semicolons, no DDL/transaction keywords, no pg_sleep/dblink/lo_*. Validation issues sit behind the card's status icon. Keep chatting (or paste corrected SQL) until it's right.
  4. Run executes reads in a BEGIN READ ONLY transaction and writes in a normal transaction with SET LOCAL statement_timeout (default 10s). Read queries without a LIMIT are wrapped in a subquery with your default row limit (default 100).
  5. The results flow into the same chat thread: a bordered table card appears where the run happened (first 10 rows, "View more" for the rest), with Copy as CSV and Export CSV. Every run is recorded in the transcript, and the conversation just keeps going underneath.

Keyboard: Enter in the composer submits (Option+Enter for a newline); Cmd+Enter runs the active SQL; Cmd+N starts a new session; Cmd+R refreshes the active database's schema; Cmd+, opens Settings.

Build and run

The Makefile pins DEVELOPER_DIR to /Applications/Xcode-26.app. If your Xcode 26 lives elsewhere (e.g. it is your default /Applications/Xcode.app), override it: make build DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer.

make project   # regenerate Widen.xcodeproj from project.yml (needs xcodegen)
make build     # build the app (Debug)
make run       # build and launch Widen.app
make test      # unit tests
make test-db   # unit + Postgres integration tests (needs a local Postgres server)
make test-fm   # unit + on-device Foundation Models smoke test
make xcode     # open the project in Xcode 26

The committed Widen.xcodeproj is generated - edit project.yml and run make project instead of editing project settings by hand. If you open the project in Xcode directly, make sure it is Xcode 26, not an older default Xcode. Widen targets macOS 14, while optional Foundation Models code is compiled behind macOS 26 availability checks.

Release packaging

Release packaging is automated for Developer ID distribution. Debug stays ad-hoc signed for local development. The release script reads local signing, notarizing, bundle ID, and Sparkle values from environment variables or .env.release.local:

cp .env.release.example .env.release.local
make release-mac

See docs/release.md for the full signed DMG, Sparkle, and static website release runbook.

For codebase onboarding, implementation details, and development caveats (local code signing, sandbox status, SSL modes), see docs/implementation-guide.md.

Open source

Widen is MIT licensed and developed in the open. Start with CONTRIBUTING.md for local setup, testing expectations, and the safety/privacy rules contributors should preserve. See PRIVACY.md for the data-flow summary and SECURITY.md for vulnerability reporting.

License

MIT - see LICENSE.

Contributors

betocmn

684 commits

Languages

Swift

98.9%