diff --git a/public/engines/bigquery.svg b/public/engines/bigquery.svg
new file mode 100644
index 0000000..e86b7d8
--- /dev/null
+++ b/public/engines/bigquery.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/firestore.svg b/public/engines/firestore.svg
new file mode 100644
index 0000000..78f0d46
--- /dev/null
+++ b/public/engines/firestore.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/kubernetes.svg b/public/engines/kubernetes.svg
new file mode 100644
index 0000000..570866a
--- /dev/null
+++ b/public/engines/kubernetes.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/modbus.svg b/public/engines/modbus.svg
new file mode 100644
index 0000000..cd8afc3
--- /dev/null
+++ b/public/engines/modbus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/mqtt.svg b/public/engines/mqtt.svg
new file mode 100644
index 0000000..2542eea
--- /dev/null
+++ b/public/engines/mqtt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/mtconnect.svg b/public/engines/mtconnect.svg
new file mode 100644
index 0000000..ef4d586
--- /dev/null
+++ b/public/engines/mtconnect.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/netconf.svg b/public/engines/netconf.svg
new file mode 100644
index 0000000..8f01cd1
--- /dev/null
+++ b/public/engines/netconf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/opcua.svg b/public/engines/opcua.svg
new file mode 100644
index 0000000..3693c2b
--- /dev/null
+++ b/public/engines/opcua.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/rabbitmq.svg b/public/engines/rabbitmq.svg
new file mode 100644
index 0000000..d9bdfbd
--- /dev/null
+++ b/public/engines/rabbitmq.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/s3.svg b/public/engines/s3.svg
new file mode 100644
index 0000000..d2c272c
--- /dev/null
+++ b/public/engines/s3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/snmp.svg b/public/engines/snmp.svg
new file mode 100644
index 0000000..aac9e01
--- /dev/null
+++ b/public/engines/snmp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/snowflake.svg b/public/engines/snowflake.svg
new file mode 100644
index 0000000..5aeaba6
--- /dev/null
+++ b/public/engines/snowflake.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/spark.svg b/public/engines/spark.svg
new file mode 100644
index 0000000..2768215
--- /dev/null
+++ b/public/engines/spark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/engines/sparkplug.svg b/public/engines/sparkplug.svg
new file mode 100644
index 0000000..6ece9d9
--- /dev/null
+++ b/public/engines/sparkplug.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/site.config.json b/site.config.json
index 464e195..9728310 100644
--- a/site.config.json
+++ b/site.config.json
@@ -4,7 +4,7 @@
"url": "https://libredb.org",
"domain": "libredb.org",
"tagline": "The database editor that deploys next to your data.",
- "description": "LibreDB Studio is the open-source database IDE that deploys next to your data instead of onto your laptop — one browser tab for PostgreSQL, MySQL, MongoDB, Redis and twenty-three more engines, with SSO and audit built in.",
+ "description": "LibreDB Studio is the open-source database IDE that deploys next to your data instead of onto your laptop — one browser tab for PostgreSQL, MySQL, MongoDB, Redis and thirty-seven more engines, with SSO and audit built in.",
"version": "1.0.0",
"license": "MIT",
"company": "Sekoya Grup Bilişim ve Teknoloji Ltd. Şti., İstanbul",
diff --git a/src/data/compare.ts b/src/data/compare.ts
index ee4a650..fc8a682 100644
--- a/src/data/compare.ts
+++ b/src/data/compare.ts
@@ -98,7 +98,7 @@ export const consequences: Consequence[] = [
{
question: 'Working across several engines at once',
desktop: 'Depends on the tool; often several tools.',
- beside: 'Twenty-seven engines behind one tab and one grid.',
+ beside: 'Forty-one engines behind one tab and one grid.',
},
];
diff --git a/src/data/engines.ts b/src/data/engines.ts
index 52df82c..0804056 100644
--- a/src/data/engines.ts
+++ b/src/data/engines.ts
@@ -1,5 +1,5 @@
/**
- * Every engine shown in the hexagon grid and on /databases: the twenty-seven
+ * Every engine shown in the hexagon grid and on /databases: the forty-one
* external engines of libredb-studio's `EXTERNAL_DATABASE_TYPES`
* (src/lib/db/compatibility.ts), plus LibreDB, the embedded store the product
* carries, which is flagged `embedded` and is not counted.
@@ -17,6 +17,10 @@
*/
export type EngineCategory =
| 'SQL'
+ | 'Industrial'
+ | 'Network'
+ | 'Platform'
+ | 'Object store'
| 'Analytics'
| 'Federated'
| 'Document'
@@ -296,6 +300,132 @@ export const engines: Engine[] = [
tr: 'kafka \u00b7 9092',
not: 'Read-only: it reads records, it does not produce them.',
},
+ {
+ id: 'bigquery',
+ name: 'BigQuery',
+ cat: 'Analytics',
+ logo: '/engines/bigquery.svg',
+ desc: 'GoogleSQL over the REST API v2 with no Google SDK: datasets with their tables and views, a free dry-run Explain, and the bytes a statement will process shown before it runs.',
+ tr: 'REST API v2 \u00b7 https',
+ not: 'No Google SDK is used, so anything the REST API does not expose is not there.',
+ },
+ {
+ id: 'snowflake',
+ name: 'Snowflake',
+ cat: 'Analytics',
+ logo: '/engines/snowflake.svg',
+ desc: 'The SQL API v2 with Studio\u2019s own client and no Snowflake driver: every statement is one asynchronous request, signed with a key-pair JWT or a programmatic access token.',
+ tr: 'SQL API v2 \u00b7 https',
+ not: 'No driver, so driver-only features such as PUT and GET file transfer are absent.',
+ },
+ {
+ id: 'spark',
+ name: 'Apache Spark',
+ cat: 'Federated',
+ logo: '/engines/spark.svg',
+ desc: 'Spark Connect over gRPC: catalogs, databases and tables in the browser, and Spark SQL in the editor.',
+ tr: 'Spark Connect gRPC \u00b7 15002',
+ not: 'A session a server cannot release is remembered by its id rather than silently reused.',
+ },
+ {
+ id: 'firestore',
+ name: 'Firestore',
+ cat: 'Document',
+ logo: '/engines/firestore.svg',
+ desc: 'Read-only access to a database in Native mode over the Firestore REST API v1, with no Google SDK: collections, documents and their fields.',
+ tr: 'REST API v1 \u00b7 https',
+ not: 'Read-only: it reads documents, it never writes one.',
+ },
+ {
+ id: 'rabbitmq',
+ name: 'RabbitMQ',
+ cat: 'Streaming',
+ logo: '/engines/rabbitmq.svg',
+ desc: 'Read-only: the management HTTP API for the tree, the details and the health panel, and an AMQP 0-9-1 client of Studio\u2019s own for stream messages.',
+ tr: 'management HTTP API \u00b7 15672',
+ not: 'The AMQP client can encode no publish, take or delete, so a write cannot be expressed.',
+ },
+ {
+ id: 'mqtt',
+ name: 'MQTT',
+ cat: 'Streaming',
+ logo: '/engines/mqtt.svg',
+ desc: 'Read-only access to a broker\u2019s topic tree over MQTT 5.0: one discovery subscription collects what the broker delivers until a budget ends the read.',
+ tr: 'MQTT 5.0 \u00b7 1883',
+ not: 'The encoder has no PUBLISH, and shared subscriptions are refused because they would take a device\u2019s messages.',
+ },
+ {
+ id: 'sparkplug',
+ name: 'Sparkplug B',
+ cat: 'Industrial',
+ logo: '/engines/sparkplug.svg',
+ desc: 'One MQTT broker read through the Eclipse Sparkplug B 3.0.0 topic namespace: groups, edge nodes and devices with their metrics.',
+ tr: 'MQTT \u00b7 Sparkplug B 3.0.0 namespace',
+ not: 'Read-only is an absence of code here, not a setting that could be turned off.',
+ },
+ {
+ id: 'opcua',
+ name: 'OPC UA',
+ cat: 'Industrial',
+ logo: '/engines/opcua.svg',
+ desc: 'The address space of one OPC UA server as a browsable tree, with node attributes and current values.',
+ tr: 'OPC UA TCP \u00b7 4840',
+ not: 'Read-only by construction rather than by configuration: no write service is wired up.',
+ },
+ {
+ id: 'modbus',
+ name: 'Modbus',
+ cat: 'Industrial',
+ logo: '/engines/modbus.svg',
+ desc: 'Modbus TCP, read-only: a device, or a gateway in front of serial devices, read over a raw socket by a client this project owns.',
+ tr: 'Modbus TCP \u00b7 502',
+ not: 'No write function code is implemented, so a coil or a register cannot be set.',
+ },
+ {
+ id: 'mtconnect',
+ name: 'MTConnect',
+ cat: 'Industrial',
+ logo: '/engines/mtconnect.svg',
+ desc: 'One MTConnect agent read over HTTP: devices, their components and the data items they publish.',
+ tr: 'HTTP \u00b7 5000',
+ not: 'Read only: the agent\u2019s own documents are the whole surface, and nothing is posted back.',
+ },
+ {
+ id: 'netconf',
+ name: 'NETCONF',
+ cat: 'Network',
+ logo: '/engines/netconf.svg',
+ desc: 'One network device read over NETCONF on SSH: the running configuration and state data as a browsable tree.',
+ tr: 'NETCONF over SSH \u00b7 830',
+ not: 'Phase one is read only: no edit-config is sent, so a device cannot be changed.',
+ },
+ {
+ id: 'snmp',
+ name: 'SNMP',
+ cat: 'Network',
+ logo: '/engines/snmp.svg',
+ desc: 'A read-only view of SNMP agents, speaking SNMPv2c over UDP, with the MIB walk presented as a tree.',
+ tr: 'SNMPv2c over UDP',
+ not: 'It writes nothing, ever: no SET is implemented.',
+ },
+ {
+ id: 'kubernetes',
+ name: 'Kubernetes',
+ cat: 'Platform',
+ logo: '/engines/kubernetes.svg',
+ desc: 'A read-only browser and a kubectl-subset console for one cluster, over the API server\u2019s REST API and with no driver.',
+ tr: 'API server REST \u00b7 6443',
+ not: 'Read-only whatever the connection says: no request it can send changes the cluster.',
+ },
+ {
+ id: 's3',
+ name: 'S3-compatible object storage',
+ cat: 'Object store',
+ logo: '/engines/s3.svg',
+ desc: 'Buckets, folders and objects with their metadata and a capped preview of text, JSON, CSV or Parquet. Verified on MinIO, Silo, Garage and RustFS, and not on AWS S3 or any hosted service.',
+ tr: 'S3 REST API \u00b7 9000',
+ not: 'Read-only by construction: Studio sends only GET and HEAD requests.',
+ },
];
/** The engines a user points Studio at: every entry but the embedded store. This is the published count. */
diff --git a/src/data/faq.ts b/src/data/faq.ts
index 5eb6fac..b98dfcd 100644
--- a/src/data/faq.ts
+++ b/src/data/faq.ts
@@ -10,7 +10,7 @@ export const faq = [
},
{
q: 'Which databases are supported?',
- a: 'Twenty-seven engines: PostgreSQL, MySQL, Oracle, Db2 LUW, SQL Server, SQLite, libSQL, DuckDB, ClickHouse, Apache Druid, Databend, Trino, MongoDB, Couchbase, Redis, etcd, Oxia, Cassandra, Neo4j, Milvus, Qdrant, Elasticsearch, OpenSearch, Prometheus, InfluxDB (InfluxQL), InfluxDB 3 (SQL) and Apache Kafka — relational, document, key-value, wide-column, graph, vector, analytical, search, time-series, streaming and federated query. Twenty-seven more, such as MariaDB, TiDB, CockroachDB, Valkey and ScyllaDB, speak one of those wire protocols and connect through the same drivers, each measured against a live instance, so the drivers reach fifty-four named engines in all. LibreDB itself, the embedded store the playground runs on, is in the list on /databases but not in either count: those count the engines you point Studio at, not the one it carries.',
+ a: 'Forty-one engines: PostgreSQL, MySQL, Oracle, Db2 LUW, SQL Server, SQLite, libSQL, DuckDB, MongoDB, Redis, Couchbase, Firestore, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Trino, BigQuery, Databend, Snowflake, Apache Spark, Apache Cassandra, Prometheus, Apache Kafka, etcd, Neo4j, Milvus, Qdrant, InfluxDB (InfluxQL), InfluxDB 3 (SQL), Oxia, S3-compatible object storage, Kubernetes, MQTT, RabbitMQ, OPC UA, MTConnect, Modbus, NETCONF, SNMP and Sparkplug B — relational, document, key-value, wide-column, graph, vector, analytical, search, time-series, streaming and federated query. Twenty-seven more, such as MariaDB, TiDB, CockroachDB, Valkey and ScyllaDB, speak one of those wire protocols and connect through the same drivers, each measured against a live instance, so the drivers reach fifty-four named engines in all. LibreDB itself, the embedded store the playground runs on, is in the list on /databases but not in either count: those count the engines you point Studio at, not the one it carries.',
},
{
q: 'Is anything held back from the open-source build?',
diff --git a/src/data/home.ts b/src/data/home.ts
index 2baf62c..219280b 100644
--- a/src/data/home.ts
+++ b/src/data/home.ts
@@ -23,7 +23,7 @@ export const hero = {
lineOne: ['You', 'created', 'the', 'database.'],
lineTwo: ['The', 'editor', 'is', 'already', 'beside', 'it.'],
},
- sub: 'LibreDB Studio is the database IDE that deploys next to your data instead of onto your laptop — one browser tab for PostgreSQL, MySQL, MongoDB, Redis and twenty-three more engines, with SSO and audit built in.',
+ sub: 'LibreDB Studio is the database IDE that deploys next to your data instead of onto your laptop — one browser tab for PostgreSQL, MySQL, MongoDB, Redis and thirty-seven more engines, with SSO and audit built in.',
primaryCta: { label: 'Open live demo', href: 'https://app.libredb.org' },
secondaryCta: { label: 'Deploy in one click', href: '#deploy' },
command: 'docker run -p 3000:3000 libredb/libredb-studio',
@@ -152,7 +152,7 @@ export const how = {
/* --- databases ------------------------------------------------------------ */
export const databases = {
- eyebrow: 'Twenty-seven engines',
+ eyebrow: 'Forty-one engines',
headline: { lineOne: 'One interface.', gradient: 'Different engines.' },
intro:
"Relational, document, key-value, graph, vector, time-series, streaming, analytical, search and federated query — the same tree, editor and grid over each of them, and each engine's real limits declared rather than papered over.",
@@ -160,7 +160,7 @@ export const databases = {
notDoNote:
'Stated because the alternative is a feature list that quietly breaks on the fourth engine. Capability flags come from the provider itself — a control that cannot work is hidden, not offered and then failed.',
footnote:
- 'The claim is the span, not a count — twenty-seven engines, one interface, plus LibreDB, the embedded store the playground runs on. Twenty-seven more speak one of these wire protocols and connect through the same drivers, each measured against a live instance: fifty-four named engines in all. Per-engine detail lives in the provider docs.',
+ 'The claim is the span, not a count — forty-one engines, one interface, plus LibreDB, the embedded store the playground runs on. Twenty-seven more speak one of these wire protocols and connect through the same drivers, each measured against a live instance: sixty-eight named engines in all. Per-engine detail lives in the provider docs.',
} as const;
/* --- product demo --------------------------------------------------------- */
diff --git a/src/data/supporters.ts b/src/data/supporters.ts
index 0a875fb..64b54f3 100644
--- a/src/data/supporters.ts
+++ b/src/data/supporters.ts
@@ -84,7 +84,7 @@ export const supportersPage = {
eyebrow: 'Supporters',
headline: { before: 'Who pays for the parts ', gradient: 'we do not build' },
intro:
- 'LibreDB Studio is MIT and self-hosted, but the work around it is not free: a build fleet, fifty-four database engines to probe against, a public trial anyone can open, and the code-signing certificate the Windows binaries still lack. Where a company or an open-source programme covers one of those, it is named here.',
+ 'LibreDB Studio is MIT and self-hosted, but the work around it is not free: a build fleet, sixty-eight database engines to probe against, a public trial anyone can open, and the code-signing certificate the Windows binaries still lack. Where a company or an open-source programme covers one of those, it is named here.',
empty: {
kicker: 'Current supporters',
diff --git a/src/pages/databases.astro b/src/pages/databases.astro
index 04ecfed..5977377 100644
--- a/src/pages/databases.astro
+++ b/src/pages/databases.astro
@@ -20,6 +20,10 @@ const ORDER: EngineCategory[] = [
'Search',
'Time-series',
'Streaming',
+ 'Industrial',
+ 'Network',
+ 'Platform',
+ 'Object store',
];
const BLURBS: Record = {
@@ -35,6 +39,11 @@ const BLURBS: Record = {
'Index-first engines queried through their own SQL endpoint, Elasticsearch SQL or OpenSearch SQL, not the JSON query DSL.',
'Time-series': 'Metric stores read through their own query language; the series is the table.',
Streaming: 'Logs of records, browsed by offset or by time rather than queried.',
+ Industrial:
+ 'Plant-floor protocols read as they are published: an address space, a topic namespace or a register map.',
+ Network: 'Network devices read over their own management protocols, configuration and state as a tree.',
+ Platform: 'A cluster read through its API server, workloads and their objects rather than rows.',
+ 'Object store': 'Buckets and objects with their metadata, and a capped preview of what an object holds.',
};
// Every card is shown, but the counters count external engines only, so they
diff --git a/tests/engines.test.ts b/tests/engines.test.ts
index 2017abe..0d1bbda 100644
--- a/tests/engines.test.ts
+++ b/tests/engines.test.ts
@@ -79,11 +79,11 @@ describe('the engine count is stated consistently', () => {
// The rule is libredb-studio's (src/lib/db/compatibility.ts,
// `connectableProductCount`, #424): a published count is the external engines,
// `EXTERNAL_DATABASE_TYPES`, so the embedded store is shown but never counted.
- const WORD = 'twenty-seven';
+ const WORD = 'forty-one';
const STALE = ['seventeen engines', 'eighteen engines', 'nineteen engines'];
it('matches the number of external engines actually defined', () => {
- expect(externalEngines.length).toBe(27);
+ expect(externalEngines.length).toBe(41);
});
it('flags exactly one entry as the embedded store, and it is LibreDB', () => {
diff --git a/tests/llms.test.ts b/tests/llms.test.ts
index 188bd38..6fdbb9a 100644
--- a/tests/llms.test.ts
+++ b/tests/llms.test.ts
@@ -50,6 +50,18 @@ const WORDS = [
'twenty-eight',
'twenty-nine',
'thirty',
+ 'thirty-one',
+ 'thirty-two',
+ 'thirty-three',
+ 'thirty-four',
+ 'thirty-five',
+ 'thirty-six',
+ 'thirty-seven',
+ 'thirty-eight',
+ 'thirty-nine',
+ 'forty',
+ 'forty-one',
+ 'forty-two',
];
describe('llms.txt', () => {