Entity structure diagram
About entity structure diagrams
An entity structure diagram maps the legal and economic relationships between organizations and people — who owns what, through which entity form, and in which jurisdiction. Corporate counsel use them to document holding structures and subsidiary chains. Tax advisors draw them to show cross-border IP licensing flows and transfer-pricing arrangements. Startup attorneys produce them for cap tables and board consents. Estate planners use them to show grantor-trust-beneficiary arrangements. The diagram is the first document requested in any M&A due diligence process and the standard attachment to an OECD transfer-pricing master file.
Schematex follows the practitioner conventions synthesized from SEC Regulation S-K Exhibit 21 (subsidiary disclosure), IRS Form 8832 entity classifications, ISO 3166-1 jurisdiction codes, ISO 20275 legal entity forms, and Big Four tax memo conventions. Entity types map to distinct shapes (rectangle for corp, rounded rectangle for LLC, ellipse for trust) so any reader can identify the legal form at a glance. This page documents what the parser accepts today.
1. Your first entity structure
The smallest useful entity structure: a parent owning two subsidiaries.
Four rules cover 80% of usage:
- Start with
entity-structure, optionally followed by a quoted title. - Each legal entity is a node:
entity ID "Display Name" type— the type determines the shape. - Connect entities with
->. Append: pctto label ownership percentage:parent -> child : 60%. - Add
@jurisdictionafter the type to show a jurisdiction badge:corp@DE.
Comments must start with
#on their own line.
2. Entity types
The entity type determines the shape rendered for that node. Schematex maps several common aliases to a canonical type.
| Canonical type | Aliases accepted | Rendered shape | Typical use |
|---|---|---|---|
corp | corporation, inc | Rectangle (sharp corners) | C-corp, S-corp, Ltd., SA, AG |
llc | llp, gmbh, bv | Rounded rectangle | LLC, LLP, GmbH, BV |
lp | lllp, fund | Notched rectangle | LP, LLLP, investment fund |
trust | — | Ellipse | Family trust, statutory trust |
individual | person | Circle | Founder, grantor, natural person |
foundation | npo | Pentagon (shield) | Non-profit, charitable foundation |
disregarded | branch | Dashed rectangle | Disregarded entity, foreign branch |
pool | — | Dashed rounded rectangle | Option pool, ESOP, unissued shares |
placeholder | tbf | Dashed rectangle (faded) | To-be-formed entity, acquisition target |
Entity syntax:
entity ID "Display Name" type
entity ID "Display Name" type@JURISDICTION
entity ID "Display Name" type@JURISDICTION [properties]ID rules. Must start with a letter, followed by letters, digits, underscores, or hyphens: [A-Za-z][A-Za-z0-9_-]*.
3. Node properties
Optional properties inside […] annotate the entity with additional context visible in the rendered node.
| Property | Syntax | Effect |
|---|---|---|
status: new | new, eliminated, modified, normal | Visual badge for transaction-step diagrams |
tax: ccorp | quoted string | Tax classification label below entity name |
role: "Grantor" | quoted string | Role label (for individuals and trustees) |
note: "…" | quoted string | Small note displayed inside the node |
est: "2024-03-15" | quoted string | Formation date |
Any key not in the reserved set (status, tax, role, note, est) is stored as a custom property.
entity alice "Alice Chen" individual [role: "Founder & CEO"]
entity trust1 "Smith Irrevocable Trust" trust@SD [est: "2019-06-01", note: "Spendthrift provisions"]
entity opco "OpCo, Inc." corp@DE [status: new, tax: ccorp]4. Jurisdiction
Append @CODE after the entity type to display a jurisdiction badge on the node. The code is a 2–3 letter string — ISO 3166-1 alpha-2 country codes and US state abbreviations are both accepted.
entity parent "Parent Corp" corp@US
entity ie_sub "Ireland Sub" corp@IE
entity ky_fund "Cayman Fund" lp@KY
entity de_llc "Delaware LLC" llc@DECommon codes: US United States · DE Delaware · CA California · NY New York · UK United Kingdom · IE Ireland · NL Netherlands · KY Cayman Islands · SG Singapore · HK Hong Kong · JP Japan · BM Bermuda · VG British Virgin Islands · CH Switzerland · LU Luxembourg · SD South Dakota.
@DE resolves as Delaware by default (most common in US legal contexts).
Jurisdiction clusters
Declare a jurisdiction with jurisdiction CODE "Name" [color: "#hex"] to group all entities sharing that code into a labeled, dashed-border cluster region on the diagram.
jurisdiction US "United States" [color: "#3b82f6"]
jurisdiction IE "Ireland" [color: "#059669"]When an entity's @CODE matches a declared jurisdiction, it is automatically placed inside that cluster. If jurisdiction is not declared, the badge still appears but no cluster region is drawn.
Manual clusters
Use cluster "Label" [members: [id1, id2], color: "#hex"] to group entities that don't share a single jurisdiction code.
cluster "Ireland / Cayman IP" [members: [ie_ip, nl_bv], color: "#059669"]5. Ownership edges
An edge line connects two entity IDs with an operator. The operator determines the line style and visual semantics.
| Operator | Renders as | Meaning |
|---|---|---|
-> | Solid arrow | Equity ownership (default) |
==> | Double line arrow | Voting-only control (no economic interest) |
-.-> | Dashed grey arrow | Option pool / conditional ownership |
-~-> | Dashed purple arrow | IP license, management agreement, intercompany service |
--> | Dashed green arrow | Distribution (trust to beneficiaries) |
Ownership percentage: append : pct after the target ID.
parent -> subsidiary : 60%Share class: add [class: "Series A Pref"] to label the share class on the edge.
vc -> startup : 22% [class: "Series A Pref"]Non-equity label: use [label: "…"] for descriptive edge text on license or distribution edges.
ip_co -~-> opco [label: "IP License · royalty"]
trust --> beneficiary [label: "Discretionary distributions"]Combining: class: and label: can appear together.
fund -> portfolio : 35% [class: "Common", label: "Post-Series B"]6. Labels & comments
- Title:
entity-structure "Acme Holdings"— first line, quoted. - Entity display name: the quoted string in
entity ID "Name" type— appears inside the node. - Jurisdiction badge:
@CODEafter type — 2–3 letter code shown in the node corner. - Node properties:
[note: "…", role: "…", status: new, …]— annotations inside the node. - Edge percentage:
: pctafter the target ID — appears on the ownership arrow. - Edge class:
[class: "…"]— share class label on the arrow. - Edge label:
[label: "…"]— descriptive text on the arrow. - Comments:
#at the start of a line (after leading whitespace). Inline trailing#comments inside bracket blocks are also stripped.
7. Reserved words & escaping
Reserved at line start: entity-structure (header), entity, jurisdiction, cluster.
Entity type keywords — these strings are parsed as entity types and must not be used as entity IDs: corp, corporation, inc, llc, llp, gmbh, bv, lp, lllp, fund, trust, individual, person, foundation, npo, disregarded, branch, pool, placeholder, tbf.
Edge operator tokens — avoid these sequences inside IDs: ->, ==>, -.->, -~->, -->.
Strings with spaces must be double-quoted in display names, notes, role labels, and color values.
Jurisdiction codes are case-insensitive in the source but normalized to uppercase: @de and @DE are equivalent.
8. Common mistakes
| You wrote | Parser says | Fix |
|---|---|---|
entity acme Acme Inc. corp@DE (name unquoted) | Parse fails — name must be quoted | entity acme "Acme Inc." corp@DE |
acme -> sub [50%] (percent inside brackets) | 50% not recognized as a property key | acme -> sub : 50% (colon before percent, outside brackets) |
entity acme "Acme" Ltd@DE | Ltd is not a recognized type keyword | Use corp or llc; Ltd is not in the alias table |
acme -> unknown_id : 100% | EntityParseError: Edge references unknown entity "unknown_id" | Declare every entity before using it in an edge |
cluster "US entities" [ids: [a, b]] | ids: not recognized; property is silently ignored | Use members: [a, b] |
jurisdiction DE "Delaware" then entity co "Co" corp@DE | Cluster draws around co — correct. But @DE in a US context is Delaware, not Germany | Use @DE for Delaware, @DEU is not valid — there is no ambiguity workaround; document the intent in a note: |
entity x "X" corp [status: pending] | pending is not a valid status — property silently stored as custom prop | Use new, eliminated, modified, or normal |
9. Grammar (EBNF)
document = header (blank | comment | jurisdiction-def | cluster-def | entity-def | edge)*
header = "entity-structure" ( WS quoted-string )? NEWLINE
quoted-string = '"' any-char-but-quote* '"'
jurisdiction-def = "jurisdiction" CODE WS quoted-string ( "[" jur-attrs "]" )? NEWLINE
jur-attrs = jur-attr ("," jur-attr)*
jur-attr = "color:" quoted-string
cluster-def = "cluster" WS quoted-string ( "[" cluster-attrs "]" )? NEWLINE
cluster-attrs = cluster-attr ("," cluster-attr)*
cluster-attr = "members:" "[" id ("," id)* "]"
| "color:" quoted-string
entity-def = "entity" WS id WS quoted-string WS entity-type ( "@" CODE )?
( "[" entity-attrs "]" )? NEWLINE
entity-attrs = entity-attr ("," entity-attr)*
entity-attr = "status:" status
| "tax:" quoted-string
| "role:" quoted-string
| "note:" quoted-string
| "est:" quoted-string
| key ":" quoted-string # custom property
entity-type = "corp" | "corporation" | "inc"
| "llc" | "llp" | "gmbh" | "bv"
| "lp" | "lllp" | "fund"
| "trust"
| "individual" | "person"
| "foundation" | "npo"
| "disregarded" | "branch"
| "pool"
| "placeholder" | "tbf"
edge = id WS op WS id ( ":" WS pct-text )? ( "[" edge-attrs "]" )? NEWLINE
op = "->" | "==>" | "-.->" | "-~->" | "-->"
pct-text = any text up to "[" or end of line # e.g. "100%" or "V 75% / E 50%"
edge-attrs = edge-attr ("," edge-attr)*
edge-attr = "class:" quoted-string
| "label:" quoted-string
status = "new" | "eliminated" | "modified" | "normal"
CODE = [A-Za-z]{2,3}
id = [A-Za-z] [A-Za-z0-9_-]*
comment = "#" any NEWLINEAuthoritative source: src/diagrams/entity/parser.ts. If this diverges from the parser, the parser wins — please open an issue.
10. Standard compliance
Schematex entity structure diagrams synthesize conventions from:
- SEC Regulation S-K, Item 601(b)(21) — Exhibit 21 subsidiary disclosure conventions
- IRS Form 8832 — C-corp / pass-through / disregarded entity classifications
- ISO 3166-1 alpha-2 — jurisdiction codes on node badges
- ISO 20275:2017 — Legal Entity Identifier (LEI) entity form classification
- OECD Transfer Pricing Guidelines (2022) — cross-border IP license and royalty flow conventions
- Big Four tax memo conventions (EY / PwC / KPMG / Deloitte) — de-facto standard for cross-border structure diagrams
What is implemented today:
- ✅ Nine entity types with distinct shapes:
corp,llc,lp,trust,individual,foundation,disregarded,pool,placeholder - ✅ Type aliases:
corporation,inc,llp,gmbh,bv,lllp,fund,person,npo,branch,tbf - ✅ Five edge operators:
->(ownership),==>(voting),-.->(pool),-~->(license),-->(distribution) - ✅ Ownership percentage labels (
: pct) and share class ([class: "…"]) - ✅ Jurisdiction badges (
@CODE) with ISO 3166-1 and US state codes - ✅ Jurisdiction cluster regions (dashed-border grouping by
@CODE) - ✅ Manual clusters (
cluster "…" [members: […]]) - ✅ Node properties:
status,tax,role,note,est, custom key-value pairs - ⏳ V/E split percentage —
V 75% / E 50%stored inpercentagestring but rendering as two-line label not yet implemented - ⏳ Transaction-step diff rendering —
status: new/eliminated/modifiedstored but visual diff badges not yet rendered - ⏳ Inline share-count annotation —
100 shares Commonalongside percentage
11. Related examples
12. Roadmap
Planned — not yet parseable. Do not use these in generated DSL today; the parser will reject or ignore them.
- V/E split rendering —
V 75% / E 50%on a single edge, displayed as a two-line percentage label distinguishing voting interest from economic interest. - Transaction-step diff badges —
status: newrenders a green "NEW" badge;status: eliminatedrenders a red strikethrough; used for pre/post M&A structure comparison on a single diagram. - Share count annotation —
-> sub : 100 shares Commonalongside a percentage to capture the exact share count from a capitalization table. - Bidirectional ownership — explicit
<->edge for cross-ownership (two entities holding each other), with S-curve routing to avoid clutter. - Legend block — auto-generated legend showing shape-to-entity-type and operator-to-relationship-type mapping.
Track in the GitHub issues if you need any of these sooner.