ggen - Ontology-Driven Code Generation
Transform RDF ontologies into typed code through SPARQL queries and Tera templates.
π What is ggen? (Explanation)
ggen is a deterministic code generator that bridges semantic web technologies (RDF, SPARQL, OWL) with modern programming languages. Instead of manually maintaining data models in multiple languages, you define your domain once as an RDF ontology and generate type-safe code across Rust, TypeScript, Python, and more.
Why ontologies?
- Single Source of Truth: Define your domain model once, generate everywhere
- Semantic Validation: Use OWL constraints to catch domain violations at generation time
- Inference: SPARQL CONSTRUCT queries materialize implicit relationships before code generation
- Deterministic: Same ontology + templates = identical output (reproducible builds)
Use Cases
- API Development: Generate client libraries from OpenAPI specs converted to RDF
- Data Modeling: Ensure consistency across microservices
- Academic Research: Generate code from domain ontologies (biology, chemistry, finance)
- Multi-Language Projects: Keep Rust backend and TypeScript frontend in sync
π Quick Start (Tutorial)
Installation
# Install via cargo
# Verify installation
Your First Sync (5 minutes)
Step 1: Create a minimal ontology (schema/domain.ttl)
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ex: <https://example.com/> .
ex:Person a rdfs:Class ;
rdfs:label "Person" ;
rdfs:comment "Represents a person in the system" .
ex:name a rdf:Property ;
rdfs:domain ex:Person ;
rdfs:range rdfs:Literal ;
rdfs:label "name" .
ex:email a rdf:Property ;
rdfs:domain ex:Person ;
rdfs:range rdfs:Literal ;
rdfs:label "email" .
Step 2: Create a configuration (ggen.toml)
[]
= "my-first-ggen"
= "0.1.0"
= "Learning ggen with a simple Person model"
[]
= "schema/"
= "templates/"
= "src/generated/"
Step 3: Create a Rust template (templates/rust-struct.tera)
// Generated by ggen from {{ ontology }}
{{
pub : ,
}
Step 4: Run sync
# Output:
# β
Loaded ontology: schema/domain.ttl (3 triples)
# β
Rendered template: rust-struct.tera
# β
Generated: src/generated/domain.rs (42 lines)
# β
Sync complete in 0.2s
What you'll get (src/generated/domain.rs):
// Generated by ggen from domain.ttl
π How-To Guides (Problem-Oriented)
How to sync a workspace with multiple crates
# Sync all workspace members
# Sync specific member
How to preview changes before applying
# Dry-run mode (no file writes)
# Verify mode (CI/CD validation)
||
How to preserve manual edits in generated files
Mark custom code with // MANUAL comments:
// GENERATED CODE (readonly)
// MANUAL: Custom validation logic (preserved during sync)
Then use incremental mode:
How to use SPARQL CONSTRUCT for inference
Add inference rules to your ontology:
@prefix ggen: <https://ggen.io/ns#> .
ex:InferredRule a ggen:ConstructQuery ;
ggen:query """
CONSTRUCT {
?person ex:hasContactInfo ?email .
}
WHERE {
?person ex:email ?email .
}
""" .
The CONSTRUCT query materializes new triples before code generation.
How to integrate with CI/CD
GitHub Actions (.github/workflows/codegen.yml):
name: Code Generation
on:
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo install ggen
- run: ggen sync --mode verify
- name: Fail if generated code is out of sync
run: git diff --exit-code src/generated/
How to publish a package to the ggen marketplace
Create gpack.toml:
[]
= "awesome-templates"
= "1.0.0"
= "Your Name"
= "you@example.com"
= "Reusable Tera templates for API generation"
= "MIT"
= "https://github.com/yourname/awesome-templates"
[]
= ["api-client.tera", "server-stubs.tera"]
[]
= ["ggen >= 5.0.0"]
Then publish:
π Reference (Information-Oriented)
Command: ggen sync
Signature:
ggen sync [OPTIONS] [--from <SOURCE>] [--to <TARGET>]
Options:
| Flag | Type | Default | Description |
|---|---|---|---|
--from |
STRING | . |
Source path (ontology or workspace) |
--to |
STRING | Auto | Target output directory |
--mode |
STRING | full |
Sync mode: full, incremental, verify |
--dry-run |
BOOL | false |
Preview changes without writing files |
--force |
BOOL | false |
Override conflicts (use with caution) |
--verbose |
BOOL | false |
Show detailed operation logs |
Sync Modes:
full: Regenerate all artifacts from scratch (initial setup, major updates)incremental: Update only changed elements, preserve// MANUALsections (development iteration)verify: Check consistency without modifying files (CI/CD validation)
Exit Codes:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Manifest validation error |
| 2 | Ontology load error |
| 3 | SPARQL query error |
| 4 | Template rendering error |
| 5 | File I/O error |
| 6 | Timeout exceeded |
Configuration: ggen.toml
Located at repository root (same level as Cargo.toml).
Minimal configuration:
[]
= "my-project"
= "1.0.0"
[]
= "schema/"
= "src/generated/"
Complete schema:
[]
= STRING # Project identifier (required)
= STRING # Semantic version (required)
= STRING # Project description
= [STRING, ...] # Author list
= STRING # SPDX license (MIT, Apache-2.0, etc.)
[]
= STRING # Ontology directory (default: "schema/")
= STRING # Templates directory (default: "templates/")
= STRING # Output directory (default: "generated/")
= BOOL # Enable incremental sync (default: true)
= BOOL # Overwrite existing files (default: false)
[]
= BOOL # Enable sync (default: true)
= STRING # Trigger: "save" | "commit" | "manual" (default: "save")
= BOOL # Run validation after sync (default: true)
= STRING # Handle conflicts: "fail" | "warn" | "ignore" (default: "fail")
[]
= [STRING, ...] # Supported formats: ["turtle", "rdf-xml", "n-triples"]
= STRING # Default format (default: "turtle")
= STRING # Base URI for ontology (optional)
= BOOL # Strict RDF validation (default: false)
[]
= BOOL # Cache compiled templates (default: true)
= BOOL # Reload on file change (default: true)
[]
= STRING # Package registry URL
= STRING # Cache directory (default: ".ggen/cache/")
= BOOL # Verify signatures (default: true)
[]
= STRING # Formatter: "default" | "rustfmt" | "prettier" | "black"
= INTEGER # Max line length (default: 100)
= INTEGER # Indentation width (default: 2)
Environment variable expansion:
[]
= "${SCHEMA_DIR:schema/}" # Use SCHEMA_DIR env var or default
= "${OUT_DIR:generated/}"
CLI overrides:
Package Distribution: gpack.toml
For publishing reusable templates to the marketplace.
[]
= STRING # Package identifier
= STRING # Semantic version
= STRING # Author name
= STRING # Contact email
= STRING # Package description
= STRING # SPDX license
= STRING # Git repository URL
= STRING # Documentation URL
= [STRING, ...] # Search keywords
[]
= [STRING, ...] # Template files to include
[]
= [STRING, ...] # Version requirements (e.g., "ggen >= 5.0.0")
πΊοΈ Project Structure Example
my-project/
βββ ggen.toml # Project configuration
βββ schema/
β βββ domain.ttl # RDF ontology (Turtle format)
β βββ constraints.ttl # OWL constraints
βββ templates/
β βββ rust-struct.tera # Tera template for Rust
β βββ ts-interface.tera # Tera template for TypeScript
β βββ python-dataclass.tera # Tera template for Python
βββ src/
β βββ generated/ # Output of ggen sync
β β βββ domain.rs
β β βββ types.ts
β β βββ models.py
β β βββ .manifest # Sync metadata
β βββ main.rs
βββ Cargo.toml # Rust workspace
π Links
- Documentation: https://docs.ggen.io
- GitHub: https://github.com/seanchatmangpt/ggen
- Crates.io: https://crates.io/crates/ggen
- Examples: examples/
- Contributing: CONTRIBUTING.md
π License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
π€ Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Built with:
- π¦ Rust 1.75+ (edition 2021)
- π Oxigraph (RDF store)
- π SPARQL 1.1
- π¨ Tera (template engine)
- βοΈ cargo-make (build automation)
- π§ͺ Chicago School TDD (state-based testing)