
Visual Design
- 117 installs
- 101 repo stars
- Updated August 4, 2026
- factory-ai/factory-plugins
Helps with design & ui/ux tasks.
About
visual-design is a Claude Code skill for design & ui/ux. It helps solo builders move faster with AI-assisted development.
- visual-design
- Design & UI/UX
- AI-coding skill
Visual Design by the numbers
- 117 all-time installs (skills.sh)
- Ranked #1,073 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/factory-ai/factory-plugins --skill visual-designAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 117 |
|---|---|
| repo stars | ★ 101 |
| Last updated | August 4, 2026 |
| Repository | factory-ai/factory-plugins ↗ |
What it does
Helps with design & ui/ux tasks.
Files
Visual design
Image generation and presentations.
Image generation
Create and edit images from the command line using nanobanana CLI.
npm install -g @factory/nanobanana
export GEMINI_API_KEY="your-key"
nanobanana generate "company logo" --count=4 --styles=modern,minimal
nanobanana edit photo.png "remove background"
nanobanana icon "settings gear" --style=flat
nanobanana diagram "auth flow" --type=flowchartHandles: logos, icons, diagrams, patterns, photo restoration, UI assets, visual sequences.
See: image-generation.md
Presentations
Create slides using Slidev, a markdown-based presentation tool.
npm init slidev@latest
slidev # dev server
slidev export --format pptx # export to PowerPoint
slidev build # build as hostable SPAWrite slides in markdown, get code highlighting, animations, diagrams, and Vue components.
See: presentations.md and reference-slide-example.md
Image generation
Generate and edit images from the command line using nanobanana, a CLI wrapper around Gemini's image models.
Setup
Install via npm:
npm install -g @factory/nanobananaOr download a standalone binary from https://github.com/Factory-AI/nanobanana-cli/releases
Set your API key:
export GEMINI_API_KEY="your-api-key"Get a key at https://aistudio.google.com/apikey
Commands
generate
Create images from text:
nanobanana generate "sunset over mountains"Generate multiple variations:
nanobanana generate "company logo" --count=4Apply styles:
nanobanana generate "cat portrait" --styles=watercolor,sketch,pixel-artOpen images after generation:
nanobanana generate "forest path" --previewedit
Modify an existing image:
nanobanana edit photo.png "add sunglasses to the person"
nanobanana edit landscape.jpg "change the sky to sunset"
nanobanana edit product.png "remove the background"restore
Fix old or damaged photos:
nanobanana restore old_photo.jpg
nanobanana restore damaged.png "remove scratches, enhance colors"icon
Generate app icons:
nanobanana icon "settings gear" --style=minimal
nanobanana icon "chat bubble" --type=favicon --sizes=16,32,64
nanobanana icon "rocket" --style=flat --background=transparentOptions: --type (app-icon, favicon, ui-element), --style (flat, minimal, modern, skeuomorphic), --sizes, --background, --corners
pattern
Create seamless patterns and textures:
nanobanana pattern "hexagons" --style=geometric --colors=duotone
nanobanana pattern "marble texture" --type=texture
nanobanana pattern "subtle gradient" --type=wallpaper --density=sparseOptions: --type (seamless, texture, wallpaper), --style (geometric, organic, abstract, floral, tech), --density, --colors
diagram
Generate technical diagrams:
nanobanana diagram "user authentication flow" --type=flowchart
nanobanana diagram "microservices architecture" --type=architecture
nanobanana diagram "database schema" --type=databaseOptions: --type (flowchart, architecture, network, database, wireframe, mindmap, sequence), --style, --layout, --complexity
story
Create sequential images for tutorials or narratives:
nanobanana story "seed growing into tree" --steps=5 --type=process
nanobanana story "making coffee" --type=tutorial --steps=6
nanobanana story "day to night transition" --type=timeline --steps=4Options: --steps (2-8), --type (story, process, tutorial, timeline), --style, --transition
tips
Get prompting help:
nanobanana tips # general tips
nanobanana tips generate # tips for generate command
nanobanana tips diagram # tips for diagram commandOutput
All images save to ./nanobanana-output/ in the current directory. Filenames are based on the prompt.
Prompting
The difference between a useless image and a useful one is usually the prompt.
Be specific. "Create a logo" gives you something generic. "Minimalist logo for a fintech company, geometric shapes, blue and white, suitable for favicon" gets you something you can actually use.
Include context. What's the image for? Who's the audience? Are there brand colors to match? Technical requirements like transparency or specific dimensions?
Reference styles. "In the style of Material Design" or "Similar to iOS app icons" or "Inspired by mid-century modern illustration" helps the model understand what you're after.
Generate variations. Run with --count=4 and pick the best one, then iterate. First attempts rarely nail it.
When to use what
generate - Most flexible. Use when other commands don't fit or when you want full control over the prompt.
edit - When you have an image and want to change specific parts without regenerating the whole thing. Good for adding/removing objects, changing colors, swapping backgrounds.
restore - Old family photos, damaged images, low-quality scans. Knows to preserve the original feel while fixing problems.
icon - App icons, favicons, UI elements. Adds the right styling and sizing automatically.
pattern - Backgrounds, textures, materials. Makes them tileable by default.
diagram - Technical illustrations. Handles the layout and labeling conventions for different diagram types.
story - Multi-step visuals. Maintains consistency across frames.
Limitations
Generated images have an invisible SynthID watermark for provenance tracking.
Safety filters block some content.
Complex scenes with many specific elements may need multiple attempts.
The model interprets prompts. If the result isn't what you wanted, try rephrasing rather than adding more words.
Presentations
Create slide decks using Slidev, a markdown-based presentation tool for developers. Write slides in markdown, get beautiful results with code highlighting, animations, and Vue components.
For a complete example showing all features, see reference-slide-example.md.
Setup
npm init slidev@latestOr add to an existing project:
npm install @slidev/cli @slidev/theme-defaultRun the dev server:
npx slidevBasic structure
Slides are written in a single slides.md file. Separate slides with ---:
---
theme: seriph
background: https://cover.sli.dev
class: text-center
---
# My Presentation
Subtitle goes here
---
# Second Slide
Content for the second slideFrontmatter
Each slide can have frontmatter for configuration:
---
layout: two-cols
transition: slide-left
class: px-20
---Global frontmatter goes at the top of the file and applies to all slides.
Layouts
Slidev has built-in layouts:
default- basic slidecenter- centered contenttwo-cols- two column layout (use::right::to separate)image-right/image-left- image on one sidecover- title slidesection- section dividerquote- for quotationsfact- highlight a key fact
Example two-column layout:
---
layout: two-cols
---
# Left Column
Content here
::right::
# Right Column
More contentCode blocks
Code highlighting works out of the box with Shiki:
```md `ts {2|3-4|all} const greeting = "Hello"; const name = "World"; console.log(${greeting}, ${name}!`);
The {2|3-4|all} syntax creates click-through highlighting:
- First click highlights line 2
- Second click highlights lines 3-4
- Third click shows all
Magic Move
Animate between code states:
````md ```md magic-move
// Step 1
const count = ref(0);// Step 2
const count = ref(0);
const doubled = computed(() => count.value * 2);``` ````
`````
Monaco Editor
Make code blocks editable:
```md ``ts {monaco} const x = 1 + 1
Or runnable:
```md ``ts {monaco-run} console.log("This runs in the browser!");
Animations
Click animations
Use v-click to reveal elements on click:
<div v-click>This appears on first click</div>
<div v-click>This appears on second click</div>Or with numbered order:
<div v-click="3">This appears third</div>
<div v-click="1">This appears first</div>
<div v-click="2">This appears second</div>Marks and highlights
<span v-mark.red="2">Highlighted on click 2</span>
<span v-mark.circle.orange>Circled</span>
<span v-mark.underline.blue>Underlined</span>Motion
Use v-motion for entrance animations:
<div v-motion :initial="{ x: -80, opacity: 0 }" :enter="{ x: 0, opacity: 1 }">
Slides in from left
</div>Diagrams
Mermaid diagrams work directly in markdown:
````md
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Do something]
B -->|No| D[Do something else]````
PlantUML also supported:
````md
@startuml
Alice -> Bob: Hello
Bob -> Alice: Hi!
@enduml````
LaTeX
Math is supported via KaTeX:
Inline: $E = mc^2$
Block:
$$
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
$$Themes
Change theme in frontmatter:
---
theme: seriph
---Popular themes: default, seriph, apple-basic, dracula, shibainu
Browse themes: https://sli.dev/resources/theme-gallery
CLI Reference
Development
# Start dev server (default: slides.md on port 3030)
slidev
# Custom entry file
slidev my-slides.md
# Custom port and auto-open browser
slidev --port 8080 --open
# Enable remote access (for presenting from another device)
slidev --remote
# Remote with password protection
slidev --remote mypasswordBuilding
# Build as hostable SPA
slidev build
# Custom output directory
slidev build --out ./public
# Include PDF download button in SPA
slidev build --download
# Exclude speaker notes
slidev build --without-notesExporting
# Export to PDF (default)
slidev export
# Export to PowerPoint
slidev export --format pptx
# Export to PNG (one image per slide)
slidev export --format png
# Export to markdown
slidev export --format md
# Export specific slides
slidev export --range "1,4-5,6"
# Export with click animations (one page per click)
slidev export --with-clicks
# Export dark theme version
slidev export --dark
# Custom output filename
slidev export --output my-presentationOther commands
# Format markdown file
slidev format
# Eject theme to local files for customization
slidev theme ejectSpeaker notes
Add notes with HTML comments at the end of a slide:
---
# My Slide
Content here
<!--
These are speaker notes.
Only visible in presenter mode.
Press 'p' to toggle presenter view.
-->Custom components
Create Vue components in components/ folder and use them directly:
<MyCustomChart :data="chartData" />Generating images for slides
Use nanobanana to generate custom images:
# Generate a diagram
nanobanana diagram "user authentication flow" --type=flowchart
# Generate an icon
nanobanana icon "rocket launch" --style=minimal
# Generate a background
nanobanana pattern "subtle gradient mesh" --type=wallpaperThen reference in your slides:
---
background: ./nanobanana-output/subtle_gradient_mesh.png
---Example slide deck
````md --- theme: seriph background: https://cover.sli.dev class: text-center transition: slide-left ---
Project Update
Q1 2026 Review
---
layout: two-cols
What we shipped
- Feature A
- Feature B
- Feature C
::right::
Metrics
- 50% faster
- 2x more users
- 99.9% uptime
---
Architecture
graph LR
Client --> API
API --> DB
API --> Cache````
---
layout: center class: text-center
---
Questions?
## Tips
- Keep slides simple. One idea per slide.
- Use code highlighting to walk through complex code.
- Leverage diagrams instead of bullet points when showing processes.
- Generate custom images rather than using stock photos.
- Practice with presenter mode (`p` key) to see notes and upcoming slides.
- Export to PDF for sharing, keep the source for presenting live.
## Documentation
Full Slidev docs: https://sli.dev/llms.txt
Key references:
- [Syntax Guide](https://sli.dev/guide/syntax) - Markdown extensions, frontmatter, slots
- [Animations](https://sli.dev/guide/animations) - Click animations, motion, transitions
- [Layouts](https://sli.dev/builtin/layouts) - All built-in layouts
- [Components](https://sli.dev/builtin/components) - Built-in Vue components
- [Themes](https://sli.dev/resources/theme-gallery) - Theme gallery
- [CLI Reference](https://sli.dev/builtin/cli) - All CLI commands and options
Features worth exploring:
- [Shiki Magic Move](https://sli.dev/features/shiki-magic-move) - Animate code changes
- [Monaco Editor](https://sli.dev/features/monaco-editor) - Live code editing in slides
- [Drawing](https://sli.dev/features/drawing) - Annotate slides during presentation
- [Recording](https://sli.dev/features/recording) - Record presentations with camera
- [Remote Access](https://sli.dev/features/remote-access) - Control from another deviceWelcome to Slidev
Presentation slides for developers
<div @click="$slidev.nav.next" class="mt-12 py-1" hover:bg="white op-10"> Press Space for next page <carbon:arrow-right /> </div>
<div class="abs-br m-6 text-xl"> <button @click="$slidev.nav.openInEditor" title="Open in Editor" class="slidev-icon-btn"> <carbon:edit /> </button> <a href="https://github.com/slidevjs/slidev" target="_blank" class="slidev-icon-btn"> <carbon:logo-github /> </a> </div>
<!-- The last comment block of each slide will be treated as slide notes. It will be visible and editable in Presenter Mode along with the slide. Read more in the docs -->
--- transition: fade-out ---
What is Slidev?
Slidev is a slides maker and presenter designed for developers, consist of the following features
- 📝 Text-based - focus on the content with Markdown, and then style them later
- 🎨 Themable - themes can be shared and re-used as npm packages
- 🧑💻 Developer Friendly - code highlighting, live coding with autocompletion
- 🤹 Interactive - embed Vue components to enhance your expressions
- 🎥 Recording - built-in recording and camera view
- 📤 Portable - export to PDF, PPTX, PNGs, or even a hostable SPA
- 🛠 Hackable - virtually anything that's possible on a webpage is possible in Slidev
<br> <br>
Read more about Why Slidev?
<!-- You can have style tag in markdown to override the style for the current page. Learn more: https://sli.dev/features/slide-scope-style -->
<style> h1 { background-color: #2B90B6; background-image: linear-gradient(45deg, #4EC5D4 10%, #146b8c 20%); background-size: 100%; -webkit-background-clip: text; -moz-background-clip: text; -webkit-text-fill-color: transparent; -moz-text-fill-color: transparent; } </style>
<!-- Here is another comment. -->
--- transition: slide-up level: 2 ---
Navigation
Hover on the bottom-left corner to see the navigation's controls panel, learn more
Keyboard Shortcuts
| <kbd>right</kbd> / <kbd>space</kbd> | next animation or slide |
| <kbd>left</kbd> / <kbd>shift</kbd><kbd>space</kbd> | previous animation or slide |
| <kbd>up</kbd> | previous slide |
| <kbd>down</kbd> | next slide |
<!-- https://sli.dev/guide/animations.html#click-animation --> <img v-click class="absolute -bottom-9 -left-7 w-80 opacity-50" src="https://sli.dev/assets/arrow-bottom-left.svg" alt="" /> <p v-after class="absolute bottom-23 left-45 opacity-30 transform -rotate-10">Here!</p>
--- layout: two-cols layoutClass: gap-16 ---
Table of contents
You can use the Toc component to generate a table of contents for your slides:
<Toc minDepth="1" maxDepth="1" />The title will be inferred from your slide content, or you can override it with title and level in your frontmatter.
::right::
<Toc text-sm minDepth="1" maxDepth="2" />
--- layout: image-right image: https://cover.sli.dev ---
Code
Use code snippets and get the highlighting directly, and even types hover!
```ts {all|5|7|7-8|10|all} twoslash // TwoSlash enables TypeScript hover information // and errors in markdown code blocks // More at https://shiki.style/packages/twoslash
import { computed, ref } from 'vue'
const count = ref(0) const doubled = computed(() => count.value * 2)
doubled.value = 2
<arrow v-click="[4, 5]" x1="350" y1="310" x2="195" y2="334" color="#953" width="2" arrowSize="1" />
<!-- This allow you to embed external code blocks -->
<<< @/snippets/external.ts#snippet
<!-- Footer -->
[Learn more](https://sli.dev/features/line-highlighting)
<!-- Inline style -->
<style>
.footnotes-sep {
@apply mt-5 opacity-10;
}
.footnotes {
@apply text-sm opacity-75;
}
.footnote-backref {
display: none;
}
</style>
<!--
Notes can also sync with clicks
[click] This will be highlighted after the first click
[click] Highlighted with `count = ref(0)`
[click:3] Last click (skip two clicks)
-->
---
level: 2
---
# Shiki Magic Move
Powered by [shiki-magic-move](https://shiki-magic-move.netlify.app/), Slidev supports animations across multiple code snippets.
Add multiple code blocks and wrap them with <code>````md magic-move</code> (four backticks) to enable the magic move. For example:
```ts {|2|} // step 1 const author = reactive({ name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] })
// step 2 export default { data() { return { author: { name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] } } } }
// step 3 export default { data: () => ({ author: { name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] } }) }
Non-code blocks are ignored.
<!-- step 4 --> <script setup> const author = { name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] } </script>
---
Components
<div grid="~ cols-2 gap-4"> <div>
You can use Vue components directly inside your slides.
We have provided a few built-in components like <Tweet/> and <Youtube/> that you can use directly. And adding your custom components is also super easy.
<Counter :count="10" /><!-- ./components/Counter.vue --> <Counter :count="10" m="t-4" />
Check out the guides for more.
</div> <div>
<Tweet id="1390115482657726468" /><Tweet id="1390115482657726468" scale="0.65" />
</div> </div>
<!-- Presenter note with bold, italic, and ~~striked~~ text.
Also, HTML elements are valid: <div class="flex w-full"> <span style="flex-grow: 1;">Left content</span> <span>Right content</span> </div> -->
--- class: px-20 ---
Themes
Slidev comes with powerful theming support. Themes can provide styles, layouts, components, or even configurations for tools. Switching between themes by just one edit in your frontmatter:
<div grid="~ cols-2 gap-2" m="t-2">
---
theme: default
------
theme: seriph
---<img border="rounded" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-default/01.png?raw=true" alt="">
<img border="rounded" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-seriph/01.png?raw=true" alt="">
</div>
Read more about How to use a theme and check out the Awesome Themes Gallery.
---
Clicks Animations
You can add v-click to elements to add a click animation.
<div v-click>
This shows up when you click the slide:
<div v-click>This shows up when you click the slide.</div></div>
<br>
<v-click>
The <span v-mark.red="3"><code>v-mark</code> directive</span> also allows you to add <span v-mark.circle.orange="4">inline marks</span> , powered by Rough Notation:
<span v-mark.underline.orange>inline markers</span></v-click>
<div mt-20 v-click>
</div>
---
Motions
Motion animations are powered by @vueuse/motion, triggered by v-motion directive.
<div
v-motion
:initial="{ x: -80 }"
:enter="{ x: 0 }"
:click-3="{ x: 80 }"
:leave="{ x: 1000 }"
>
Slidev
</div><div class="w-60 relative"> <div class="relative w-40 h-40"> <img v-motion :initial="{ x: 800, y: -100, scale: 1.5, rotate: -50 }" :enter="final" class="absolute inset-0" src="https://sli.dev/logo-square.png" alt="" /> <img v-motion :initial="{ y: 500, x: -100, scale: 2 }" :enter="final" class="absolute inset-0" src="https://sli.dev/logo-circle.png" alt="" /> <img v-motion :initial="{ x: 600, y: 400, scale: 2, rotate: 100 }" :enter="final" class="absolute inset-0" src="https://sli.dev/logo-triangle.png" alt="" /> </div>
<div class="text-5xl absolute top-14 left-40 text-[#2B90B6] -z-1" v-motion :initial="{ x: -80, opacity: 0}" :enter="{ x: 0, opacity: 1, transition: { delay: 2000, duration: 1000 } }"> Slidev </div> </div>
<!-- vue script setup scripts can be directly used in markdown, and will only affects current page --> <script setup lang="ts"> const final = { x: 0, y: 0, rotate: 0, scale: 1, transition: { type: 'spring', damping: 10, stiffness: 20, mass: 2 } } </script>
<div v-motion :initial="{ x:35, y: 30, opacity: 0}" :enter="{ y: 0, opacity: 1, transition: { delay: 3500 } }">
</div>
---
LaTeX
LaTeX is supported out-of-box. Powered by KaTeX.
<div h-3 />
Inline $\sqrt{3x-1}+(1+x)^2$
Block $ {1|3|all} \begin{aligned} \nabla \cdot \vec{E} &= \frac{\rho}{\varepsilon_0} \\ \nabla \cdot \vec{B} &= 0 \\ \nabla \times \vec{E} &= -\frac{\partial\vec{B}}{\partial t} \\ \nabla \times \vec{B} &= \mu_0\vec{J} + \mu_0\varepsilon_0\frac{\partial\vec{E}}{\partial t} \end{aligned} $
---
Diagrams
You can create diagrams / graphs from textual descriptions, directly in your Markdown.
<div class="grid grid-cols-4 gap-5 pt-4 -mb-6">
```mermaid {scale: 0.5, alt: 'A simple sequence diagram'} sequenceDiagram Alice->John: Hello John, how are you? Note over Alice,John: A typical interaction
graph TD B[Text] --> C{Decision} C -->|One| D[Result 1] C -->|Two| E[Result 2]
mindmap root((mindmap)) Origins Long history ::icon(fa fa-book) Popularisation British popular psychology author Tony Buzan Research On effectiveness<br/>and features On Automatic creation Uses Creative techniques Strategic planning Argument mapping Tools Pen and paper Mermaid
@startuml
package "Some Group" { HTTP - [First Component] [Another Component] }
node "Other Groups" { FTP - [Second Component] [First Component] --> FTP }
cloud { [Example 1] }
database "MySql" { folder "This is my folder" { [Folder 3] } frame "Foo" { [Frame 4] } }
[Another Component] --> [Example 1] [Example 1] --> [Folder 3] [Folder 3] --> [Frame 4]
@enduml
</div>
Learn more: [Mermaid Diagrams](https://sli.dev/features/mermaid) and [PlantUML Diagrams](https://sli.dev/features/plantuml)
---
foo: bar
dragPos:
square: 691,32,167,_,-16
---
# Draggable Elements
Double-click on the draggable elements to edit their positions.
<br>
###### Directive Usage
<img v-drag="'square'" src="https://sli.dev/logo.png">
<br>
###### Component Usage
<v-drag text-3xl> <div class="i-carbon:arrow-up" /> Use the v-drag component to have a draggable container! </v-drag>
<v-drag pos="663,206,261,_,-15">
<div text-center text-3xl border border-main rounded>
Double-click me!
</div>
</v-drag>
<img v-drag="'square'" src="https://sli.dev/logo.png">
###### Draggable Arrow
<v-drag-arrow two-way />
<v-drag-arrow pos="67,452,253,46" two-way op70 />
---
src: ./pages/imported-slides.md
hide: false
---
---
# Monaco Editor
Slidev provides built-in Monaco Editor support.
Add `{monaco}` to the code block to turn it into an editor:
import { ref } from 'vue' import { emptyArray } from './external'
const arr = ref(emptyArray(10))
Use `{monaco-run}` to create an editor that can execute the code directly in the slide:
import { version } from 'vue' import { emptyArray, sayHello } from './external'
sayHello() console.log(vue ${version}) console.log(emptyArray<number>(10).reduce(fib => [...fib, fib.at(-1)! + fib.at(-2)!], [1, 1]))
---
layout: center
class: text-center
---
# Learn More
[Documentation](https://sli.dev) · [GitHub](https://github.com/slidevjs/slidev) · [Showcases](https://sli.dev/resources/showcases)
<PoweredBySlidev mt-10 />