How might we create tools that let designers sketch behavior as naturally as they sketch screens?

Sketching States Before Screens #

Exploring how plain-text state sketching and behavior-first design help clarify complex UI interactions before visual design, improving collaboration and product flow.

After a few years away from publishing, I’m rebooting this site with something I’ve been quietly exploring: a plain-text way to sketch product flows and UI behavior before jumping into visual design.

This started a while back when I was designing a handheld Android barcode scanner used by warehouse workers. The interface was straightforward, but the system logic wasn’t. I kept hitting the same question: “What happens now? What happens next?”

Statecharts helped me map out the complexity — user input, errors, retries, edge cases — but the tooling felt scattered. I had diagrams in one place, design files in another, and notes everywhere. I tried Sketch.systems and other tools, but I still ended up stitching things together manually.

Visual design tools are great at showing how an interface looks — but not how it behaves.

And yet, behavior is where so many product decisions live. These moments — when something fails, changes, or surprises the user — shape the actual experience.

State thinking helps expose those questions early. It gives designers and developers a shared language for what the app does, not just what it shows.

So I started tinkering with a lightweight DSL (domain-specific language) to describe app behavior in text. Something expressive but not overly technical. Here's a simplified example:

Repository Page
keypress "/" -> CommandPalette:active

CommandPalette
query_scope: repo:owner/repo

Inactive*

Active&
type "test" -> Suggestions / "Jump to" updated w/ params
keypress "Enter" => SERP w/ query_scope

This lets me describe screens, components, parameters, nested states, and user interactions in a clear and readable way — kind of like writing a narrative sequence like a screenplay.

I’ve also been converting this DSL into a flattened XState machine that works with the Stately visualizer. Seeing the behavior mapped out visually helps me validate the logic early, even before I start drawing screens.

Here’s how the DSL elements map to XState structures:

DSL ElementDSL SyntaxXState Representation
Page / ScreenRepository PageTop-level state (e.g., RepositoryPage)
ComponentCommandPaletteNested state inside parent (e.g., RepositoryPage.states.CommandPalette)
Parameterquery_scope: repo:owner/repoStored in context
Initial StateInactive*initial: 'Inactive'
Parallel StateActive&type: 'parallel' inside XState
User Action / Eventkeypress "/"Event (e.g., KEYPRESS_Slash)
Transition->Internal transition (e.g., on: { KEYPRESS_Slash: ... })
Navigation=>target with absolute path or external screen state
Nested SelectorSuggestions / "Jump to"Nested state paths

And here’s a matching snippet from the XState machine:

import { createMachine } from 'xstate';

const appMachine = createMachine({
id: 'App',
initial: 'RepositoryPage',
states: {
RepositoryPage: {
id: 'RepositoryPage',
initial: 'CommandPalette',
states: {
CommandPalette: {
id: 'CommandPalette',
initial: 'Inactive',
states: {
Inactive: {
on: {
KEYPRESS_Slash: 'Active'
}
},
Active: {
type: 'parallel',
states: {
Suggestions: {
id: 'Suggestions',
initial: 'JumpTo',
states: {
JumpTo: {
id: 'JumpTo',
initial: 'Idle',
states: {
Idle: {
on: {
TYPE_test: 'UpdatedWParams'
}
},
UpdatedWParams: {
id: 'UpdatedWParams',
on: {
SELECT_helper_js: '#App.FilePage_helper_js'
}
}
}
}
}
}
},
on: {
KEYPRESS_Enter: '#App.SERP_w_query_scope'
}
}
}
}
}
},
SERP_w_query_scope: {
type: 'final'
},
FilePage_helper_js: {
type: 'final'
}
}
});

This isn’t a product or a full-blown tool — at least not yet. I’m not a developer, so most of this is prototyped by hand. But I’m curious where it might go.

Some ideas I’m thinking about:

For now, it’s just a side project — but one that’s helped me think more clearly about interaction design.

If you’re a designer, developer, or curious hybrid who’s felt limited by UI-first tools, I’d love to hear what you’ve tried — or what you’ve wished existed.

Acknowledgments #

This exploration builds on the work and ideas of others who’ve helped me think differently about interaction design:

Big thanks to them for pushing the field forward.

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Twitter.

Published