Crow’s-foot diagram
Read this page in the documentation
Crow’s-foot diagram Cardinality made explicit: which side is one, which is many, and which is optional. The code What it produces Generated by running the snippet above — this is the generator's real output, rebuilt by scripts/build-diagram-examples.mjs, not a picture of it. <div class="diagram-example"> <!-- Generated by ts-prorm-orm RelationalDiagram --> <svg xmlns="http://www.w3.org/2000/svg" width="1092" height="298" viewBox="0 0 1092 298"><rect width="1092" height="298" fill="#ffffff"/><rect width="1092" height="60" fill="#f0f0f0" stroke="#000000" stroke-width="1"/><text x="24" y="38" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="24" font-weight="bold" fill="#000000">Blog cardinality</text><g data-rel="User-Post"><path d="M 296 179 C 361 179, 361 179, 426 179" fill="none" stroke="#000000" stroke-width="1"/><line x1="307" y1="172" x2="307" y2="186" stroke="#000000" stroke-width="2"/><line x1="426" y1="179" x2="413" y2="172" stroke="#000000" stroke-width="1"/><line x1="426" y1="179" x2="413" y2="179" stroke="#000000" stroke-width="1"/><line x1="426" y1="179" x2="413" y2="186" stroke="#000000" stroke-width="1"/><line x1="413" y1="172" x2="413" y2="186" stroke="#000000" stroke-width="1"/><rect x="315.5" y="169" width="91" height="18" fill="#ffffff" stroke="#000000" stroke-width="1"/><text x="361" y="182" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" font-weight="bold" fill="#000000" text-anchor="middle">one-to-many</text></g><g data-rel="Post-Tag"><path d="M 666 179 C 731 179, 731 179, 796 179" fill="none" stroke="#000000" stroke-width="1"/><line x1="666" y1="179" x2="679" y2="172" stroke="#000000" stroke-width="1"/><line x1="666" y1="179" x2="679" y2="179" stroke="#000000" stroke-width="1"/><line x1="666" y1="179" x2="679" y2="186" stroke="#000000" stroke-width="1"/><line x1="679" y1="172" x2="679" y2="186" stroke="#000000" stroke-width="1"/><line x1="796" y1="179" x2="783" y2="172" stroke="#000000" stroke-width="1"/><line x1="796" y1="179" x2="783" y2="179" stroke="#000000" stroke-width="1"/><line x1="796" y1="179" x2="783" y2="186" stroke="#000000" stroke-width="1"/><line x1="783" y1="172" x2="783" y2="186" stroke="#000000" stroke-width="1"/><rect x="682" y="169" width="98" height="18" fill="#ffffff" stroke="#000000" stroke-width="1"/><text x="731" y="182" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" font-weight="bold" fill="#000000" text-anchor="middle">many-to-many</text></g><rect x="56" y="129" width="240" height="100" fill="#ffffff" stroke="#000000" stroke-width="1"/><rect x="56" y="129" width="240" height="40" fill="#f0f0f0" stroke="#000000" stroke-width="1"/><text x="68" y="154" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="16" font-weight="bold" fill="#000000">User</text><rect x="56" y="169" width="240" height="26" fill="#ffffff"/><circle cx="70" cy="182" r="3.5" fill="#000000"/><text x="84" y="186" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="bold" text-decoration="underline" fill="#000000">id</text><text x="286" y="186" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">INTEGER</text><text x="84" y="191" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="8" font-weight="bold" fill="#666666">PK</text><line x1="56" y1="195" x2="296" y2="195" stroke="#000000" stroke-width="1"/><rect x="56" y="195" width="240" height="26" fill="#f0f0f0"/><circle cx="70" cy="208" r="2" fill="#666666"/><text x="84" y="212" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="normal" fill="#000000">email</text><text x="286" y="212" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">VARCHAR(255)</text><line x1="56" y1="221" x2="296" y2="221" stroke="#000000" stroke-width="1"/><rect x="426" y="116" width="240" height="126" fill="#ffffff" stroke="#000000" stroke-width="1"/><rect x="426" y="116" width="240" height="40" fill="#f0f0f0" stroke="#000000" stroke-width="1"/><text x="438" y="141" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="16" font-weight="bold" fill="#000000">Post</text><rect x="426" y="156" width="240" height="26" fill="#ffffff"/><circle cx="440" cy="169" r="3.5" fill="#000000"/><text x="454" y="173" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="bold" text-decoration="underline" fill="#000000">id</text><text x="656" y="173" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">INTEGER</text><text x="454" y="178" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="8" font-weight="bold" fill="#666666">PK</text><line x1="426" y1="182" x2="666" y2="182" stroke="#000000" stroke-width="1"/><rect x="426" y="182" width="240" height="26" fill="#f0f0f0"/><circle cx="440" cy="195" r="2" fill="#666666"/><text x="454" y="199" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="normal" fill="#000000">title</text><text x="656" y="199" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">VARCHAR(200)</text><line x1="426" y1="208" x2="666" y2="208" stroke="#000000" stroke-width="1"/><rect x="426" y="208" width="240" height="26" fill="#ffffff"/><circle cx="440" cy="221" r="3.5" fill="none" stroke="#000000" stroke-width="1"/><text x="454" y="225" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="bold" fill="#000000">authorId</text><text x="656" y="225" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">INTEGER</text><text x="454" y="230" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="8" font-weight="bold" fill="#666666">FK</text><line x1="426" y1="234" x2="666" y2="234" stroke="#000000" stroke-width="1"/><rect x="796" y="129" width="240" height="100" fill="#ffffff" stroke="#000000" stroke-width="1"/><rect x="796" y="129" width="240" height="40" fill="#f0f0f0" stroke="#000000" stroke-width="1"/><text x="808" y="154" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="16" font-weight="bold" fill="#000000">Tag</text><rect x="796" y="169" width="240" height="26" fill="#ffffff"/><circle cx="810" cy="182" r="3.5" fill="#000000"/><text x="824" y="186" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="bold" text-decoration="underline" fill="#000000">id</text><text x="1026" y="186" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">INTEGER</text><text x="824" y="191" font-family="ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif" font-size="8" font-weight="bold" fill="#666666">PK</text><line x1="796" y1="195" x2="1036" y2="195" stroke="#000000" stroke-width="1"/><rect x="796" y="195" width="240" height="26" fill="#f0f0f0"/><circle cx="810" cy="208" r="2" fill="#666666"/><text x="824" y="212" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="normal" fill="#000000">slug</text><text x="1026" y="212" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10" fill="#666666" text-anchor="end">VARCHAR(60)</text><line x1="796" y1="221" x2="1036" y2="221" stroke="#000000" stroke-width="1"/></svg> </div> Use this when the question is how many, and the ER diagram when the question is what columns. Saving it generate() returns the SVG as a string; save(path) writes it straight to disk. Related reading Diagram generators — every generator and its options Models — the definitions these are drawn from