katsuragi
v0.2.0
Published
Text-based UI wireframe generator
Downloads
19
Readme
Katsuragi
Half the tokens. Twice the clarity.
Turn UI ideas into wireframes with a text format AI actually understands.
Who is this for?
- Developers discussing UI with non-technical stakeholders
- Engineers using AI coding assistants (Claude Code, Cursor, Aider)
- Teams who want git-diffable UI specs
Why .kui?
---
config:
themeVariables:
xyChart:
plotColorPalette: "#9CA3AF, #3B82F6, #F87171"
---
xychart-beta
title "Tokens per wireframe (login example)"
x-axis ["Natural Lang", "ASCII", ".kui", "HTML"]
y-axis "Tokens" 0 --> 400
bar [102, 84, 0, 0]
bar [0, 0, 120, 0]
bar [0, 0, 0, 330].kui hits the sweet spot between efficiency and reliability:
| Format | Tokens | Precise | Stable | |--------|--------|---------|--------| | Natural Language | 102 | ❌ | ❌ | | ASCII Art | 84 | ⚠️ | ❌ | | .kui | 120 | ✓ | ✓ | | HTML | 330 | ✓ | ✓ |
50% fewer tokens than HTML, with the same precision.
→ Full comparison with 3 patterns
How it works
Write a .kui file:
ratio: 16:9
grid: 4x3
colors: { primary: "#3B82F6" }
A1..D1: { type: txt, value: "Login", align: center }
A2..D2: { type: input, label: "Email" }
A3..C3: { type: input, label: "Password" }
D3: { type: btn, value: "Login", bg: $primary }Run one command:
npx ktr login.kui -o login.pngGet this:

