PlantUML Salt UI wireframes: from ASCII to UI mockups

puml.online

When you need to document “what the UI looks like” inside a Markdown-friendly diff-able file, PlantUML Salt turns ASCII boxes into readable wireframes. No drawing tool, no Figma — just text.

What is Salt

Salt is PlantUML’s wireframe language. It draws UI windows in pure ASCII; the renderer turns them into readable UI mockups.

1
2
3
4
5
6
7
8
9
10
11
12
@startsalt
{+
--------------------
| Order detail
--------------------
Order id: | "ORD-2026-001"
Customer: | "Alice"
Total: | "299.00"
.
[Cancel] | [Pay]
}
@endsalt

What you get:

  • |...| text input field
  • [ ] checkbox / [X] checked
  • { } window container
  • .{...} dotted separator
  • + nested
  • . vertical space

Element cheat sheet

Element Syntax Render
Text input placeholder Editable field
Filled input {"value"} Filled field
Button [label] Button
Radio ( ) / (X) Empty / selected
Checkbox [ ] / [X] Unchecked / checked
Dropdown ^single ^multi Dropdown
Table {#col1, col2, ..., rows} Table

Real examples

Login form

1
2
3
4
5
6
7
8
9
10
11
@startsalt
{+
Login
----
Email: | "Your email"
Password: | "Your password"
..
[^Remember me]
[Login] | [Cancel]
}
@endsalt

Settings page

1
2
3
4
5
6
7
8
9
10
11
12
13
@startsalt
{+ UserSettings
{ (Basic
Username: | {"alice"}
Email: | {"alice@example.com"}
}
{ (Roles
Role: | ( ) Member | ( ) Editor | (X) Admin
}
..
[Save] | [Cancel]
}
@endsalt

{} inside the root window groups sections.

Table view

1
2
3
4
5
6
7
8
9
10
11
12
13
@startsalt
{+ Orders
{#col1, col2, col3
A | B | C
-- | - | -
cell | cell | cell
cell | cell | cell
cell | cell | cell
}
..
[New] | [Export] | [Delete]
}
@endsalt

Tabs

1
2
3
4
5
6
7
8
@startsalt
{+
{/ <b>Overview</b> | Settings | Permissions | History }
{ Tab content goes here }
..
[Save] | [Cancel]
}
@endsalt

Markdown-embedded content

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@startsalt
{+ Editor
== README.md

This project is a **rich text** editor...
See [PlantUML](https://plantuml.com)

-- separator --

- item 1
- item 2

```plantuml
@startuml
class Demo
@enduml

==
}
@endsalt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

`==...==` block renders Markdown / fenced code.

## Form (lighter variant)

`@startform` / `@endform` is the same engine with a different name; pick whichever you prefer:

```plantuml
@startform
{+ Submit feedback
Name: | "Your name"
Email: | "Your email"
Type | ( ) Bug | ( ) Feature | (X) Suggestion
Detail | "..."
..
[Submit] | [Cancel]
}
@endform

Pairing with JSON for API docs

UI elements and data fields pair clearly:

1
2
3
4
5
6
7
8
9
10
11
@startsalt
{+ User profile
{/ Profile | Orders | Favorites }
{
Avatar: | <img>
Name: | "Alice"
Signed up: | "2026-07-15"
Bio: | "..."
}
}
@endsalt

Companion JSON:

1
2
3
4
5
6
7
8
9
@startjson
{
"user_id": 1024,
"avatar_url": "https://cdn.example.com/avatars/1024.png",
"name": "Alice",
"created_at": "2026-07-15T14:00:00Z",
"bio": "..."
}
@endjson

Real: full login API doc set

1
2
3
4
5
6
docs/login/
login-ui.puml # @startsalt
login-request.puml # @startjson POST /login body
login-response.puml # @startjson POST /login success
login-errors.puml # @startjson error responses
login-sequence.puml # @startuml sequence

5 separate .puml files cover the full Login API + UI + errors surface.

Error-response UI

Validation errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@startsalt
{+ Login - validation
Email: | "alice|"
Password: | ""
.
{#
Error | Field
--------------------------- | -----
Must be a valid email | Email
At least 8 characters | Password
}
..
[Retry]
}
@endsalt

Complex dashboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@startsalt
{+ Admin - data dashboard
{/ <b>Live</b> | 7 days | 30 days | Custom }
{
{ Metric cards (7 days)
{ PV: 12,345 | UV: 4,567 | Conv: 3.2% | Bounce: 21%
.
[+ Add] | [Export]
}
}
{
{# Hot pages,
Page | PV | Share
-------- | -- | -----
Home | 8000 | 35%
Product | 5000 | 22%
Detail | 3000 | 13%
}
}
}
@endsalt

Pick the right tool

Need Use
Wireframe / UI mockup @startsalt
Form fields @startform
API response / config @startjson
Config files @startyaml
Sequence / class / component standard @startuml

Anti-patterns

1. Salt with embedded CSS

1
2
3
4
5
@startsalt
{+ login
email: | <input type="email" class="...">
}
@endsalt

Salt doesn’t support rich styles. For real layouts, switch to Figma / Storybook.

2. JSON not fenced with @startjson

1
2
3
4
5
6
@startuml
{
"code": 0,
"data": []
}
@enduml

Plain @startuml doesn’t auto-expand JSON. Always use @startjson.

3. UI nested too deep

1
2
3
@startsalt
{+ root { { { { {... deep nested ... } } } } }
@endsalt

Past 3 levels of {}, break into separate .puml files (or move to Figma).

Review checklist

Salt

  • All UI elements drawn? Inputs, buttons, selectors?
  • Nesting ≤ 3 levels?
  • Companion JSON for data?

JSON

  • Complete sample responses (success + error)?
  • Field names match code schema?
  • Types clear (string vs number vs boolean)?

TL;DR

Salt lifts wireframes back to text — diffable alongside the actual code in the same review. UI docs don’t need a separate drawing tool any more; they ride in the same git history as the schema they describe.

  • Title: PlantUML Salt UI wireframes: from ASCII to UI mockups
  • Author: puml.online
  • Created at : 2026-07-29 16:10:00
  • Updated at : 2026-08-14 21:34:29
  • Link: https://puml.online/blog/plantuml-salt-form-json-en/
  • License: This work is licensed under CC BY-NC-SA 4.0.