Makepad 2.0 SplashCAUTION
Build App with Makepad and AI skills
Overview
Build App with Makepad and AI skills
7cbc563d4f32OBSERVED · 2026-10-12Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: makepad-2.0-splash
description: |
CRITICAL: Use for Makepad 2.0 Splash scripting language. Triggers on:
splash language, makepad script, script_mod!, makepad scripting, splash 脚本,
makepad 2.0 script, mod.state, on_render, script_eval, streaming evaluation,
splash syntax, splash vm, let binding, splash functions, hot reload, live reload,
ScriptModKey, script_mod_overrides, checkpoint, incremental parsing,
canvas splash, POST splash, fn tick, on_audio, set_text, tab switching,
音乐播放器, token monitor, driver script, audio API,
热重载, 脚本引擎, 增量解析
---
# Makepad 2.0 Splash Scripting Language
Splash is Makepad 2.0's core runtime UI scripting language, released February 12, 2026. It replaces the old compile-time `live_design!` macro system with a runtime `script_mod!` macro that enables hot reload, streaming evaluation, and AI-first code generation.
## Core Concepts
### Script Structure
Every Splash script starts with a `use` import and is embedded in Rust via the `script_mod!{}` macro:
```rust
use makepad_widgets::*;
app_main!(App);
script_mod! {
use mod.prelude.widgets.*
// let bindings, functions, state, and UI definitions go here
startup() do #(App::script_component(vm)){
ui: Root{
main_window := Window{
window.inner_size: vec2(800, 600)
body +: {
// UI content
}
}
}
}
}
```
### Syntax Rules
- **No commas** between properties -- whitespace-delimited
- **No semicolons** -- cleaner syntax optimized for LLM generation
- **Property assignment**: `key: value`
- **Dot-path shorthand**: `draw_bg.color: #f00` (equivalent to `draw_bg +: { color: #f00 }`)
- **Merge operator**: `key +: { ... }` extends parent without replacing
- **Named children**: `name := Widget{...}` (addressable, overridable per-instance)
- **Let bindings**: `let MyTemplate = Widget{...}` (local scope, must be defined before use)
- **Rust binding**: `#(Struct::register_widget(vm))` connects Splash to Rust structs
- **Debug logging**: `~expression` logs value during evaluation
### State Management
State is managed via the `mod.state` object and reactive `on_render` callbacks:
```
// Define state
let state = { counter: 0 }
mod.state = state
// Reactive rendering -- re-runs when .render() is called
main_view := View{
on_render: ||{
Label{ text: "Count: " + state.counter }
}
}
```
### Event Handling
Events are handled both inline in Splash and from Rust:
```
// Inline event handlers in Splash
add_button := Button{
text: "Add"
on_click: ||{
add_todo(ui.todo_input.text(), "")
ui.todo_input.set_text("")
}
}
// TextInput return key
todo_input := TextInput{
on_return: || ui.add_button.on_click()
}
// Startup event
on_startup: ||{
ui.main_view.render()
}
```
From Rust, use `script_eval!` to execute Splash code:
```rust
impl MatchEvent for App {
fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) {
if self.ui.button(cx, ids!(increment_button)).clicked(actions) {
script_eval!(cx, {
mod.state.counter += 1
ui.main_view.render()
});
}
}
}
```
### Functions
```
fn tag_color(tag) {
if tag == "dev" theme.color_highlight
else if tag == "design" theme.color_selection_focus
else theme.color_highlight
}
fn add_todo(text, tag) {
todos.push({text: text, tag: tag, done: false})
ui.todo_list.render()
}
```
### Control Flow
```
// If/else
if todos.len() == 0
EmptyState{}
else for i, todo in todos {
TodoItem{ label.text: todo.text }
}
// For loops
for i, item in array {
Label{ text: item.name }
}
// While
while condition { ... }
```
### HTTP Requests
```
let req = net.HttpRequest{
url: "https://api.example.com/data"
method: net.HttpMethod.GET
headers: {"User-Agent": "MakepadApp/1.0"}
}
net.http_request(req) do net.HttpEvents{
on_response: |res| {
let text = res.body.to_string()
let json = res.body.parse_json()
}
on_error: |e| { /* handle error */ }
}
```
Streaming responses use `is_streaming: true` with `on_stream` and `on_complete` callbacks.
### HTML Parsing
```
let doc = html_string.parse_html()
doc.query("p") // all <p> elements
doc.query("#main") // by id
doc.query("p.bold") // by class
doc.query("div > p") // direct children
doc.query("p[0]").text // text content
doc.query("a@href") // attribute value
```
### Streaming Evaluation
Splash's parser supports checkpoint-based incremental parsing, designed for AI/LLM streaming code generation:
```rust
// Rust API for streaming evaluation
vm.eval_with_append_source(script_mod, &code, NIL.into())
```
This enables real-time UI updates as code is generated token-by-token, without requiring a complete script before evaluation.
### Hot Reload & Script Mod Tracking
Splash scripts support hot reload via the `--hot` flag. The VM tracks each `script_mod!` block with a unique `ScriptModKey` (file, line, column):
```rust
// Internal: ScriptModKey uniquely identifies a script_mod! block
ScriptModKey { file: "src/app.rs", line: 5, col: 1 }
// Runtime substitution via overrides
ScriptCode::script_mod_overrides // HashMap of ScriptModKey -> updated source
```
**How hot reload works:**
1. File watcher (`makepad_live_reload_core`) detects source file changes
2. `script_mod!` blocks are extracted from Rust source (handles raw strings, comments, char literals)
3. Rust placeholder counts (`#(...)`) are tracked -- adding/removing placeholders requires full rebuild
4. Validated script mods are applied via `script_mod_overrides`
5. IP-to-location mapping provides source maps for error reporting (fallback to nearest token for synthetic opcodes)
**ScriptSource variants:**
- `ScriptSource::Mod` -- Standard module evaluation (startup)
- `ScriptSource::Streaming` -- Incremental streamingTrust audit
CAUTIONgrade B · trust 86/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (6)
curl -s -X POST "http://127.0.0.1:$PORT/splash" -d 'View{width:Fill height:Fit Label{text:"Hello"}}'curl -s -X POST "http://127.0.0.1:$PORT/splash/stream" # begin
curl -s -X POST "http://127.0.0.1:$PORT/splash/stream" -d 'View{...' # appendcurl -s -X POST "http://127.0.0.1:$PORT/splash/end" # end
curl -s -X POST "http://127.0.0.1:$PORT/clear"
Gates applied: no_behavioural_pass, no_license.
7cbc563d4f32full audit observations/trust-audit/skill/zhanghandong__makepad-2.0-splash.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | 7cbc563d4f32 | CAUTION | B | 86 | first audit |
Questions
What does the Makepad 2.0 Splash skill do?
Build App with Makepad and AI skills
Is Makepad 2.0 Splash safe to install?
With care. The audit graded it B (86/100) and found 6 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can Makepad 2.0 Splash access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Makepad 2.0 Splash work with?
Its documentation mentions claude-code and cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (7cbc563d4f32), read on 2026-10-12. The repository is watched, and a new audit runs when it changes — this is the first audit.