clawbuttons
Drop-in buttons for the entire OpenClaw-style harness ecosystem — OpenClaw, Hermes, IronClaw, NanoClaw, ZeroClaw, OpenHarness, and ClaudeClaw. Built as framework-agnostic Web Components with zero dependencies.
Supported Harnesses
| OpenClaw | <openclaw-button> | openclaw -p | #E74C3C | The dominant open-source AI agent platform (200k+ stars) |
| Hermes | <hermes-button> | hermes -p | #9B59B6 | Persistent personal agent with long-term memory |
| IronClaw | <ironclaw-button> | ironclaw agent | #5D6D7E | Rust-based privacy-first AI assistant with WASM sandboxes |
| NanoClaw | <nanoclaw-button> | claw | #1ABC9C | Minimalist container-based agent (~500 lines of TS) |
| ZeroClaw | <zeroclaw-button> | zeroclaw agent | #E67E22 | Rust-based with WASM sandbox, 14x faster than OpenClaw |
| OpenHarness | <openharness-button> | oh | #27AE60 | Lightweight Python harness (44x lighter than Claude Code) |
| ClaudeClaw | <claudeclaw-button> | claudeclaw | #D4795C | Lightweight Claude Code wrapper with daemon mode |
Install
npm install clawbuttons
Or use the CDN (no build step):
<script src="https://unpkg.com/clawbuttons"></script>
Quick Start
<openclaw-button command="Deploy the full-stack app" theme="branded"></openclaw-button>
<hermes-button command="/research deep-dive" variant="outline"></hermes-button>
<ironclaw-button command="Audit security vulnerabilities" theme="dark"></ironclaw-button>
<nanoclaw-button command="Run isolated tests" skill-url="https://example.com/skill.zip"></nanoclaw-button>
Framework Integration
Vanilla HTML / CDN
<script src="https://unpkg.com/clawbuttons"></script>
<openclaw-button command="/deploy --prod" theme="branded"></openclaw-button>
<hermes-button command="/research" theme="dark"></hermes-button>
<script>
document.querySelector('openclaw-button')
.addEventListener('cb-copy', (e) => console.log('Copied:', e.detail.command));
</script>
React / Next.js
Use the dedicated React wrappers (handles SSR, hydration, and prop forwarding):
import {
OpenClawButton,
HermesButton,
IronClawButton,
NanoClawButton,
ZeroClawButton,
OpenHarnessButton,
ClaudeClawButton,
} from 'clawbuttons/react';
function App() {
return (
<>
<OpenClawButton
command="Deploy the full-stack app"
theme="branded"
onCopy={(cmd) => console.log('Copied:', cmd)}
/>
<HermesButton
command="/research"
skillUrl="https://example.com/skill.zip"
variant="outline"
/>
<IronClawButton
command="Security audit"
theme="dark"
/>
</>
);
}
The React wrappers:
- Include
'use client' for Next.js App Router
- Handle SSR/hydration with
suppressHydrationWarning
- Lazy-load the Web Components to avoid SSR crashes
- Forward both property callbacks (
onCopy) and CustomEvent listeners (onCbCopy)
Vue / Nuxt
Option A: Vue Plugin (recommended)
import { createApp } from 'vue';
import { ClawButtonsPlugin } from 'clawbuttons/vue';
import App from './App.vue';
const app = createApp(App);
app.use(ClawButtonsPlugin);
app.mount('#app');
<template>
<openclaw-button
command="/deploy"
theme="branded"
@cb-copy="onCopy"
/>
<hermes-button
command="/research"
variant="outline"
/>
</template>
<script setup>
function onCopy(e) {
console.log('Copied:', e.detail.command);
}
</script>
Option B: Manual setup
import vue from '@vitejs/plugin-vue';
export default {
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) =>
tag.endsWith('-button') && ['openclaw', 'hermes', 'ironclaw', 'nanoclaw', 'zeroclaw', 'openharness', 'claudeclaw'].some(h => tag.startsWith(h)),
},
},
}),
],
};
Svelte / SvelteKit
<script>
import 'clawbuttons';
function handleCopy(e) {
console.log('Copied:', e.detail.command);
}
</script>
<openclaw-button
command="/deploy"
theme="branded"
on:cb-copy={handleCopy}
/>
<hermes-button command="/research" variant="ghost" />
Angular
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import 'clawbuttons';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<openclaw-button
command="/deploy"
theme="branded"
(cb-copy)="onCopy($event)"
></openclaw-button>
<ironclaw-button
command="Security audit"
theme="dark"
></ironclaw-button>
Solid
import 'clawbuttons';
function App() {
return (
<>
<openclaw-button
command="/deploy"
theme="branded"
on:cb-copy={(e) => console.log(e.detail.command)}
/>
<hermes-button command="/research" variant="outline" />
</>
);
}
Astro
---
---
<script>
import 'clawbuttons';
</script>
<openclaw-button command="/deploy" theme="branded" />
<hermes-button command="/research" theme="dark" />
Programmatic JavaScript API
import { createButton } from 'clawbuttons';
const btn = createButton('openclaw', {
command: '/deploy --prod',
theme: 'branded',
onCopy: (cmd) => console.log('Copied:', cmd),
});
document.getElementById('container').appendChild(btn);
Themes
branded | Uses each harness's brand color (default) |
branded-alt | Purple secondary (#6B5CE7) — great for mixing harnesses |
dark | Dark surface, light text, harness-colored accents |
light | White surface, dark text, harness-colored accents |
system | Auto-switches between light/dark based on prefers-color-scheme |
Sizes
sm | 2rem (32px at default font size) |
md | 2.5rem (40px) (default) |
lg | 3rem (48px) |
Events
All buttons dispatch native CustomEvents with bubbles: true and composed: true (crosses Shadow DOM).
cb-copy | { command: string, harness: string } | Command copied to clipboard |
cb-open | { command: string, harness: string } | Button clicked / popup opens |
cb-close | { harness: string } | Popup closed |
el.addEventListener('cb-copy', (e) => {
console.log(`Copied ${e.detail.harness} command:`, e.detail.command);
});
API Reference
Common Attributes (all <*-button> elements)
command | string | — | The skill/command to run |
skill-url | string | — | URL to downloadable skill package |
theme | 'branded' | 'branded-alt' | 'dark' | 'light' | 'system' | 'branded' | Theme variant |
size | 'sm' | 'md' | 'lg' | 'md' | Button size |
variant | 'filled' | 'outline' | 'ghost' | 'filled' | Visual variant |
shape | 'rounded' | 'pill' | 'square' | 'rounded' | Border radius shape |
popup | 'true' | 'false' | 'true' | Show popup dialog on click |
prompt-flag | 'true' | 'false' | 'true' | Prepend CLI prefix to command |
popup-title | string | 'Run on {Harness}' | Custom popup title |
popup-description | string | — | Custom popup description |
JavaScript Exports
import {
createButton,
registerHarnessButton,
registerAllButtons,
register,
showPopup,
HARNESSES,
HARNESS_IDS,
getHarness,
getIcon,
resolveTheme,
} from 'clawbuttons';
import {
OpenClawButton,
HermesButton,
IronClawButton,
NanoClawButton,
ZeroClawButton,
OpenHarnessButton,
ClaudeClawButton,
} from 'clawbuttons/react';
import { ClawButtonsPlugin } from 'clawbuttons/vue';
Explicit Registration
Registration happens automatically on import. For frameworks that need timing control:
import { register } from 'clawbuttons';
register();
Or register individual harnesses with custom tag names:
import { registerHarnessButton } from 'clawbuttons';
registerHarnessButton('openclaw');
registerHarnessButton('hermes', 'my-hermes-btn');
Browser Support
Works in all browsers that support Custom Elements v1:
- Chrome 67+
- Firefox 63+
- Safari 10.1+
- Edge 79+
License
MIT