Skip to content
kuy124Public

About

Draw ERDs in Chen notation or crow's-foot tables, together, in a browser. Peer-to-peer, no server, no account.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

ERD Maker

Draw entity–relationship diagrams in the browser: Chen notation or crow’s-foot tables, keys and relationships included. Share a live room or download a diagram. No account.

Diagrams save in your browser. Download a JSON backup (Ctrl+S) before clearing browser data.

Get started

  1. Draw — use Add your first entity, or open an example: Customer–Order, Student–Course, Employee–Dependent. Each opens in its own room.
  2. Name — new shapes take typing immediately. Double-click later to edit.
  3. Share or download — a room link, or SVG, PNG, JSON, or SQL.
⚙️ For developers: run locally
npm install
npm run dev
npm run verify

Verification runs unit tests, TypeScript, a production build, and browser tests. Browser tests start Vite preview and a local y-webrtc signaling server, with no public dependency. Rooms save through IndexedDB.

Build a diagram

  • Build panel adds entities, attributes, relationships, specializations.
  • Connect in Chen: drag entity to entity. It creates the diamond with both participants. Drag onto a diamond to add a participant.
  • Connect in crow’s-foot: pick two attribute rows. Change an endpoint via Connection attribute; Automatic follows the inferred key and foreign key.
  • Check diagram flags missing names and keys, stray attributes, incomplete relationships, and invalid ranges. A hint opens the affected properties.
  • Fit frames the drawing. Add unary relationship in Properties links an entity to itself.
  • Entities come as Regular, Weak, or Associative.
  • A crow’s-foot row with no attribute behind it was generated by the diagram. It stays editable and takes your name.
⚙️ For developers: exact-schema details
  • Unique is a candidate key: it identifies a row but is not the primary key, and another table may reference it instead. Marked UQ in tables, broken underline in Chen, UNIQUE in SQL. Key instead makes it part of the primary key, and a foreign key must then carry every part. A generated primary-key role leaves an existing id editable.
  • Composite attributes own parts via Add attribute or Belongs to. Chen draws the hierarchy; tables and SQL use leaf names like billing_address_street, keeping each leaf’s key and type. No parts means a scalar column. Deleting one removes its subtree; Undo restores it.
  • Hand-shaped lines use dbdiagram-style controls: round handle or section drags perpendicular, square splits at midpoint, Enter adds a section, arrows nudge (Shift larger), Escape cancels, Route line automatically restores routing. Neighbouring sections snap together; self-intersections are blocked, endpoint stubs protected. Segment positions sync live and survive reloads.
  • Table positions sync separately from Chen positions; auto-arrange never overrules a hand move, and the newest placement wins a conflict.
  • Specializations and attributes on relationships live in Diagram; selecting one switches to Chen.

Move around

  • Scroll zooms toward the pointer; trackpad and two-finger pinch zoom too. Range: 25% to 300%.
  • Left controls: Build, Diagram, Properties, Help. On phones they move to the bottom bar.
  • Focus view (I) hides controls; Escape or I returns.
  • Right-click canvas or a shape for its menu. Shift-click multi-selects. Shift-drag box-selects.
  • Undo and Redo apply to edits; remote changes stay shared.
⚙️ For developers: phone and menu specifics

Editing sheets take at most 45% of the screen, keep normal scrolling, and stay above the on-screen keyboard; Done returns to the drawing while Select, Connect, Pan, Undo, and Redo stay reachable. Right-click menus also open with Shift+F10 or the Menu key: arrows navigate, Enter activates, Escape or Tab closes. Right-clicking a selected shape keeps the selection.

Notation

Chen symbol Meaning
Rectangle Entity
Ellipse Attribute
Diamond Relationship
Triangle Specialization
Double rectangle Weak entity
Double diamond Identifying relationship
Double ellipse Multivalued attribute
Dashed ellipse Derived attribute
Underlined attribute Key

A weak entity’s partial key identifies it within its parent; SQL combines it with the parent’s key.

⚙️ For developers: endpoint symbols and ranges

Chen endpoints follow ERDPlus: two bars required one, circle and bar optional one, bar and fork required many, circle and fork optional many. N and M both use the fork. Click an endpoint to edit constraints; advanced numeric ranges stay visible beside the line. Minimum / maximum takes whole numbers and N; invalid input stays local until corrected, and relationships may stay incomplete or exceed two participants.

Each person picks their own notation, stored per room and browser. JSON files and snapshots keep the exporter’s view field and current notation.

