linked-db / linked-ql

A modern take on SQL and SQL databases that checks all the boxes for modern apps

Home Page:https://linked-ql.netlify.app/

Repository from Github https://github.comlinked-db/linked-qlRepository from Github https://github.comlinked-db/linked-ql

LinkedQL

A modern take on SQL and SQL databases

npm version npm downloads bundle License

LinkedQL Banner



Try an advanced form of SQL right on your database.
LinkedQL is a database client (client.query()) that solves the modern database capability problem in a single interface — and in under 80 KiB min | zip.
Relationships • JSON • Schema • Reactivity • Versioning • Offline → SOLVED




Quick Start

Installation

LinkedQL is distributed as an npm package. Install it with:

npm install @linked-db/linked-ql

The package provides clients for all supported SQL dialects — including FlashQL, the in-memory SQL engine for local or offline use.

Initialization

Import and initialize the client for your use case. You can run either fully in-memory or with a database. Here are two quick examples:

Run Locally with FlashQL

FlashQL lets you run SQL queries entirely in memory — with zero setup.

import { FlashClient } from '@linked-db/linked-ql/flash';

const client = new FlashClient();

const result = await client.query(`
  CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);
  INSERT INTO users (name) VALUES ('Ada'), ('Linus');
  SELECT * FROM users;
`);

console.log(result.rows);
// [{ id: 1, name: 'Ada' }, { id: 2, name: 'Linus' }]

FlashQL is ideal for:

  • Local-first and offline-first apps
  • Running SQL over runtime data
  • Testing and prototyping

Connect to a Database

Connect to your database from the list of supported dialects below. Here’s an example using PostgreSQL:

import { PGClient } from '@linked-db/linked-ql/pg';

const client = new PGClient({
  host: 'localhost',
  port: 5432,
  user: 'postgres',
  password: 'password',
  database: 'myapp',
});

await client.connect();

const result = await client.query(`SELECT 10 AS value`);
console.log(result.rows); // [{ value: 10 }]

await client.disconnect();

Clients & Dialects

Dialect Import Path Guide
PostgreSQL @linked-db/linked-ql/pg PostgreSQL →
MySQL @linked-db/linked-ql/mysql MySQL →
MariaDB @linked-db/linked-ql/mariadb MariaDB →
FlashQL (In-Memory) @linked-db/linked-ql/flash FlashQL →

Query Interface

LinkedQL maintains a unified and familiar interface across all dialects — whether remote or local. Method signatures and return values are consistent and documented in the Client API Reference →


Note

You’re viewing @linked-db/linked-ql — the newest iteration.
For the prev 0.3.x branch, see linked-db/linked-ql@0.3.*.

Important

🚀 LinkedQL is in active development and evolving daily. Current status = alpha.
You’re welcome to experiment, but it’s not yet suited for production workloads.



1 | Language Capabilities

Feature Summary Docs
DeepRefs Follow foreign key relationships directly in simple arrow notation. Read → DeepRefs Docs
JSON Literals Model JSON objects and arrays using literal JSON syntax. Read → JSON Docs
UPSERT Perform the classic INSERT...ON CONFLICT statement in a single step. Read → UPSERT Docs

Examples


(a) JSON Literals — Structured Projection

Model JSON objects and arrays using literal JSON syntax.

const result = await client.query(`
  SELECT
  id,
  { first: first_name, last: last_name } AS name,
  { email, phone: phone_number } AS contact
  FROM users
`);

console.log(result.rows[0]);
// { id: 1, name: { first: 'Jane', last: 'Dark' }, contact: { email: 'jane@example.com', phone: null } }

(b) DeepRefs — Relationship Traversal

Follow foreign key relationships directly in simple arrow notation.

const posts = await client.query(`
  SELECT title, author ~> { name, email }
  FROM posts
  WHERE published = true;
`);

console.log(posts.rows[0]);
// { title: 'Syntax Shorthands', author: { name: 'John', email: 'john@example.com' } }

(c) UPSERT — Insert or Update

Perform the classic INSERT...ON CONFLICT statement in a single step.

await client.query(`
  UPSERT INTO users (id, name, email)
  VALUES
    (1, 'Jane', 'jane@example.com'),
    (2, 'James', 'j2@example.com');
`);



2 | Runtime Capabilities

Feature Summary Docs
Live Queries Turn on reactivity over any query and get back a live view of your data. Read → RealtimeSQL Docs
Timeline Engine Anchor a query to a fixed schema version for stable results over time. (Coming soon)

Examples


(a) Live Queries and Live Views

Turn on reactivity over any query and get back a live view of your data.

