SQL Playground — Run SQLite in Your Browser
A SQLite database that lives in this tab. Write a schema, insert rows, run joins and see the result tables — with a real SQL engine and no server.
SQLite is not loaded yet. The first run downloads about 0.8 MB from jsDelivr once, then the runtime is cached locally; your SQL and data stay in this tab.
Schema
SQLite not loadedRun a query or load an example to see the tables in this database.
The database lives until you press Stop or reload. Stop also discards every table and row.
What this playground does
This page runs SQLite in your browser. Write a query in the editor and press Run: the statement executes against a real SQLite database, and any rows it returns are rendered as a table beside the editor. You can create a schema, insert sample rows, join tables, try aggregate functions and inspect the result without installing a database or sending anything to a server.
It is a scratchpad, not a production database. The database is in memory, belongs to this tab and disappears when you press Stop or close the page. That is a deliberate trade: it keeps the tool private, fast to start and impossible to leave running behind you.
The SQL editor highlights syntax, completes SQLite keywords and common functions such as
COUNT, SUM and COALESCE, and shows a short signature on
hover. It loads after the first paint, so the runtime and the page controls do not wait for the
editor bundle.
How the runtime works
The engine is sql.js 1.15.2, the SQLite C library compiled to WebAssembly. On the first run the page downloads the JavaScript loader and the WebAssembly module — about 0.8 MB — from jsDelivr, then starts a temporary database inside a sandboxed iframe. Later runs reuse the same database, so the schema persists while you iterate. The loader and wasm are kept in the browser’s Cache Storage after the first visit, so later page loads normally start without downloading them again; Stop still discards the database, not the runtime cache.
The two-click start is intentional. A first run that silently fetches a megabyte and then appears to hang is worse than stating the cost before it happens. The status line reports loading, ready, running and finished states, and Stop is available while the runtime loads or a query executes.
Seeing what is in the database
The Schema panel above the editor answers the first question a database tool should answer: how
many tables are there, and what is in them? After the runtime starts it shows the table count, each
table or view, its column count and the column names. Click a table chip to load a
SELECT * ... LIMIT 100 query into the editor. The panel is refreshed after every
successful statement and also after a statement fails, so a partially executed script leaves an
honest view of what exists.
SQLite does not implement MySQL’s SHOW TABLES or DESCRIBE. The equivalents
are ordinary catalogue queries:
| Task | SQLite |
|---|---|
| List tables and views | SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'; |
| Show a table’s columns | PRAGMA table_info('people'); |
| Read the CREATE statement | SELECT sql FROM sqlite_master WHERE name = 'people'; |
| Preview rows | SELECT * FROM people LIMIT 100; |
| Count rows | SELECT COUNT(*) FROM people; |
| Remove a table | DROP TABLE IF EXISTS people; |
The example selector is a starting point rather than a tutorial: each option is a complete script that creates its own tables and returns a result, so you can run it, change one clause and see what breaks. Use Stop when you want an empty database; use the editor’s history and the Reset query button to return to the starting sample.
What SQLite supports here
| Area | Supported | Notes |
|---|---|---|
| DDL and DML | Yes | CREATE, ALTER, DROP, INSERT, UPDATE, DELETE and indexes |
| Queries | Yes | Joins, subqueries, CTEs, aggregates, window functions and CASE expressions |
| PRAGMA | Yes | Temporary database settings; everything resets on Stop |
| Multiple statements | Yes | The whole script is executed in one run |
| Files | No | The database is in memory; there is no file input or persistent storage |
| Extensions / other dialects | No | No loadable extensions; MySQL, PostgreSQL and SQL Server syntax is not SQLite syntax |
Privacy and the sandbox
The SQL iframe is sandboxed with allow-scripts only and without
allow-same-origin. It has an opaque origin, so the database code cannot read this
site’s cookies, localStorage or DOM, and it cannot navigate the parent page. Your SQL and the
result rows come back only as messages over postMessage. Neither is sent to this
site’s server; there is no endpoint that accepts it.
The CDN request is the one network exchange the tool makes on its own: jsDelivr serves the pinned runtime files and therefore sees your IP address and user agent, as any CDN would. It does not receive your schema, your rows or your query results. There is no analytics call and no database connection from this page.
Common uses
- Learning joins. Create two small tables, insert a few rows and compare INNER, LEFT and CROSS joins.
- Checking a query before production. Reduce a slow or surprising query to a small schema and inspect what SQLite actually returns.
- Teaching SQL. A complete example with visible input and output is easier to discuss than a screenshot.
- Testing SQLite behaviour. Check how NULLs sort, how aggregates treat empty groups, or what a PRAGMA changes in this build.
- Preparing test data. Build a few rows quickly, then copy the INSERT statements into a project or a test fixture.
Working within the limits
SQLite is a file database, but this build has no persistent file: the database is created in
memory and discarded with the iframe. There is no concurrency, no authentication, no backup and
no extension loading. Memory is bounded by the tab, so a query that generates millions of rows can
be slow or fail; Stop is the escape hatch. The SQLite dialect is not a compatibility layer for
other databases — functions such as MySQL’s DATE_FORMAT or PostgreSQL’s
generate_series are not available unless the SQLite build happens to provide an
equivalent.
For a quick check or a teaching example, that is enough. For a real application, use a SQLite file on disk or a server database, with migrations, backups and the concurrency model the application needs. The playground is the workbench, not the store.
Frequently asked questions
Is my SQL or my data uploaded anywhere?
No. The database runs inside a sandboxed iframe in this browser tab. Your query and the rows you create are passed to that iframe with postMessage and never sent to this site or to a server. The sql.js runtime files are downloaded from jsDelivr, so the CDN sees the request for those files — not your SQL and not your data.
Which SQL dialect is this?
SQLite. The runtime is sql.js 1.15.2, which bundles SQLite compiled to WebAssembly. It understands SQLite’s SQL surface — CREATE/INSERT/SELECT/UPDATE/DELETE, joins, subqueries, CTEs, aggregates, PRAGMA and the usual SQLite functions — but not MySQL, PostgreSQL or SQL Server extensions. A query that works in another database may need edits here.
How do I see which tables exist?
The Schema panel above the editor lists every table and view with its columns after a run. It also shows the table and column counts. If you prefer SQL, run SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name;. SQLite has no SHOW TABLES command.
Why does SHOW TABLES or DESCRIBE fail?
Those are MySQL commands, not SQLite. Use the sqlite_master catalogue to list objects and PRAGMA table_info('table_name') to inspect columns. This playground prints that hint when it sees the syntax error, and the Schema panel gives the same information without a query.
Where are the SQL examples?
The Load an example selector above the editor contains runnable SQLite snippets: create and query a table, join two tables, aggregate with GROUP BY, use a CTE with a window function, and list tables. Selecting one loads the code without executing it; press Run when you want to execute it.
Why do I have to press Run twice the first time?
The first execution downloads the SQLite runtime: about 0.8 MB of JavaScript and WebAssembly from jsDelivr. The first click explains the download; the second click starts it. The page then keeps the pinned loader and wasm in the browser’s Cache Storage, so later visits and later runs normally do not download them again; clearing site data or using a private window removes that cache.
Does the schema persist between runs?
Yes, until you press Stop or reload the page. The same SQLite database is reused for every run, so a table created in one run is available in the next. Stop discards the iframe and with it the database; the next run starts from an empty database. There is no file and no localStorage, so closing the tab also loses everything.
Can I run more than one statement at a time?
Yes. sql.js executes the whole string, so a CREATE TABLE, several INSERTs and a SELECT can be submitted together. The Results panel shows every result set that returns rows; row counts are reported for statements that only modify data. If one statement fails, the error is shown and the transaction stops at that point.
How do I stop a slow query?
Press Stop. The database runs in a separate sandboxed iframe, so discarding that document terminates the query even when SQLite itself is busy. Stopping also throws away the database, so any tables and rows you created are lost; the next run starts with an empty schema.
Can I import a CSV or open a file?
Not in this playground. It has no file input and no persistent filesystem; data is created with SQL or pasted into an INSERT. The /csv-to-json/ and /csv-viewer/ tools handle CSV locally, and /fake-data-generator/ can produce rows to paste here if you need a larger sample.
Why is there no result for my INSERT or CREATE TABLE?
Those statements do not return rows. SQLite returns a row count instead, which the page reports below the editor. Use a SELECT after the change if you want to see the data; the Results panel shows row-returning statements only.
Can I use PRAGMA commands?
Yes. SQLite PRAGMAs are ordinary statements and run like any other query. Some affect only the temporary in-memory database, and any setting you change is discarded when the database is stopped or the page is reloaded.
Is this a replacement for a real database?
No. It is a single-user, in-memory SQLite instance for practice, teaching and checking a query before you run it elsewhere. There are no users, permissions, concurrent writers, persistent storage, backups or extensions. Use a real SQLite file or server database for anything that must survive the tab.
Go deeper
Longer explanations of the problems this tool solves:
Sources
- SQLite documentation — SQL syntax, data types, PRAGMAs and the in-memory database model.
- sql.js documentation — the SQLite WebAssembly build and its JavaScript API.
- MDN Web Docs — iframe sandbox and the same-origin policy.
- CodeMirror 6 documentation — the SQL language package used by the editor.
Everything runs in your browser — nothing you type is uploaded.