
Ux Prototyping
- 1 installs
- 404 repo stars
- Updated August 5, 2026
- aiskillstore/marketplace
ux-prototyping is a skill that generates a single-file interactive HTML prototype from a UX specification to validate user flows and interaction patterns.
About
ux-prototyping builds a single-file HTML prototype from a UX specification to validate user flows, interaction patterns, and information architecture. A developer uses it after writing specs/architecture/ux.md when they want a clickable mockup before committing to real UI code. It focuses on flow fidelity, screen states, and navigation rather than pixel-perfect styling.
- Turns a UX spec into a single-file interactive HTML prototype
- Implements empty, loading, error and success states for each screen
- Prioritizes flow validation over visual polish
Ux Prototyping by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,609 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
ux-prototyping capabilities & compatibility
- Capabilities
- ui design · web design · frontend
- Use cases
- ui design · web design · frontend
What ux-prototyping says it does
Create interactive single-file HTML prototypes for UX validation.
Prioritize UX fidelity over visual polish.
Implement screens as `<section>` elements with `data-screen` attributes:
npx skills add https://github.com/aiskillstore/marketplace --skill ux-prototypingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 404 |
| Last updated | August 5, 2026 |
| Repository | aiskillstore/marketplace ↗ |
What it does
Build an interactive single-file HTML prototype from a UX spec to validate user flows before implementation.
Who is it for?
Validating user journeys and screen states from a UX spec before writing production UI
Skip if: Producing pixel-perfect, brand-styled production UI
When should I use this skill?
You have a UX spec and want a clickable prototype to test flows
What you get
A single HTML file with all screens, states, and navigation ready to click through
- Single-file HTML prototype with all screens and interactions
By the numbers
- 6-item validation checklist before delivery
- 5 screen states covered: empty, loading, error, success, partial
Files
UX Prototyping Skill
Create single-file HTML prototypes focused on validating user flows, interaction patterns, and information architecture. Prioritize UX fidelity over visual polish.
Workflow
1. Read the UX spec at specs/architecture/ux.md (or user-specified path) 2. Identify core flows - Extract user journeys, screens, states, and interactions 3. Build prototype - Create single HTML file with all screens and interactions 4. Output - Save to /mnt/user-data/outputs/prototype.html
Prototype Structure
Generate a single HTML file containing:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[App Name] - UX Prototype</title>
<style>/* All CSS inline */</style>
</head>
<body>
<!-- All screens as sections -->
<!-- Navigation/state management -->
<script>/* All JS inline */</script>
</body>
</html>Core Principles
UX First, UI Second
- Do: Implement all user flows, states, transitions, error states, empty states
- Do: Make interactions feel responsive and logical
- Do: Show realistic data and content hierarchy
- Defer: Pixel-perfect styling, animations, brand colors (use clean defaults)
Screen Management Pattern
Implement screens as <section> elements with data-screen attributes:
function showScreen(screenId) {
document.querySelectorAll('[data-screen]').forEach(s => s.hidden = true);
document.querySelector(`[data-screen="${screenId}"]`).hidden = false;
}State Management Pattern
Use a simple state object:
const state = { currentScreen: 'home', user: null, data: [] };
function setState(updates) { Object.assign(state, updates); render(); }Essential UX Elements
1. User Flows
- Primary task completion paths
- Alternative/secondary flows
- Error recovery flows
2. Screen States
- Empty - First-time user, no data
- Loading - Skeleton or spinner
- Error - Network/validation errors
- Success - Confirmations
- Partial - Some data loaded
3. Interactions
- Form inputs with validation
- Button states (hover/active/disabled)
- Screen navigation
- Modal/overlay behaviors
Base Styles
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f8fafc; --surface: #fff; --text: #1e293b;
--text-muted: #64748b; --primary: #3b82f6; --border: #e2e8f0;
--success: #22c55e; --error: #ef4444; --radius: 8px;
}
body { font-family: system-ui, sans-serif; background: var(--bg); color: var(--text); }
[data-screen] { display: none; }
[data-screen].active { display: block; }
.card { background: var(--surface); border-radius: var(--radius); padding: 1.5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.btn { padding: 0.625rem 1.25rem; border-radius: var(--radius); font-weight: 500; cursor: pointer; border: none; }
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover { background: #2563eb; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.input { width: 100%; padding: 0.625rem; border: 1px solid var(--border); border-radius: var(--radius); }
.input:focus { outline: none; border-color: var(--primary); }
.container { max-width: 480px; margin: 0 auto; padding: 1rem; }
.stack > * + * { margin-top: 1rem; }
.empty-state { text-align: center; padding: 3rem; color: var(--text-muted); }
.error-msg { color: var(--error); font-size: 0.875rem; }Validation Checklist
Before delivering, verify:
- [ ] All screens from spec implemented
- [ ] Primary flow completable end-to-end
- [ ] Empty/error/loading states shown
- [ ] Navigation works correctly
- [ ] Interactive elements have feedback
- [ ] Responsive on mobile viewport
Output
Save to /mnt/user-data/outputs/prototype.html (or descriptive name like prototype-onboarding.html).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>APP_NAME - UX Prototype</title>
<style>
/* Reset & Variables */
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f8fafc;
--surface: #ffffff;
--text: #1e293b;
--text-muted: #64748b;
--primary: #3b82f6;
--primary-hover: #2563eb;
--border: #e2e8f0;
--success: #22c55e;
--error: #ef4444;
--warning: #f59e0b;
--radius: 8px;
--shadow: 0 1px 3px rgba(0,0,0,0.1);
}
/* Base */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
min-height: 100vh;
}
/* Screen Management */
[data-screen] { display: none; min-height: 100vh; }
[data-screen].active { display: flex; flex-direction: column; }
/* Layout */
.container { width: 100%; max-width: 480px; margin: 0 auto; padding: 1rem; }
.stack > * + * { margin-top: 1rem; }
.stack-sm > * + * { margin-top: 0.5rem; }
.row { display: flex; gap: 0.75rem; align-items: center; }
.flex-1 { flex: 1; }
.justify-between { justify-content: space-between; }
.justify-center { justify-content: center; }
.text-center { text-align: center; }
/* Typography */
h1 { font-size: 1.5rem; font-weight: 600; }
h2 { font-size: 1.25rem; font-weight: 600; }
h3 { font-size: 1rem; font-weight: 600; }
.text-muted { color: var(--text-muted); }
.text-sm { font-size: 0.875rem; }
.text-xs { font-size: 0.75rem; }
/* Components */
.card {
background: var(--surface);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 1.25rem;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.625rem 1.25rem;
border-radius: var(--radius);
font-weight: 500;
font-size: 0.9375rem;
cursor: pointer;
border: none;
transition: all 0.15s ease;
text-decoration: none;
}
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover { background: var(--primary-hover); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.btn-secondary:hover { background: var(--bg); }
.btn-ghost { background: transparent; color: var(--primary); }
.btn-ghost:hover { background: rgba(59,130,246,0.1); }
.btn-block { width: 100%; }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.875rem; }
.input-group { display: flex; flex-direction: column; gap: 0.375rem; }
.input-group label { font-size: 0.875rem; font-weight: 500; }
.input {
width: 100%;
padding: 0.625rem 0.875rem;
border: 1px solid var(--border);
border-radius: var(--radius);
font-size: 1rem;
transition: border-color 0.15s, box-shadow 0.15s;
}
.input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(59,130,246,0.1);
}
.input.error { border-color: var(--error); }
.input::placeholder { color: var(--text-muted); }
.error-msg { color: var(--error); font-size: 0.8125rem; }
.success-msg { color: var(--success); font-size: 0.8125rem; }
/* States */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3rem 1.5rem;
text-align: center;
color: var(--text-muted);
}
.empty-state svg { width: 64px; height: 64px; margin-bottom: 1rem; opacity: 0.5; }
.skeleton {
background: linear-gradient(90deg, var(--border) 25%, #f1f5f9 50%, var(--border) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: var(--radius);
}
@keyframes shimmer { to { background-position: -200% 0; } }
.spinner {
width: 24px; height: 24px;
border: 2px solid var(--border);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Navigation */
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
background: var(--surface);
border-bottom: 1px solid var(--border);
}
.header-title { font-weight: 600; }
.tab-bar {
display: flex;
background: var(--surface);
border-top: 1px solid var(--border);
padding: 0.5rem;
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
padding: 0.5rem;
color: var(--text-muted);
text-decoration: none;
font-size: 0.75rem;
cursor: pointer;
border: none;
background: none;
}
.tab-item.active { color: var(--primary); }
.tab-item svg { width: 24px; height: 24px; }
/* Modal */
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
display: none;
align-items: center;
justify-content: center;
padding: 1rem;
z-index: 100;
}
.modal-overlay.active { display: flex; }
.modal {
background: var(--surface);
border-radius: var(--radius);
width: 100%;
max-width: 400px;
max-height: 90vh;
overflow-y: auto;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.modal-body { padding: 1rem; }
.modal-footer {
display: flex;
gap: 0.75rem;
padding: 1rem;
border-top: 1px solid var(--border);
}
/* List */
.list { display: flex; flex-direction: column; }
.list-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.875rem 0;
border-bottom: 1px solid var(--border);
cursor: pointer;
}
.list-item:last-child { border-bottom: none; }
.list-item:hover { background: var(--bg); margin: 0 -1rem; padding-left: 1rem; padding-right: 1rem; }
/* Badge */
.badge {
display: inline-flex;
align-items: center;
padding: 0.125rem 0.5rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 500;
}
.badge-primary { background: rgba(59,130,246,0.1); color: var(--primary); }
.badge-success { background: rgba(34,197,94,0.1); color: var(--success); }
.badge-warning { background: rgba(245,158,11,0.1); color: var(--warning); }
.badge-error { background: rgba(239,68,68,0.1); color: var(--error); }
/* Utility */
.mt-auto { margin-top: auto; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }
.p-0 { padding: 0; }
.hidden { display: none !important; }
</style>
</head>
<body>
<!-- ============================================
SCREEN: Welcome / Onboarding
============================================ -->
<section data-screen="welcome" class="active">
<div class="container" style="display: flex; flex-direction: column; min-height: 100vh; justify-content: center;">
<div class="text-center stack">
<h1>Welcome to APP_NAME</h1>
<p class="text-muted">Brief description of what this app does and why it's valuable.</p>
<div style="margin-top: 2rem;">
<button class="btn btn-primary btn-block" onclick="showScreen('login')">Get Started</button>
</div>
<p class="text-sm text-muted" style="margin-top: 1rem;">
Already have an account? <a href="#" onclick="showScreen('login'); return false;">Sign in</a>
</p>
</div>
</div>
</section>
<!-- ============================================
SCREEN: Login
============================================ -->
<section data-screen="login">
<div class="header">
<button class="btn btn-ghost btn-sm" onclick="showScreen('welcome')">← Back</button>
<span class="header-title">Sign In</span>
<div style="width: 60px;"></div>
</div>
<div class="container stack" style="padding-top: 2rem;">
<div class="input-group">
<label>Email</label>
<input type="email" class="input" placeholder="you@example.com" id="login-email">
</div>
<div class="input-group">
<label>Password</label>
<input type="password" class="input" placeholder="••••••••" id="login-password">
</div>
<button class="btn btn-primary btn-block" onclick="handleLogin()">Sign In</button>
<p class="text-center text-sm text-muted">
Don't have an account? <a href="#" onclick="showScreen('signup'); return false;">Sign up</a>
</p>
</div>
</section>
<!-- ============================================
SCREEN: Home (Main)
============================================ -->
<section data-screen="home">
<div class="header">
<span class="header-title">APP_NAME</span>
<button class="btn btn-ghost btn-sm" onclick="showScreen('settings')">⚙️</button>
</div>
<div class="container stack" style="padding-bottom: 5rem;">
<!-- Empty State Example -->
<div class="card empty-state" id="empty-state">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
<h3 class="mb-1">No items yet</h3>
<p class="text-sm">Create your first item to get started.</p>
<button class="btn btn-primary" style="margin-top: 1rem;" onclick="showModal('create-modal')">Create Item</button>
</div>
<!-- List Example (hidden by default) -->
<div class="card p-0 hidden" id="items-list">
<div class="list" style="padding: 0 1rem;">
<!-- Items populated by JS -->
</div>
</div>
</div>
<!-- Tab Navigation -->
<nav class="tab-bar">
<button class="tab-item active" onclick="showScreen('home')">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>
Home
</button>
<button class="tab-item" onclick="showScreen('search')">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
Search
</button>
<button class="tab-item" onclick="showScreen('profile')">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
Profile
</button>
</nav>
</section>
<!-- ============================================
SCREEN: Detail View
============================================ -->
<section data-screen="detail">
<div class="header">
<button class="btn btn-ghost btn-sm" onclick="showScreen('home')">← Back</button>
<span class="header-title">Item Details</span>
<button class="btn btn-ghost btn-sm">Edit</button>
</div>
<div class="container stack">
<div class="card">
<h2 id="detail-title">Item Title</h2>
<p class="text-muted text-sm" style="margin-top: 0.5rem;">Created Jan 1, 2024</p>
<p style="margin-top: 1rem;" id="detail-description">Item description goes here.</p>
</div>
<button class="btn btn-secondary btn-block" style="color: var(--error);">Delete Item</button>
</div>
</section>
<!-- ============================================
SCREEN: Settings
============================================ -->
<section data-screen="settings">
<div class="header">
<button class="btn btn-ghost btn-sm" onclick="showScreen('home')">← Back</button>
<span class="header-title">Settings</span>
<div style="width: 60px;"></div>
</div>
<div class="container stack">
<div class="card p-0">
<div class="list" style="padding: 0 1rem;">
<div class="list-item">
<span class="flex-1">Account</span>
<span class="text-muted">→</span>
</div>
<div class="list-item">
<span class="flex-1">Notifications</span>
<span class="text-muted">→</span>
</div>
<div class="list-item">
<span class="flex-1">Privacy</span>
<span class="text-muted">→</span>
</div>
<div class="list-item">
<span class="flex-1">Help & Support</span>
<span class="text-muted">→</span>
</div>
</div>
</div>
<button class="btn btn-secondary btn-block" onclick="handleLogout()">Sign Out</button>
</div>
</section>
<!-- ============================================
MODAL: Create Item
============================================ -->
<div class="modal-overlay" id="create-modal">
<div class="modal">
<div class="modal-header">
<h3>Create New Item</h3>
<button class="btn btn-ghost btn-sm" onclick="hideModal('create-modal')">✕</button>
</div>
<div class="modal-body stack">
<div class="input-group">
<label>Title</label>
<input type="text" class="input" placeholder="Enter title" id="new-item-title">
</div>
<div class="input-group">
<label>Description</label>
<textarea class="input" rows="3" placeholder="Enter description" id="new-item-desc"></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary flex-1" onclick="hideModal('create-modal')">Cancel</button>
<button class="btn btn-primary flex-1" onclick="createItem()">Create</button>
</div>
</div>
</div>
<script>
// ==========================================
// STATE MANAGEMENT
// ==========================================
const state = {
currentScreen: 'welcome',
user: null,
items: []
};
// ==========================================
// SCREEN NAVIGATION
// ==========================================
function showScreen(screenId) {
document.querySelectorAll('[data-screen]').forEach(s => s.classList.remove('active'));
document.querySelector(`[data-screen="${screenId}"]`).classList.add('active');
state.currentScreen = screenId;
// Update tab bar active state
document.querySelectorAll('.tab-item').forEach(t => t.classList.remove('active'));
const activeTab = document.querySelector(`.tab-item[onclick*="${screenId}"]`);
if (activeTab) activeTab.classList.add('active');
}
// ==========================================
// MODAL MANAGEMENT
// ==========================================
function showModal(modalId) {
document.getElementById(modalId).classList.add('active');
}
function hideModal(modalId) {
document.getElementById(modalId).classList.remove('active');
}
// ==========================================
// AUTH HANDLERS
// ==========================================
function handleLogin() {
const email = document.getElementById('login-email').value;
const password = document.getElementById('login-password').value;
// Simulate login
if (email && password) {
state.user = { email };
showScreen('home');
}
}
function handleLogout() {
state.user = null;
state.items = [];
showScreen('welcome');
}
// ==========================================
// ITEM HANDLERS
// ==========================================
function createItem() {
const title = document.getElementById('new-item-title').value;
const desc = document.getElementById('new-item-desc').value;
if (title) {
state.items.push({ id: Date.now(), title, description: desc });
renderItems();
hideModal('create-modal');
document.getElementById('new-item-title').value = '';
document.getElementById('new-item-desc').value = '';
}
}
function viewItem(id) {
const item = state.items.find(i => i.id === id);
if (item) {
document.getElementById('detail-title').textContent = item.title;
document.getElementById('detail-description').textContent = item.description || 'No description';
showScreen('detail');
}
}
function renderItems() {
const emptyState = document.getElementById('empty-state');
const itemsList = document.getElementById('items-list');
const listContainer = itemsList.querySelector('.list');
if (state.items.length === 0) {
emptyState.classList.remove('hidden');
itemsList.classList.add('hidden');
} else {
emptyState.classList.add('hidden');
itemsList.classList.remove('hidden');
listContainer.innerHTML = state.items.map(item => `
<div class="list-item" onclick="viewItem(${item.id})">
<div class="flex-1">
<div style="font-weight: 500;">${item.title}</div>
<div class="text-sm text-muted">${item.description || 'No description'}</div>
</div>
<span class="text-muted">→</span>
</div>
`).join('');
}
}
// Initialize
renderItems();
</script>
</body>
</html>
{
"schema_version": "2.0",
"meta": {
"generated_at": "2026-01-23T02:21:31.180Z",
"slug": "emz1998-ux-prototyping",
"source_url": "https://github.com/Emz1998/avaris-ai/tree/master/.claude/skills/ux-prototyping",
"source_ref": "master",
"model": "claude",
"analysis_version": "3.0.0",
"source_type": "community",
"content_hash": "56adbd03f538f830305c7adb2fb0a970b6c1ebdeca1d1d61648109e9d27f8786",
"tree_hash": "7692fa6864d8c912810e822ca51bec031612b7c330d154269c1c8d0af8f30077"
},
"skill": {
"name": "ux-prototyping",
"description": "Create interactive single-file HTML prototypes for UX validation. Use when the user asks to create a prototype, mockup, or interactive wireframe based on specs/architecture/ux.md or any UX specification. Triggers include requests like \"create a prototype\", \"build a prototype from the UX spec\", \"make an interactive mockup\", \"prototype the user flow\", or \"validate the UX\".",
"summary": "Create interactive single-file HTML prototypes for UX validation from UX specification documents",
"icon": "🎨",
"version": "1.0.0",
"author": "Emz1998",
"license": "MIT",
"tags": [
"prototyping",
"ux-design",
"wireframing",
"user-flows",
"interactive-mockups"
],
"supported_tools": [
"claude",
"codex",
"claude-code"
],
"risk_factors": [
"scripts",
"external_commands"
]
},
"security_audit": {
"risk_level": "low",
"is_blocked": false,
"safe_to_publish": true,
"summary": "Static scanner flagged 51 patterns but all evaluations confirm false positives. The scanner misidentified Date.now() timestamps as cryptographic algorithms, markdown backticks as shell commands, and standard DOM methods as reconnaissance. This is a legitimate UX prototyping skill that generates self-contained HTML mockups from UX specifications. No network calls, no filesystem access, no credential handling.",
"risk_factor_evidence": [],
"critical_findings": [],
"high_findings": [],
"medium_findings": [
{
"title": "False Positive: innerHTML Assignment",
"description": "Scanner flagged line 505 innerHTML assignment as XSS risk. This is a false positive because the prototype is self-contained with no external input vectors. The data displayed comes from local form input within the same prototype session.",
"locations": [
{
"file": "assets/prototype-template.html",
"line_start": 505,
"line_end": 513
}
],
"verdict": "FALSE_POSITIVE",
"confidence": 0.95,
"confidence_reasoning": "The innerHTML renders locally-generated item data from the same prototype. No external user input or network data sources exist."
},
{
"title": "False Positive: Markdown Backticks as Shell Commands",
"description": "Scanner flagged SKILL.md code block delimiters as Ruby/shell backtick execution. This is a documentation file containing markdown code blocks for example prototypes, not executable code.",
"locations": [
{
"file": "SKILL.md",
"line_start": 12,
"line_end": 121
}
],
"verdict": "FALSE_POSITIVE",
"confidence": 0.98,
"confidence_reasoning": "SKILL.md is a markdown documentation file. The backticks are code block delimiters for displaying example HTML/JavaScript snippets."
}
],
"low_findings": [
{
"title": "False Positive: Hardcoded URLs",
"description": "Scanner flagged SVG namespace URLs at lines 301, 320, 324, 328 as hardcoded URLs. These are standard SVG xmlns attributes required for inline SVG rendering in HTML.",
"locations": [
{
"file": "assets/prototype-template.html",
"line_start": 301,
"line_end": 301
},
{
"file": "assets/prototype-template.html",
"line_start": 320,
"line_end": 320
},
{
"file": "assets/prototype-template.html",
"line_start": 324,
"line_end": 324
},
{
"file": "assets/prototype-template.html",
"line_start": 328,
"line_end": 328
}
],
"verdict": "FALSE_POSITIVE",
"confidence": 0.95,
"confidence_reasoning": "These are standard SVG namespace URLs required for rendering inline SVG icons. No external network requests are made."
},
{
"title": "False Positive: Date.now() as Cryptographic Algorithm",
"description": "Scanner misidentified Date.now() and template literal strings as weak cryptographic algorithms. Date.now() is a standard timestamp function used for generating unique item IDs.",
"locations": [
{
"file": "assets/prototype-template.html",
"line_start": 254,
"line_end": 254
},
{
"file": "assets/prototype-template.html",
"line_start": 347,
"line_end": 347
},
{
"file": "assets/prototype-template.html",
"line_start": 402,
"line_end": 403
},
{
"file": "assets/prototype-template.html",
"line_start": 473,
"line_end": 476
},
{
"file": "assets/prototype-template.html",
"line_start": 480,
"line_end": 480
},
{
"file": "assets/prototype-template.html",
"line_start": 488,
"line_end": 488
},
{
"file": "assets/prototype-template.html",
"line_start": 509,
"line_end": 509
},
{
"file": "SKILL.md",
"line_start": 3,
"line_end": 3
},
{
"file": "SKILL.md",
"line_start": 121,
"line_end": 121
}
],
"verdict": "FALSE_POSITIVE",
"confidence": 0.98,
"confidence_reasoning": "Date.now() is a JavaScript timestamp function, not cryptography. Template literals like 'Brief description' are plain text. Scanner pattern matching failed to distinguish between actual crypto code and unrelated code."
},
{
"title": "False Positive: Array.join() as Obfuscation",
"description": "Scanner flagged .join('') as obfuscation pattern. This is standard JavaScript array method usage for converting item arrays to HTML strings.",
"locations": [
{
"file": "assets/prototype-template.html",
"line_start": 513,
"line_end": 513
}
],
"verdict": "FALSE_POSITIVE",
"confidence": 0.95,
"confidence_reasoning": "Array.join('') is a common JavaScript pattern for template string generation. No obfuscation or malicious intent present."
},
{
"title": "False Positive: DOM Methods as System Reconnaissance",
"description": "Scanner flagged document.querySelectorAll and similar DOM methods as system reconnaissance. These are standard JavaScript DOM manipulation functions.",
"locations": [
{
"file": "assets/prototype-template.html",
"line_start": 81,
"line_end": 81
},
{
"file": "assets/prototype-template.html",
"line_start": 93,
"line_end": 93
},
{
"file": "assets/prototype-template.html",
"line_start": 131,
"line_end": 131
},
{
"file": "assets/prototype-template.html",
"line_start": 145,
"line_end": 145
},
{
"file": "assets/prototype-template.html",
"line_start": 152,
"line_end": 152
},
{
"file": "assets/prototype-template.html",
"line_start": 201,
"line_end": 201
},
{
"file": "assets/prototype-template.html",
"line_start": 208,
"line_end": 208
},
{
"file": "assets/prototype-template.html",
"line_start": 218,
"line_end": 218
},
{
"file": "assets/prototype-template.html",
"line_start": 485,
"line_end": 485
}
],
"verdict": "FALSE_POSITIVE",
"confidence": 0.95,
"confidence_reasoning": "querySelector, querySelectorAll, getElementById are standard DOM APIs used for UI rendering in client-side JavaScript applications."
}
],
"dangerous_patterns": [],
"files_scanned": 2,
"total_lines": 644,
"audit_model": "claude",
"audited_at": "2026-01-23T02:21:31.180Z",
"risk_factors": [
"scripts",
"external_commands"
]
},
"content": {
"user_title": "Create Interactive UX Prototypes",
"value_statement": "Creating interactive prototypes manually is time-consuming and requires front-end skills. This skill converts UX specifications into single-file HTML prototypes that run in any browser, enabling rapid user flow validation without coding.",
"seo_keywords": [
"Claude",
"Codex",
"Claude Code",
"UX prototyping",
"interactive prototypes",
"user flow validation",
"wireframing tool",
"prototype generator",
"mockup creator",
"UX validation"
],
"actual_capabilities": [
"Generate single-file HTML prototypes from UX specification documents",
"Create complete user flow simulations with navigation and state transitions",
"Build essential UI components including forms, modals, lists, and navigation",
"Implement multiple screen states: empty, loading, error, and success scenarios",
"Support responsive layouts optimized for mobile viewport testing"
],
"limitations": [
"Requires existing UX specification document to generate prototypes",
"Prototypes are for validation purposes only, not production interfaces",
"No advanced animations or pixel-perfect styling included",
"Limited to single-file HTML output without external dependencies"
],
"use_cases": [
{
"title": "Rapid Prototype for Stakeholder Review",
"description": "Generate an interactive prototype from UX specs to demonstrate user flows to stakeholders before development begins. Validate navigation logic and screen sequencing early.",
"target_user": "Product designers"
},
{
"title": "User Testing Mockups",
"description": "Create lightweight prototypes for usability testing sessions. The single HTML file works offline and runs in any browser, making it ideal for remote or in-person user research.",
"target_user": "UX researchers"
},
{
"title": "Development Handoff Reference",
"description": "Generate interactive prototypes that developers can reference during implementation. The clear screen patterns and state management serve as implementation blueprints.",
"target_user": "Frontend developers"
}
],
"prompt_templates": [
{
"title": "Basic Prototype Request",
"prompt": "Create an interactive prototype for a [APP_TYPE] app based on the UX specification at [PATH_TO_UX_SPEC]. Generate a single HTML file with all screens, navigation, and user flows from the spec.",
"scenario": "When a user provides a UX spec and wants a working prototype"
},
{
"title": "Specific User Flow",
"prompt": "Build a prototype focusing on the [FLOW_NAME] user flow from the UX spec. Include all screens, states, and interactions needed to complete this flow from start to finish.",
"scenario": "When validation is needed for a specific user journey"
},
{
"title": "Mobile App Mockup",
"prompt": "Create a mobile-first prototype for a [APP_NAME] app based on specs/architecture/ux.md. Include onboarding, main screens, and navigation patterns appropriate for mobile use.",
"scenario": "When building mobile app prototypes with tab navigation"
},
{
"title": "Complete App Prototype",
"prompt": "Generate a comprehensive prototype for the complete app experience. Include all screens from the UX spec: welcome/onboarding flows, authentication screens, main app views with empty and populated states, settings, and all key interactions.",
"scenario": "When a full app prototype is needed for comprehensive validation"
}
],
"output_examples": [
{
"input": "Create a prototype for a task management app based on the UX spec at specs/architecture/ux.md",
"output": [
"A single HTML file saved to /mnt/user-data/outputs/prototype.html",
"Interactive welcome screen with Get Started button",
"Login screen with email and password fields",
"Home screen showing empty state and sample task list",
"Tab navigation between Home, Search, and Profile screens",
"Create item modal with title and description fields",
"Detail view screen for individual items",
"Settings screen with account, notifications, and privacy options"
]
},
{
"input": "Build a prototype for the onboarding flow",
"output": [
"Single HTML file with welcome screen",
"Sign up form with validation",
"Account creation flow",
"Onboarding tutorial screens",
"Transition to main app screen on completion"
]
}
],
"best_practices": [
"Keep prototypes self-contained with inline CSS and JavaScript. Avoid external CDN links for reliable offline testing.",
"Use consistent screen management patterns with data-screen attributes. Hide inactive screens and show only the active one.",
"Document all screen states including empty, loading, error, and success states. These are essential for complete user flow validation."
],
"anti_patterns": [
"Skipping empty, error, or loading states in prototypes. Users need to see how the app handles all scenarios, not just the happy path.",
"Using the prototype as a production interface. Prototypes are for validation and should not replace proper implementation.",
"Creating prototypes without testing them in a browser. Always verify navigation works and all flows are completable."
],
"faq": [
{
"question": "What is this skill for?",
"answer": "This skill converts UX specification documents into interactive single-file HTML prototypes that can be opened in any browser for user flow validation."
},
{
"question": "Do I need to know HTML to use this skill?",
"answer": "No. You provide the UX specification and the skill generates a complete working prototype with all screens and interactions."
},
{
"question": "What format should my UX spec be in?",
"answer": "The skill reads from specs/architecture/ux.md by default, or any user-specified path. The spec should describe screens, user flows, states, and interactions."
},
{
"question": "Can I use the generated prototype in production?",
"answer": "No. Prototypes are for validation and testing only. They lack proper accessibility, performance optimization, and security measures required for production."
},
{
"question": "What does the generated prototype include?",
"answer": "Single HTML file with inline CSS and JavaScript, working navigation between screens, essential UI components, empty/loading/error states, and responsive layout."
},
{
"question": "How do I test the prototype?",
"answer": "Open the generated HTML file in any web browser. The prototype works offline and includes all necessary code for testing user flows."
}
]
},
"file_structure": [
{
"name": "assets",
"type": "dir",
"path": "assets",
"children": [
{
"name": "prototype-template.html",
"type": "file",
"path": "assets/prototype-template.html",
"lines": 522
}
]
},
{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"lines": 122
}
]
}
Related skills
FAQ
What does ux-prototyping output?
A single-file HTML prototype containing all screens, states, and inline CSS/JS saved to prototype.html.
Does it produce production-ready UI?
No, it prioritizes UX fidelity over visual polish and defers pixel-perfect styling, animations, and brand colors.