Rooms and sharing

  • New diagrams open in new rooms. Browser Back returns with the work saved.
  • Share gives a short room link. The room is kept on the sync server, so the link opens the diagram even when nobody else is online; while it loads you may see Waiting for the diagram and the room code.
  • Include diagram snapshot puts the diagram in the link itself: longer, and it opens with no server at all. It starts ticked when the app has no sync server to keep rooms. Both link types allow editing.
  • Save a copy writes JSON that needs no server and survives chat apps. Import replaces the room you are in; Undo brings the old diagram back, and an invalid file leaves the room intact.
  • Your name is asked on an empty diagram, stored per browser, and sent to peers as you type.
  • A diagram lives in its room, in this browser, and — when a sync server is set up — on that server, so a link still opens later.

The header names the connection state:

Status Meaning
Live Edits flow between browsers
Same browser Other people are in this browser only
Waiting The room is reachable, nobody else is in it
Offline The signaling server is unreachable
Blocked A peer was found; the network refused the connection

A peer’s cursor appears only in the same notation, since the two views place one schema at different coordinates. Closing a tab removes a cursor immediately.

⚙️ For developers: how connections work

Tabs in one browser sync over BroadcastChannel; separate browsers use a sync server when one is configured, and WebRTC with a signaling server otherwise. Presence comes from connected peers and is shown apart from browser storage. Offline and Blocked offer Share, where a snapshot link can be copied.

With VITE_SYNC_URL set, the app talks to Cloudflare's cloudflare/worker.js instead of the signaling servers; that worker writes a room to storage when the last person leaves, which is what lets a short link open with nobody online. Without it, default server: wss://signaling.fly.dev. Override with ?signaling=, window.__ERD_SIGNALING__, or VITE_SIGNALING. If direct connections are blocked, editing and snapshot links still work; cross-device live edits do not arrive.

Export

SVG, PNG, JSON, SQL. Image exports use the full drawing bounds and strip selection, hover, connection, and presence overlays.

⚙️ For developers: SQL export rules

The SQL tab offers a dialect: Standard SQL, PostgreSQL, MySQL, or SQLite. It changes only generated key spelling (INTEGER, SERIAL, INT AUTO_INCREMENT), stored per browser and exporter, not per diagram.

Mapping: entities become tables, weak entities borrow the parent key, many-to-many makes junction tables, one-to-many adds foreign keys. Connection attributes supply the actual columns; explicit one-to-one enforces uniqueness. The export explains a reference that needs a single-column primary key or an endpoint that is gone. Foreign-key types follow the referenced key; other types use the chosen type or infer from the name.

Types are a base plus numbers: length for VARCHAR, precision and scale for DECIMAL, so VARCHAR(64) and NUMERIC(12,4) instead of fixed presets. Bases: integers, text, character strings, numeric, boolean, date/time, UUID, JSON, bytea, enum. ENUM takes a comma-separated list, shown as SQL (ENUM('pending','active','closed')); quotes are optional on input, added on export, and escaped. Bad numbers such as VARCHAR(0) are refused, not repaired. Types persist through edits, collaboration, JSON, and snapshots. SQL/DBML import is out of scope.

Keyboard

Key Action
E / A / R / S Add entity / attribute / relationship / specialization
V / C / H Select / Connect / Pan
F Fit diagram
I Toggle Focus view
Shift-click Add to or remove from the selection
Double-click Reveal the shape's properties
Shift-drag empty canvas Select several shapes with a box
Shift+F10 / Menu key Open canvas actions
Escape Finish typing, then cancel selection or connection
Delete Delete selection
Ctrl or ⌘ + Z Undo
Ctrl or ⌘ + Shift + Z Redo
Ctrl or ⌘ + S Download JSON
? Open Help

Look

IBM Plex type, paper-and-ink surfaces, quiet drafting grids, teal selection. Follows system light or dark and reduced motion. Help adds Solarized Light, Solarized Dark, Dracula, Nord, GitHub Dark, and Monokai using each project’s published values. Themes change colour tokens only, all at 4.5:1 body contrast. The choice is stored per browser; System clears it.

⚙️ For developers: design references

The thesis, palette, geometry rules, and accessibility floor live in DESIGN.md, held by two unit tests: every var() a rule reads is set somewhere, and every theme defines its tokens at 4.5:1. Read it before changing a token or adding a surface. A two-entity keyed schema stays within 11 keyboard interactions.

Teaching reference: ERDPlus. Editing and examples informed by drawDB, keyboard efficiency by dbdiagram’s guide, peer state by DrawSQL. The React/CSS/SVG/Yjs implementation and serialized model stay as they are.

About

Draw ERDs in Chen notation or crow's-foot tables, together, in a browser. Peer-to-peer, no server, no account.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages