A hybrid full-stack application demonstrating TMF (TypeScript Model Framework) integration with Eclipse EMF (Java) - showcasing how the same Ecore metamodel can generate both TypeScript and Java model code in an Nx monorepo.
- Polyglot Shared Data Model - Single Ecore metamodel generates both TypeScript (TMF) and Java (EMF) classes
- Hybrid Architecture - Angular frontend with Spring Boot backend, both using the same domain model
- Cross-Language Serialization - TJson implementations in both TypeScript and Java ensure identical serialization behavior
- Full Reflective Stack - Model-driven REST APIs, UI forms, and reference resolution across language boundaries
- Data Model (TypeScript) (
libs/datamodel-ts) - Generated fromTripPlanning.ecoreusing TMF - Data Model (Java) (
libs/datamodel-java) - Generated fromTripPlanning.ecoreusing Eclipse EMF - Backend (
apps/backend) - Spring Boot with EMF-based model handling - Client (
apps/client) - Angular app with TMF reflective editor - Model (
model/) - Shared Ecore metamodel definitions
# Install dependencies
npm install
# Start Java backend (port 8080)
nx serve backend
# In another terminal, start Angular client (port 4200)
nx serve clientVisit http://localhost:4200 to see the reflective model editor in action. Data created in the Angular frontend is persisted by the Java Spring Boot backend (simple file-based persistence).
The example models a trip planning domain with:
- Trip - Main aggregate with segments, participants, dates, and budget
- TripSegment - Trip sections with origin/destination and activities
- Traveler - People with interests and contact info
- Location - Places of interest (cities, hotels, restaurants, attractions)
- Activity - Planned activities for each segment
- TMF (TypeScript) - Lightweight EMF port for frontend development
- Eclipse EMF (Java) - Industry-standard modeling framework for backend
- Shared Metamodel - Single
TripPlanning.ecoregenerates both implementations
- TJson TypeScript - JSON serialization with cross-reference support
- TJson Java - Matching serialization behavior ensuring data compatibility
- Angular 19 with standalone components and TMF reflective editor
- Spring Boot with EMF integration and custom JSON utilities
- Nx Monorepo with optimized build caching and dependency management
# Generate TypeScript models from Ecore
npm run gen:datamodel-ts
# Java models require Eclipse EMF tooling
# Open model/*.ecore and *.genmodel files in Eclipse with EMF- Edit Metamodel - Modify
model/TripPlanning.ecore - Generate TypeScript - Run
npm run gen:datamodel-ts - Generate Java - Use Eclipse EMF tooling to regenerate Java classes (You just need to open the .ecore and .genmodel files)
- Factory Pattern for creating model instances (
TripplanningFactory.eINSTANCE) - Package Singletons for metamodel access (
TripplanningPackage.eINSTANCE) - Containment & Cross-References with automatic bidirectional updates
- Reflective APIs that adapt to any metamodel changes
- Observable Collections (EList) for reactive model relationships
- Type Safety across TypeScript frontend and Java backend
angular-java-nx/
├── apps/
│ ├── backend/ # Spring Boot backend
│ └── client/ # Angular frontend
├── libs/
│ ├── datamodel-java/ # Generated Java EMF classes
│ └── datamodel-ts/ # Generated TypeScript TMF classes
├── model/
│ └── TripPlanning.ecore # Shared metamodel
└── tools/ # Nx workspace configuration
- TMF Github Repository
- TMF npm package
- Eclipse EMF Documentation
- TMF Ecore Editor - VSCode extension for editing ecore files
- TripSnek - Travel itinerary optimization app built on top of TMF