/makepad-2.0-splash
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,
$ npx -y skills add ZhangHanDong/makepad-skills --skill makepad-2.0-splash --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/makepad-2.0-splash
Context preview
The summary Claude sees to decide when to auto-load this skill.
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,
SKILL.md
makepad-2.0-splash.SKILL.mdname: 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:
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:
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 valueStreaming Evaluation
Splash's parser supports checkpoint-based incremental parsing, designed for AI/LLM streaming code generation:
// 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):
// 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 streaming
Read more
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:
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:
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 valueStreaming Evaluation
Splash's parser supports checkpoint-based incremental parsing, designed for AI/LLM streaming code generation:
// 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):
// 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 streaming
Skills for building cross-platform UI applications with Makepad 2.0.
Other skills on makepad-skills.
- /makepad-2.0-animation
CRITICAL: Use for Makepad 2.0 animation system. Triggers on: makepad animation, makepad animator, Animator, AnimatorState, hover effect, makepad transition, animation state, Forward, Snap, Loop, ease function, makepad animate, timeline, snap(), default @off, animation group, 动画,
Open skill - /makepad-2.0-app-structure
CRITICAL: Use for Makepad 2.0 app structure and Rust integration. Triggers on: makepad app, makepad getting started, app_main!, App::run, MatchEvent, AppMain, handle_event, handle_actions, ScriptVm, from_script_mod, makepad boilerplate, makepad new project, makepad cargo,
Open skill - /makepad-2.0-design-judgment
CRITICAL: Entry-level skill for Makepad 2.0 GUI development. This is the FIRST skill to load for any Makepad task — it provides design judgment anchors ABOVE the other 13 Makepad 2.0 skills. Triggers on: makepad, makepad app, makepad project, makepad design, live_design!,
Open skill - /makepad-2.0-dsl
CRITICAL: Use for Makepad 2.0 DSL syntax and property system. Triggers on: makepad dsl, script_mod!, makepad syntax, makepad property, makepad 2.0 syntax, colon syntax, merge operator, named instance, let binding, mod.widgets, register_widget, script_component, type_default,
Open skill - /makepad-2.0-events
CRITICAL: Use for Makepad 2.0 event and action handling. Triggers on: makepad event, makepad action, MatchEvent, handle_event, handle_actions, on_click, on_render, on_return, on_startup, script_eval!, script_apply_eval!, button clicked, text changed, slider changed, checkbox
Open skill - /makepad-2.0-layout
CRITICAL: Use for Makepad 2.0 layout system. Triggers on: makepad layout, makepad width, makepad height, makepad flex, makepad flow, makepad padding, makepad margin, makepad spacing, makepad align, makepad sizing, Fill, Fit, Inset, Flow.Down, Flow.Right, ScrollXView,
Open skill