If this tool saves you time:
Star this repo to help others find it!
Note from a developer in Japan: I tried to set up GitHub Sponsors and Buy Me a Coffee, but Stripe doesn't support my bank. Couldn't configure the payout account. I'm gonna cry.
Quick Start
Install
# One-time use (no install)
npx ktr input.kui -o output.png
# Global install
npm install -g katsuragiTip:
ktris a shorter alias forkatsuragi- use whichever you prefer.
Try It
# Create a sample file
cat > hello.kui << 'EOF'
ratio: 16:9
grid: 2x2
A1: { type: txt, value: "Hello Katsuragi!", align: center }
A2..B2: { type: btn, value: "Get Started" }
EOF
# Generate image
npx ktr hello.kui -o hello.pngUsage
# Output SVG to stdout
ktr input.kui
# Save to file (format auto-detected from extension)
ktr input.kui -o output.svg
ktr input.kui -o output.png
# Explicit format
ktr input.kui -f png -o output.png
# Batch conversion
ktr *.kui -d ./output -f png
# Read from stdin
cat input.kui | ktr -o output.pngCLI Options:
| Option | Description |
|--------|-------------|
| -o, --output <file> | Output file (default: stdout for SVG) |
| -d, --output-dir <dir> | Output directory for batch conversion |
| -f, --format <format> | Output format: svg, png, or html (default: svg) |
| -V, --version | Show version number |
| -h, --help | Show help |
Watch Command
Live preview in your browser with auto-reload on save:
# Start watching a .kui file
ktr watch input.kui
# Specify port
ktr watch input.kui -p 8080
# Disable auto browser open
ktr watch input.kui --no-openWatch Options:
| Option | Description |
|--------|-------------|
| -p, --port <number> | Server port (default: 3456) |
| --no-open | Do not open browser automatically |
Fetch Command
Convert webpages to .kui wireframes:
# Basic usage
ktr fetch https://example.com -o wireframe.kui
# Specify viewport (desktop, mobile, tablet)
ktr fetch https://example.com -o mobile.kui --viewport mobile
# Override grid and ratio
ktr fetch https://example.com -o custom.kui --grid 6x4 --ratio 4:3
# Control extraction depth and element count
ktr fetch https://example.com -o simple.kui --max-elements 30 --max-depth 3Fetch Options:
| Option | Description |
|--------|-------------|
| -o, --output <file> | Output .kui file path (required) |
| --viewport <type> | Target viewport: desktop, mobile, tablet (default: desktop) |
| --grid <grid> | Override grid size (e.g., 4x3, max 26x26) |
| --ratio <ratio> | Override aspect ratio (e.g., 16:9) |
| --max-elements <n> | Maximum elements to extract (default: 50) |
| --max-depth <n> | Maximum DOM nesting depth (default: 4) |
How it works:
- Fetches HTML from the URL (no JavaScript execution)
- Extracts visual elements with priority-based filtering (header/nav/main prioritized)
- Extracts
<meta name="theme-color">as the primary color - Extracts inline style colors (
background-color,border-color) - Maps real text content (headings, button labels, placeholders) into components
- Estimates layout positions based on document flow
- Uses intelligent grid placement with overlap resolution
Limitations:
- Static HTML only (SPAs with client-side rendering won't work properly)
- No CSS analysis - layout is estimated from document structure
- Text content is truncated for wireframe display (max 20-30 characters)
- Maximum grid size: 26×26
Why Text-Based?
Katsuragi uses a text format because AI can read and write it.
| Traditional Tools | Katsuragi | |-------------------|-----------| | Design in Figma, export, share screenshot | Describe in text, generate image | | AI can't edit your design file | AI can write and modify .kui files | | "Make the button bigger" requires manual work | AI understands and updates the code |
Why Plain Text Works with AI
- Easy to copy/paste - No binary format, no special tools needed
- Fits in context windows - .kui files are small, AI can hold entire layouts in memory
- Diff-friendly - Changes are trackable in git, easy to review
- No vendor lock-in - Works with any LLM (ChatGPT, Claude, Gemini, local models)
Workflow with AI
- Add .kui spec to your project (in
AGENTS.md, system prompt, or project docs) - Ask AI: "Create a login wireframe in .kui format"
- AI generates the .kui file
- Run
ktr login.kui -o login.png - Share the image, discuss, iterate
- AI updates the .kui based on feedback
Works with LLM-powered CLI Tools
- Claude Code - Add spec to CLAUDE.md
- Cursor - Add to project rules
- Aider - Include in context
- Any LLM CLI - Paste spec in system prompt or AGENTS.md
Example Prompt
Here's the .kui format specification:
[paste the syntax section below]
Create a mobile app wireframe for a task management app.
Use 2x5 grid (ratio 9:16).
Include: header with title, task list area, and floating action button.Once the AI knows the format, it can generate and modify .kui code reliably.
.kui File Format
ratio: 16:9
grid: 4x3
colors: { primary: "#3B82F6" }
// Header
A1..D1: { type: txt, value: "Login", align: center }
// Form
A2..D2: { type: input, label: "Email" }
A3..C3: { type: input, label: "Password" }
D3: { type: btn, value: "Submit", bg: $primary }Grid System
ratio- Aspect ratio of the canvas (e.g.,16:9,4:3,1:1,9:16)grid- Grid divisions ascolumns x rows(e.g.,4x3creates columns A-D and rows 1-3)- Cell references use Excel-style notation:
A1,B2,C3 - Range notation:
A1..B3(top-left to bottom-right)
Unequal Grid Divisions
Use col-widths and row-heights to set ratio-based sizes:
ratio: 16:9
grid: 3x3
col-widths: [1, 3, 1]
row-heights: [1, 4, 1]
gap: 8
// Sidebar layout
A1..C1: { type: txt, value: "Header", align: center, bg: "#3B82F6" }
A2: { type: txt, value: "Menu", bg: "#f0f0f0" }
B2: { type: box, bg: "#ffffff", border: "#ccc" }
C2: { type: txt, value: "Info", bg: "#f0f0f0" }
A3..C3: { type: txt, value: "Footer", align: center, bg: "#e0e0e0" }Values are ratios, not pixels. [1, 3, 1] means the middle column is 3x wider than the sides. Omit for equal divisions (backward compatible).
Gap & Padding
ratio: 16:9
grid: 3x2
gap: 8
padding: 24
A1: { type: box }
B1: { type: box }
C1: { type: box }
A2..C2: { type: txt, value: "Content area", padding: 16 }gap- Spacing between cells (in pixels, default:0)padding- Canvas margin (in pixels, default:0)- Per-cell
padding- Override content padding for individual cells
Comments
Use // for comments:
// This is a comment
A1: { type: txt, value: "Hello" } // End-of-line commentComponents
| Type | Description | Properties | Defaults |
|------|-------------|------------|----------|
| txt | Text label | value, align, bg, border, padding | align: left |
| box | Empty box/container | bg, border, padding | bg: #e0e0e0 |
| btn | Button | value, bg, border, padding | bg: #e0e0e0 |
| input | Input field | label, bg, border, padding | bg: white, border: black |
| img | Image placeholder | src, alt, bg, border, padding | bg: #f0f0f0, border: #ccc |
Colors
Define a color theme and use $name references:
colors: { primary: "#3B82F6", danger: "#EF4444", accent: "orange" }
A1: { type: btn, value: "Submit", bg: $primary }
A2: { type: btn, value: "Delete", bg: $danger, border: $accent }
B1: { type: box, bg: "#f0f0f0", border: "#ccc" }
B2: { type: box, bg: lightblue }| Property | Description | Default |
|----------|-------------|---------|
| bg | Background color | Component-specific |
| border | Border color (2px width) | none |
Color formats:
- HEX:
#RGBor#RRGGBB(e.g.,#f00,#3B82F6) - CSS color names:
red,blue,lightblue,orange, etc. - Theme reference:
$name(requirescolors:definition)
Themes
Built-in visual presets:
theme: clean| Theme | Stroke | Radius | Font Size | Default BG |
|-------|--------|--------|-----------|------------|
| default | 2px | 8px | 24px | #e0e0e0 |
| clean | 1px | 4px | 20px | #f0f0f0 |
| bold | 3px | 12px | 28px | #d0d0d0 |
Per-component bg and border always override the theme.
Alignment
align:left(default),center,right
Multi-line Text
Use \n for line breaks:
A1: { type: txt, value: "Line 1\nLine 2\nLine 3" }Or use backticks for multi-line strings:
A1: { type: txt, value: `
Welcome to
Katsuragi
` }Note: Automatic text wrapping is not supported. For long text, manually insert
\nat desired break points.
Output Size
The longest edge is fixed at 1280px. The shorter edge is calculated from the ratio:
16:9→ 1280 × 7204:3→ 1280 × 9601:1→ 1280 × 12809:16→ 720 × 1280 (mobile)
More Examples


Roadmap
- [x] Core components (txt, box, btn, input, img)
- [x] SVG/PNG export
- [x] Web page to .kui conversion (
ktr fetch) - [x] Live preview with watch mode (
ktr watch) - [x] Unequal grid divisions (
col-widths,row-heights) - [x] Built-in themes (default, clean, bold)
- [x] HTML export with CSS Grid layout
- [ ] Markdown embedding (
```kuicode blocks) - [ ] VS Code extension
- [ ] Web-based editor
License
- Open Source: AGPL-3.0 (free if you open-source your code)
- Commercial Products: Free to use for building commercial products
- Commercial License Required: Only when embedding Katsuragi into SaaS platforms or distributing as closed-source
Example: Using Katsuragi to create wireframes for your commercial app? Totally free. Integrating Katsuragi into your design tool SaaS? Commercial license required.
For commercial licensing, contact En-Links LLC.
Third-Party Licenses
This software uses the following open-source libraries:
| Library | License | Description | |---------|---------|-------------| | sharp | Apache-2.0 | High-performance image processing | | libvips | LGPL-3.0-or-later | Image processing library (sharp dependency) | | commander | MIT | CLI argument parsing | | node-html-parser | MIT | HTML parsing for fetch command | | ws | MIT | WebSocket server for watch mode | | open | MIT | Open browser for watch mode |
Acknowledgments
Katsuragi is built on the shoulders of giants:
- libvips by John Googley-Fletcher and contributors - The fast image processing engine that powers our PNG generation
- sharp by Lovell Fuller - Making libvips accessible from Node.js with an elegant API
- commander.js by TJ Holowaychuk - The standard for building Node.js CLI tools
Copyright © 2025 En-Links LLC

