This content originally appeared on DEV Community and was authored by Yevhen Kozachenko 🇺🇦
🔥 Stop Wasting Time With REST – Build Real-Time Apps with SQL Over WebSockets!
Let's be honest – REST APIs are starting to feel like fax machines in the age of WhatsApp. We're building rich, collaborative, real-time interfaces, yet still fetching data like it's 1999. It's time to rethink how we design data-driven applications.
In this post, we're diving into a revolutionary approach: using SQL over WebSockets to build blazing-fast, reactive web applications. We'll explore how coupling SQL's expressive querying power with the event-driven nature of WebSockets can elevate your user experience, simplify your backend, and reduce your frontend codebase by a lot.
This technique is real, battle-tested, and achievable today – we’ll see how to do it with ElectricSQL and SQLite + CRDTs + WebSockets.
🧠 TL;DR – What’s the Idea?
- SQL is declarative; you tell it what you want.
- WebSockets are persistent; they give you a channel to push updates.
- CRDTs (conflict-free replicated data types) allow multi-writer sync (even offline!)
- Combine them = pure magic.
Let's look at how you can ship a live collaborative app – like Notion or Figma – without:
- Polling
- Redux spaghetti
- REST endpoints
- Complex backend logic
🚀 Meet ElectricSQL: Real-Time Sync for SQLite
ElectricSQL is a sync layer for SQLite with WebSocket transport, CRDT support, and automatic reactivity. Think Firebase, but SQL-native, offline-first, and open-source (😲 yes, really!).
⚙️ Stack Overview
- Backend: PostgreSQL + Electric sync service
- Frontend: SQLite (via WASM) + Electric client
- Sync: WebSockets – bi-directional, instant updates
Under the hood:
- You define your schema declaratively using SQL
- Data updates propagate automatically, no REST required
- The frontend runs a live-replicating SQLite DB (!!)
Let me show you how to build a mini Notion-style collaborative notes app using this magic.
👷 Project: Real-Time Collaborative Notes App in 100 Lines of Code
Here’s a breakdown of a minimal collaborative app.
🧱 Step 1 – Setup ElectricSQL
We’ll use the Electric CLI to scaffold a project:
npx create-electric-app realtime-notes
cd realtime-notes
npm install
npm run dev
Boom – you’ve got a dev server, sync service, and WebSocket pipeline running.
📄 Step 2 – Define Your Schema
Inside electric/schema.sql:
CREATE TABLE IF NOT EXISTS notes (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
SELECT crsql_as_crr('notes'); -- enable sync
This makes the notes table syncable. ElectricSQL will handle all CRDT magic and syncing logic behind the scenes.
💻 Step 3 – Use SQLite on the Frontend (in your browser!)
ElectricSQL provides a client that runs SQLite in the browser via WASM.
In your React component:
import { ElectricProvider, useElectricQuery } from 'electric-sql/react';
import { useEffect, useState } from 'react';
function NotesApp() {
const { results, execute, isLoading } = useElectricQuery(
`SELECT * FROM notes ORDER BY updated_at DESC`
);
const [newNote, setNewNote] = useState("");
const addNote = async () => {
const id = crypto.randomUUID();
await execute(
`INSERT INTO notes (id, content) VALUES (?, ?)`,
[id, newNote]
);
setNewNote("");
};
return (
<div>
<input
value={newNote}
onChange={(e) => setNewNote(e.target.value)}
/>
<button onClick={addNote}>Add Note</button>
<ul>
{results.map(note => (
<li key={note.id}>{note.content}</li>
))}
</ul>
</div>
);
}
This is a real SQLite database running in the browser, updated via WebSockets, and the UI reacts automatically. No Redux, no useEffect data fetching dance, no reloading. It's just... reactive.
📡 Step 4 – Real-Time without REST
Notes are updated in real-time across all clients thanks to the sync protocol and WebSocket connection. Add a note in one tab, it appears instantly on all others.
You didn’t write a single API.
⚡ What Makes This Amazing?
- No API Layer: No Express, no FastAPI, nothing. You query what you need.
- Sync, not Request/Response: Everything is updated via streams.
- Offline-first: Updates propagate when the connection is restored.
- CRDTs built-in: Conflicts auto-resolve via deterministic rules.
- SQL-familiar: Don’t learn a new DSL – this is just SQL.
🧪 What Are the Caveats?
Let’s get real – this isn’t magic beans (yet):
- You still need Postgres on the backend for source-of-truth (ElectricSQL syncs to it)
- Debugging sync state might be a learning curve
- CRDT merge logic is automatic, but still worth understanding the model
- Larger datasets? You may need to tweak sync scopes (à la GraphQL @live directives)
🧠 Who Should Use This?
- 💬 Building chat, docs, boards, collab apps
- 📱 Need offline support with minimal backend
- 🧳 Want SQLite on frontend (cross-platform FTW!)
- 🐣 Bootstrapping a SaaS without a full API layer
📚 Further Reading
- ElectricSQL Docs
- Replicache (a similar sync precursor)
- CRDT Explained: by Ink & Switch
- LiveBlocks, Convex, and other real-time stacks
✅ Conclusion: Ditch REST for Reactive SQL!
Real-time collaboration doesn’t need a RESTful API maze, Redux boilerplate, or multiple database layers. You can:
- Write SQL once
- Sync to frontends in real-time
- Get offline support + conflict resolution
With ElectricSQL and SQL over WebSockets, we’re entering a new era of reactive programming. And it’s much simpler than you think.
So maybe the real question is:
Why are you still writing REST endpoints? 🤔
Want more tutorials like this? Subscribe and shoot me a comment about the next real-time app you'd like me to build!
🟡 If you need this done – we offer fullstack development services!
This content originally appeared on DEV Community and was authored by Yevhen Kozachenko 🇺🇦
Yevhen Kozachenko 🇺🇦 | Sciencx (2025-09-16T16:11:50+00:00) 🔥 Stop Wasting Time With REST – Build Real-Time Apps with SQL Over WebSockets!. Retrieved from https://www.scien.cx/2025/09/16/%f0%9f%94%a5-stop-wasting-time-with-rest-build-real-time-apps-with-sql-over-websockets/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.