0.9.25
What's Changed
Schema introspection reliability + correctness
LibreDB Studio 0.9.25 is a reliability-and-correctness release. Its headline is a fix for schema introspection timing out on large PostgreSQL schemas (the table tree could fail to load entirely), backed by 30+ new regression tests and a tightened quality bar (100% coverage on new code). It also rolls up everything since v0.9.19 — SQL identifier-quoting correctness fixes, a Railway one-click template, a Koyeb deploy path, dependency/toolchain upgrades, and a knip dead-code gate.
This is a cumulative release covering
0.9.20→0.9.25.v0.9.19was the previous GitHub Release.
Highlights — schema introspection no longer times out on large schemas (#71)
On schemas with 100+ tables, getSchema() ran a single query joining five information_schema CTEs. Because PostgreSQL 12+ inlines single-reference CTEs and estimates rows=1 for information_schema views, the planner chose nested-loop joins that re-executed the expensive FK/index CTEs many times — ballooning to ~295s and always hitting the connection's 60s statement_timeout. The schema tree never loaded.
Two complementary fixes:
-
AS MATERIALIZEDCTEs — each CTE is now computed once instead of being re-executed inside nested loops. ~295s → ~2.6s on a 122-table schema. -
Two-phase schema loading so a slow/failing stats query can never block the table list:
getSchemaList()→ tables + columns + PKs (fast, ~50ms) —/api/db/schema/listgetSchemaRelations()→ foreign keys + indexes (heavy, ~2.3s) —/api/db/schema/relations
The explorer renders the tree from the fast list immediately, then merges relationships asynchronously. If the relations query fails or times out, it's logged and skipped — the table list stays intact. New optional provider methods fall back to
getSchema()/[]for databases that don't implement the fast path, so non-PostgreSQL engines are unaffected.
Database correctness fixes
- Cross-schema foreign keys no longer dropped (#71) — FK introspection joined
constraint_column_usageontable_schema(the referenced table's schema), silently discarding any foreign key that crossed schemas. Now joined on the constraint's own schema. - Schema-qualified identifier quoting, per-segment (#70) —
schema.tableidentifiers are quoted segment-by-segment so each part is escaped correctly. - Dialect-aware identifier quoting in generated queries, and quoted identifiers in the PostgreSQL table-stats monitoring query.
Testing & code quality
- 30+ new regression tests locking in the two-phase loading contract: provider methods (
getSchemaList/getSchemaRelations, incl. cross-schema prefixing, empty/null edge cases), both new API routes (auth, validation, provider fallbacks, error mapping), and the client hook's resilience guarantee (relations failure must not wipe the table list). - 100% coverage on new code and a green SonarCloud quality gate (duplication brought under threshold via shared CTE fragments and a shared route handler).
knipdead-code gate added to CI — removed unused dependencies and dead barrel re-exports; configured entry points/scope.- Merged-lcov fix — strip non-executable lines so coverage reporting is accurate.
Deployment & distribution
- Railway one-click template —
template.jsonservice definition, logo, per-variable descriptions, and a published Deploy on Railway button. - Koyeb — fixed the deploy-button storage default and added a catalog submission guide.
Dependencies & toolchain
- Dependency refresh with TypeScript 6 adaptation;
better-sqlite312.10.1; Node.js/Bun pins retained (24.16.0/1.3.14); base imagenode:24.16.0-trixie-slim.
Docs
- Consolidated overlapping guides and archived shipped plans; added an enterprise-features roadmap and Kubernetes/Helm setup docs; aligned Node/Bun versions across templates and CONTRIBUTING.
Upgrade notes
- No breaking changes. Drop-in upgrade for both standalone and embedded (
@libredb/studio) usage. - The schema explorer now calls two new endpoints (
/api/db/schema/list,/api/db/schema/relations). The legacy/api/db/schemaendpoint is retained for full-schema consumers (diff, AI context). - Self-hosters on PostgreSQL with large schemas should see the table tree load in seconds instead of timing out.
Install
# Docker (GHCR — primary, no pull rate limits)
docker pull ghcr.io/libredb/libredb-studio:0.9.25
# npm package (embed in your app)
npm install @libredb/studio@0.9.25
# Helm
helm repo add libredb https://libredb.org/libredb-studio/
helm install libredb-studio libredb/libredb-studioThanks to everyone using and contributing to LibreDB Studio. Issues and PRs are welcome at https://github.com/libredb/libredb-studio.
Full Changelog: v0.9.19...v0.9.25