const result = await client.query(`
  SELECT p.title, u.name
  FROM posts AS p LEFT JOIN users AS u ON p.author = u.id
  WHERE p.published = true
  ORDER BY p.created_at DESC
`, { live: true });

setInterval(() => console.log(result.rows), 1000);
// Updates automatically as post or author data changes

(b) Live Queries + DeepRefs

Combine live results with relational traversal and JSON shaping.

const result = await client.query(`
  SELECT
    { title, category } AS post,
    author ~> { name, email } AS author
  FROM posts WHERE published = true
`, { live: true });

(c) Version Binding — Point-in-Time Queries

Anchor a query to a fixed schema version for stable results over time.

const result = await client.query(`
  SELECT name, email
  FROM users@2_3
  WHERE active = true;
`);



3 | Offline Capabilities

LinkedQL bundles an embeddable SQL engine, FlashQL, that brings its full capabilities to the local runtime, the edge, and offline world.

Capability Summary Docs
Local Database Run a full SQL engine in memory — same semantics, zero setup. Read → FlashQL Docs
Federation Query local and remote data together in a single SQL surface. Read → FlashQL Docs
Sync Keep local and remote tables automatically synchronized. Read → FlashQL Docs

Examples


(a) Local Database — Runs Anywhere

Run a full SQL engine in memory — same semantics, zero setup.

import { FlashClient } from '@linked-db/linked-ql/flash';
const client = new FlashClient();

await client.query(`CREATE TABLE users (id SERIAL, name TEXT)`);
await client.query(`INSERT INTO users (name) VALUES ('Alice'), ('Bob')`);

const result = await client.query(`SELECT JSON_AGG(name) AS users FROM users`);
console.log(result.rows);
// [{ users: ['Alice', 'Bob'] }]

(b) Federation — Local + Remote

Query local and remote data together in a single SQL surface.

await client.federate({ store: ['orders'] }, remoteConfig);

const result = await client.query(`
  SELECT u.name, COUNT(o.id) AS total_orders
  FROM users AS u LEFT JOIN store.orders AS o ON o.user_id = u.id
  GROUP BY u.id ORDER BY total_orders DESC;
`);

(c) Sync — Continuous Alignment

Keep local and remote tables automatically synchronized.

await client.sync({ store: ['orders'] }, remoteConfig);

client.on('sync:status', s => console.log('Sync status:', s.state));
client.on('sync:change', e => console.log('Δ', e.table, e.type));



📚 Documentation

Feature Description Wiki Page
DeepRefs Declarative relationship traversal across foreign keys. DeepRefs →
JSON Literals Inline JSON modeling syntax — objects, arrays, aggregations. JSON Literals →
UPSERTS Simplified INSERT + UPDATE hybrid statement. UPSERTS →
RealtimeSQL Live queries powered by the Realtime Engine. RealtimeSQL →
FlashQL In-memory SQL runtime for offline, edge, and hybrid apps. FlashQL →



⏳ Progress (@next)

Component Status Note
Parser & Compiler 🟩 100% Stable
Transform Engine 🟩 100% Stable
Drivers (PG/MySQL) 🟩 97% Complete; MySQL nearing parity
FlashQL Engine 🟩 99% Expanding
Realtime Engine 🟩 99% Expanding
Timeline Engine 🟨 20% Planned
Migration Wizard 10% Planned
IDE Tooling 5% Early hooks
Docs (vNext) 🟩 95% Expanding
Status Legend:

🟩 Complete | 🟨 In Progress | ⬜ Not Started




🤝 Contributing

LinkedQL is in active development — and contributions are welcome!

Here’s how you can jump in:

  • Issues → Spot a bug or have a feature idea? Open an issue.
  • Pull requests → PRs are welcome for fixes, docs, or new ideas.
  • Discussions → Not sure where your idea fits? Start a discussion.

🛠️ Local Setup

⤷ clone → install → test

git clone https://github.com/linked-db/linked-ql.git
cd linked-ql
git checkout next
npm install
npm test

📝 Tips

  • Development happens on the next branch — be sure to switch to it as above after cloning.
  • Consider creating your feature branch from next before making changes (e.g. git checkout -b feature/my-idea).
  • Remember to npm test before submitting a PR.
  • Check the Progress section above to see where help is most needed.

🔑 License

MIT — see LICENSE

About

A modern take on SQL and SQL databases that checks all the boxes for modern apps

https://linked-ql.netlify.app/

License:MIT License


Languages

Language:JavaScript 99.6%Language:TypeScript 0.3%Language:CSS 0.1%