PlantUML Syntax

Last updated: March 2026

PlantUML is a text-based diagramming language with broad support in IDEs (IntelliJ, VS Code via extension), Confluence, and many CI documentation pipelines. Diagram2Code parses PlantUML entity diagrams and converts them to the same SQL DDL and ORM output as Mermaid input. If you already use PlantUML for architecture diagrams, this format lets you keep everything in one toolchain.

For output details — SQL DDL generation, type mapping, directives, and ORM models — see the SQL DDL Generation and ORM Generation docs.

Entity & Column Syntax

Every PlantUML diagram must open with @startuml and close with @enduml. Entities are defined with the entity keyword followed by a brace-enclosed column list.

@startuml

entity EntityName {
  * column_name : type <<STEREOTYPE>>
    column_name : type
}

@enduml

The key difference from Mermaid is that PlantUML uses name-first, then type column order, whereas Mermaid uses type first. Each column line contains:

PartRequiredDescription
* prefixNoMarks the column as NOT NULL (required). Columns without * are treated as nullable.
column_nameYesColumn identifier in snake_case. Entity names in PascalCase are automatically converted to lower_snake_case table names in SQL output.
: typeYesAbstract type (int, string, decimal, boolean, timestamp, uuid, text) or a native database type (bigint, varchar(255), etc.)
<<STEREOTYPE>>NoColumn role marker. See below.

Stereotypes (PK / FK / UNIQUE)

Stereotypes replace the Mermaid PK, FK, UK inline markers. They are written as <<STEREOTYPE>> at the end of a column line. Diagram2Code recognises three stereotypes:

StereotypeMermaid EquivalentEffect on SQL output
<<PK>>PKGenerates PRIMARY KEY. Integer PKs become SERIAL / AUTO_INCREMENT as appropriate for the dialect.
<<FK>>FKMarks the column as a foreign key. A matching relationship line is needed to resolve the REFERENCES target.
<<UNIQUE>>UKGenerates a UNIQUE constraint on the column.

A column can carry only one stereotype in PlantUML. For a column that is both a primary key and unique (which is implied anyway), use <<PK>> — the uniqueness of primary keys is enforced by the database automatically.

Relationships

Relationships follow entity blocks and use the same crow's-foot notation as Mermaid. They determine foreign key targets and drive junction-table generation for many-to-many associations.

LeftEntity CARDINALITY "--" CARDINALITY RightEntity : label
TokenMeaning
||Exactly one (mandatory, singular)
|o / o|Zero or one (optional, singular)
}| / |{One or more (mandatory, many)
}o / o{Zero or more (optional, many)

Note that in PlantUML, entity names in relationship lines use their original PascalCase form (matching how they appear in the entity block), not the snake_case form used in the SQL output.

Full Example

PlantUML — Blog schema
@startuml

entity Author {
  * id : int <<PK>>
  * name : string
  * email : string <<UNIQUE>>
  bio : text
}

entity Post {
  * id : int <<PK>>
  * author_id : int <<FK>>
  * title : string
  body : text
  published_at : timestamp
}

entity Tag {
  * id : int <<PK>>
  * name : string <<UNIQUE>>
}

Author ||--o{ Post : writes
Post }|--|{ Tag : tagged

@enduml
Generated PostgreSQL DDL (excerpt)
CREATE TABLE "author" (
  "id" SERIAL PRIMARY KEY,
  "name" TEXT NOT NULL,
  "email" TEXT UNIQUE NOT NULL,
  "bio" TEXT
);

CREATE TABLE "post" (
  "id" SERIAL PRIMARY KEY,
  "author_id" INTEGER NOT NULL
    REFERENCES "author"("id"),
  "title" TEXT NOT NULL,
  "body" TEXT,
  "published_at" TIMESTAMPTZ
);

-- junction table (many-to-many)
CREATE TABLE "post_tag" (
  "post_id" INTEGER NOT NULL
    REFERENCES "post"("id"),
  "tag_id" INTEGER NOT NULL
    REFERENCES "tag"("id"),
  PRIMARY KEY ("post_id", "tag_id")
);

PlantUML vs. Mermaid — Which Should You Use?

Both formats produce identical SQL and ORM output from Diagram2Code. The choice depends on your existing tooling and team conventions:

FactorUse MermaidUse PlantUML
GitHub / GitLab READMENative rendering — no plugin neededRequires a plugin or external renderer
IDE supportVS Code extension, JetBrains pluginFirst-class IntelliJ plugin, Confluence macro
Column notationtype name (type first)name : type (name first, like most languages)
NOT NULL columnsUse ::NN directivePrefix column with *
Existing diagramsIf you have erDiagram files alreadyIf you have @startuml entity files already

Known Limitations