Convert Mermaid ER to SQLite
Generate production-ready SQLite SQL code from your Mermaid ER diagrams in seconds.
How the Mermaid ER to SQLite conversion works
Mermaid erDiagram is a Markdown-friendly notation rendered natively by GitHub, GitLab, Notion, and Obsidian β which makes it the most common way to keep an ER diagram next to the code it describes.
Entities are blocks of `type name marker` lines (markers: PK, FK, UK, INDEX), and relationships use cardinality arrows like `USER ||--o{ POST : writes` β one-to-many from USER to POST. The converter reads both, plus comment directives for everything the base syntax can't express.
Paste your Mermaid ER source into the editor above and the engine parses it into an
intermediate schema β tables, columns, relationships, indexes β then generates
SQLite DDL from that model. Anything the diagram
syntax can't express (NOT NULL, defaults, enums, CHECK constraints, composite indexes)
you add with comment directives like %% ::NN, ::DEFAULT(now()) on the line
above a column. The Mermaid ER reference documents the
full vocabulary.
What the generator emits for SQLite
- CREATE TABLE statements using SQLite type affinity
- inline REFERENCES clauses for foreign keys (SQLite cannot ADD CONSTRAINT later)
- CHECK (col IN (β¦)) constraints for ::ENUM(...) columns
- INTEGER primary keys that alias SQLite's rowid
- CREATE INDEX / CREATE UNIQUE INDEX, including partial indexes with a WHERE clause
Type mapping: Mermaid ER to SQLite
Diagram column types are logical β the generator maps each one to the idiomatic SQLite type. These are the exact mappings the engine uses:
| Diagram type | SQLite type | Notes |
|---|---|---|
int | INTEGER | an INTEGER PRIMARY KEY aliases the rowid |
string | TEXT | SQLite ignores varchar lengths; affinity is TEXT |
text | TEXT | |
decimal | REAL | SQLite has no fixed-point type |
boolean | INTEGER | 0 / 1 by convention |
date | TEXT | ISO-8601 strings, per SQLite best practice |
timestamp | TEXT | ISO-8601 strings |
uuid | TEXT | |
bigint | INTEGER | SQLite INTEGER is 8 bytes |
blob | BLOB |
Keys, relationships, and enums
A single `int id PK` becomes `"id" INTEGER PRIMARY KEY`, which in SQLite aliases the internal rowid and auto-assigns values β no AUTOINCREMENT keyword needed for the common case.
SQLite cannot add constraints after table creation, so foreign keys are emitted inline as `REFERENCES parent("id")` on the column. The converter orders tables so parents are created before children. Remember to run PRAGMA foreign_keys = ON.
SQLite has no enum type, so `::ENUM(active, inactive)` emits `TEXT CHECK ("status" IN ('active', 'inactive'))` β the values are still enforced, just via a CHECK constraint instead of a type.
Frequently asked questions
Why are foreign keys inline instead of ALTER TABLE statements?
SQLite does not support ALTER TABLE β¦ ADD CONSTRAINT. The converter knows this and emits inline REFERENCES clauses, ordering the CREATE TABLE statements so referenced tables come first.
What happens to enum columns in SQLite?
They become TEXT with a CHECK (col IN (β¦)) constraint, so invalid values are still rejected even though SQLite has no native enum type.
Why do date and timestamp columns map to TEXT?
SQLite has no dedicated datetime type; storing ISO-8601 strings in TEXT is the documented best practice and works with SQLite's built-in date functions.
Do foreign keys actually work in SQLite?
Yes, but enforcement is off by default β run PRAGMA foreign_keys = ON per connection. The generated schema declares the constraints correctly either way.