Choose your path
A Mateu UI is one model. You make three choices, and none of them constrains the others:
- How you author it: YAML files, the visual editor (which writes those files), or code in Java, C# or Python.
- Where it renders: a web browser (Vaadin or Oracle Redwood / Visual Builder), the Mateu mobile app, or IntelliJ on the desktop.
- How it is served: by a backend (five Java frameworks, ASP.NET Core or FastAPI), or as a static bundle on a CDN with no backend at all.
You can change your mind about (2) and (3) without touching what you wrote in (1).
The same screen, three ways
Section titled “The same screen, three ways”A product listing with search and a status column, authored three ways. All three produce the same wire model and render identically in every renderer.
type: Listingtitle: Productssearchable: truerowsSource: ref: products # a named endpoint in sources.yamlcolumns: - {type: GridColumn, id: id, label: Id, identifier: true} - {type: GridColumn, id: name, label: Name} - {type: GridColumn, id: price, label: Price} - {type: GridColumn, id: status, label: Status, dataType: status}type: Routesroutes: - route: products layout: products.yamlThe rows come from a REST endpoint declared once in sources.yaml (with sample data until the API
exists). The visual editor writes these files for you. Served by a
backend, or bundled into static files.
public record Product(@NotEmpty String id, @NotEmpty String name, @Min(0) double price, @NotNull ProductStatus status) implements Identifiable {}
@UI("/products")@Title("Products")public class Products extends AutoCrud<Product> { @Override public CrudStore<Product> store() { return ProductStore.INSTANCE; // where the rows live: memory, JPA, a REST client… }}Runs on Spring Boot (MVC or WebFlux), Quarkus, Micronaut or Helidon MP. Beyond the listing you also get create, detail, edit and delete, derived from the record.
public class Product{ [Required] public string Id { get; set; } = ""; [Required] public string Name { get; set; } = ""; [Range(0, double.MaxValue)] public double Price { get; set; } public ProductStatus Status { get; set; }}
[UI("products"), Title("Products")]public class Products : Crud<Product>{ public override IEnumerable<Product> Fetch(string? search) => Store.Search(search); public override Product? Get(string id) => Store.Get(id); public override void Save(Product p) => Store.Save(p); public override void Delete(string id) => Store.Delete(id);}Runs on ASP.NET Core (dotnet add package Mateu.AspNetCore --prerelease).
class Product: id: Annotated[str, Required()] = "" name: Annotated[str, Required()] = "" price: float = 0.0 status: ProductStatus = ProductStatus.Available
@ui("products")@title("Products")class Products(Crud[Product]): def fetch(self, search): return store.search(search) def get(self, id): return store.get(id) def save(self, entity): store.save(entity) def delete(self, id): store.delete(id)Runs on FastAPI (pip install "mateu-ui[all]").
The difference is not in what you can show but in where the behaviour lives. In YAML the screen reads and writes REST endpoints directly (or through a proxy, so secrets stay on a server). In code the screen owns its data access and can run any logic on the server. You can mix the two: layout in YAML, behaviour in code.
Whichever path you take, the UI is made of the same building blocks: a mount, an app shell and menu, routes, pages, partials, actions, data sources and state, plus field types, translations, environments, access rules and project settings. Read What a Mateu UI is made of for the map, with the same product catalogue as its running example. The UX guide then shows what they look like on screen: the app shell, the six page types and the component catalogue.
Which path fits you
Section titled “Which path fits you”| You are… | Start with |
|---|---|
| Building screens over APIs that already exist, without writing code | Quickstart: YAML, then the visual editor |
| A Java team (Spring Boot, Quarkus, Micronaut, Helidon) | Quickstart: Java |
| A .NET team | C# |
| A Python team | Python |
| Designing in Figma first | Figma design-to-code |
| Composing UIs owned by several teams into one console | UI federation |
Three front doors to a new project
Section titled “Three front doors to a new project”- IntelliJ IDEA: File › New › Project… › Mateu. VS Code: command palette › Mateu: New Project…. Both ask how you author (code, code + YAML, YAML served by a backend, YAML static) and which runtime.
- Maven archetype:
mvn archetype:generate -DarchetypeGroupId=io.mateu -DarchetypeArtifactId=mateu-archetype -DarchetypeVersion=<release> -DgroupId=com.acme -DartifactId=my-app(add-Dauthoring=yamlor-Dauthoring=staticfor the YAML flavours). See Create your project. - A starter: the repository’s
starters/folder has one minimal project per runtime (Spring MVC, WebFlux, Quarkus, Micronaut, Helidon MP, .NET, Python, YAML, static). CI builds and boots every one of them.
Then: render and serve
Section titled “Then: render and serve”- Renderers: Vaadin is the default web renderer; Redwood / Visual Builder also embeds Mateu screens inside an existing Visual Builder app; the Mateu mobile app and IntelliJ render natively. See Renderers.
- Deployment: a backend, a static bundle, and guides for Netlify, Kubernetes and the app stores.