LPG ModelerDesign a property graph once. Generate every schema from it. LPG Modeler turns one hand-editable model file into LadybugDB DDL, Neo4j constraints, SHACL shapes, an OWL ontology, GQL graph types, PG-Schema and LinkML — and tells you, before you ship, exactly what each database is unable to enforce. You author the model as YAML, or on a canvas beside it. Everything downstream is generated.
The problem it removesA graph schema usually lives in four places at once: the DDL that creates the tables, the constraint script someone ran last quarter, a diagram in a wiki that stopped being true, and an ontology maintained by a different team. They drift. The diagram says a property is required. The database never enforced it. Nobody finds out until a null reaches production. LPG Modeler makes three of those four artifacts generated, and makes the fourth one reviewable text. What it doesA canvas that writes the fileCreate node types, draw edges, add properties and rename things directly on the diagram. Every action becomes a targeted edit to the YAML, applied as a workspace edit — so undo, dirty state and version control all behave the way you expect. The canvas opens beside the file, in the manner of Markdown preview. It never replaces the editor, so you keep schema-driven completion and hover in the YAML itself.
Why it matters: the webview holds no model state. It posts an intent, the extension host computes the edits, and a fresh diagram comes back from the file. Nothing on screen can diverge from what your teammates will review. Diffs you can actually reviewEdits are computed as text splices from the YAML syntax tree, never as a re-serialization. Renaming a type changes exactly the lines that name it — not the whole file. Diagram coordinates live in a separate sidecar keyed by a stable element id, so rearranging a diagram produces no semantic diff at all, and renaming a type moves nothing on screen.
Why it matters: a schema change that shows up as a 400-line reformat does not get reviewed. It gets approved. Inheritance and mixins, kept apartA node type may extend an abstract label, and it may apply any number of mixins. These look alike and are not: inheritance says what a thing is, and a mixin says what a thing carries.
A mixin has no box on the canvas, because it is not a type — it gets the panel instead,
listing its properties and every type that applies it, so you can see what a change would
touch before making it. The nearer declaration wins: a type's own property beats a mixin's,
and a mixin's beats an ancestor's. The first is reported at Why it matters: conflating reuse with subtyping produces a hierarchy shaped by which
properties happen to travel together rather than by what a thing is. Seven generators, one model
One type hierarchy, one set of keys, one set of properties — with no second definition to keep in sync. The last three are standards rather than database dialects. They are what makes a model readable by tools this project does not own — and they are emitted rather than adopted as the model format, because no published standard has anywhere to put stable element ids, import aliases, or a rename's previous IRI. Loss is reported, never silentEach generator publishes what it can express. Everything it cannot becomes a warning in the Problems panel and a comment at the exact line of the generated file, so the operator reading the DDL learns what the author already knew.
Why it matters: a Schema-driven YAML editingThe model format ships as a JSON Schema the extension contributes, so completion, hover documentation and structural errors come from the YAML tooling you already have. There is no new language server to install and no proprietary file format to get locked into. Views, so diagrams stay readableA view names a subset of types plus an optional neighbourhood expansion. One model can carry an overview beside several focused diagrams, and validation tells you which types have fallen out of every view — so diagrams do not quietly stop covering the model as it grows. Serious about RDFThe RDF export is split in two, because a property graph schema and an OWL ontology do not
mean the same thing. SHACL carries the constraints because it is closed-world validation. OWL
asserts only what is safe to assert — no Reification is applied only where it is needed: an edge with no properties stays a plain object property, and an edge that carries properties becomes an n-ary relation class plus a shortcut.
Quick start1. Create a file ending in
2. Run LPG: Open Canvas from the command palette. The diagram opens beside the file. Starting from nothing? Run LPG: New Model instead. It asks for a prefix and a base IRI, writes the file, and opens the canvas on it — no need to know the shape of a model file first. 3. Run LPG: Generate Schema and pick a target. The artifact is written next to the model and opened beside it. That is the whole loop. Nothing here needs a running database. Examples to downloadFive complete models. Each is checked in continuous integration — a test resolves every one
of them and generates all nine targets — so the file you download is the file the test
checked. Save one as
All five, with commentary on what to read in each: https://volland.github.io/lpg-modeler/examples.html Commands
The two export commands are also buttons in the editor title bar, on a model file and on the canvas tab. They honour the canvas toolbar's light checkbox, which swaps in a print-safe palette for the capture. Settings
Files
Also runs in CIThe same resolution and validation the editor runs is available as a command, so a pull request can be gated on the model being valid:
That second step is the one that pays off over time. It turns "someone forgot to regenerate the DDL" from a thing you discover during an incident into a red build. RequirementsVS Code 1.90 or newer. No database connection, container, or external service is required — generation is entirely offline. Known limitations
DocumentationFull documentation, including the model format reference and the design notes behind it: https://volland.github.io/lpg-modeler/ Contributing and issuesSource and issue tracker: github.com/Volland/lpg-modeler. Adding a generation target is one file plus one registry entry — see Targets for the capability set a new one declares. LicenseMIT. |







