If you have a working OpenClaw skill and you want more people than just your coworker on Slack to use it, ClawHub is where you publish. This guide shows exactly how to get a skill from your laptop into the public catalog, pass the automated checks, survive the human security review, and keep the thing running as OpenClaw keeps shipping weekly minors.
What ClawHub Expects From a Published Skill
ClawHub is a curated registry, not a file dump. Every submission is linted, sandbox-tested, and scanned before it shows up in the UI. Understanding the checklist up-front saves three rounds of “please fix the following”.
- OpenClaw version: your skill must declare compatibility with at least
openclaw@>=3.4.0. The review bot installs that exact version to run tests. - Repository: public on GitHub or GitLab, MIT, Apache-2.0, or GPL-3.0 only.
- Metadata file:
skill.jsonin the repo root, 1 KB max, UTF-8. - Unit tests: minimum 80% coverage; Jest or Vitest.
- Security: no plaintext API keys, must use OpenClaw’s
getSecret()helper. - Docs:
README.mdwith usage, inputs, outputs, and a GIF under 4 MB.
1. Scaffold the Skill Folder Correctly
If you used npx openclaw@latest init --skill you’re 90% there. If you started from scratch, match this minimal tree:
my-weather-skill/
├── src/
│ └── index.ts
├── __tests__/
│ └── index.test.ts
├── skill.json
├── README.md
├── LICENSE
└── package.json
Key points:
src/index.tsmust export a defaultSkillinstance.skill.jsonis machine-readable metadata; ClawHub ignores yourpackage.jsondescription field.- Tests live in
__tests__so the CI runner can glob**/__tests__/**/*.test.*.
skill.json schema
{
"name": "my-weather-skill",
"displayName": "Weather by Coordinates",
"description": "Returns current weather for latitude/longitude using the Open-Meteo API.",
"version": "1.0.0",
"license": "MIT",
"author": "Jane Doe <jane@doe.dev>",
"openClaw": ">=3.4.0",
"inputs": {
"lat": { "type": "number", "description": "Latitude" },
"lon": { "type": "number", "description": "Longitude" }
},
"outputs": {
"temperature": { "type": "number", "unit": "°C" }
},
"permissions": ["https://api.open-meteo.com/*"],
"homepage": "https://github.com/janedoe/my-weather-skill"
}
Run the schema validator before submitting:
npx @openclaw/validator skill.json
2. Write Tests That the Bot Can Run Headless
ClawHub uses the same GitHub Actions matrix as the core repo: Node 22 on Ubuntu, macOS, and Windows. Your Jest config should not rely on a display or Docker-in-Docker. If your skill spins a browser, switch to the --ci Chromium bundle:
npm install --save-dev @openclaw/headless-chromium
Example test for our weather skill:
import skill from "..";
describe("weather skill", () => {
it("returns temp as number", async () => {
const out = await skill.run({ lat: 47.01, lon: 15.43 });
expect(typeof out.temperature).toBe("number");
});
});
Generate coverage:
jest --coverage
The coverage summary is parsed; if it’s <80% your PR gets the friendly red X.
3. Security Review: Secrets, Network, and Sandboxing
This is where most submissions stall. The security bot (claw-ci-sec-001) replays your tests inside Firecracker VMs with seccomp filters. The job fails if:
- You read
/etc/passwdor anything outside/sandbox. - The code tries to spawn a shell without declaring
"shell": trueinskill.jsonpermissions. - An outbound request hits a domain not whitelisted in
permissions. - Any environment variable matches
/[_-]?key|token|secret/iand is longer than 8 chars.
Fixes:
- Use
context.http.fetchinstead ofaxios; it auto-adds the allowlist header. - Store tokens via ClawCloud’s UI; fetch at runtime:
const apiKey = await context.secrets.get("OPEN_METEO_KEY"). - Document every external call in
permissions.
Manual review
Once the bot passes, a human reads the diff. Average SLA is 48 business hours. The reviewer mainly checks for:
- Clipboard or file exfiltration patterns.
- License compliance (no vendored GPL in MIT repo).
- Reasonable resource usage (no
while(true){…}crypto loops).
Pro tip: add a SECURITY.md explaining threat model and trade-offs. It speeds the manual pass.
4. Submit to ClawHub: The PR Dance
Publishing is a pull request to openclawhub/skills. Fork, add a directory under /skills/<your-skill>, commit, and open PR. Template:
git clone https://github.com/openclawhub/skills.git
cd skills
mkdir my-weather-skill
cp -r ../my-weather-skill/* ./my-weather-skill/
git checkout -b add/my-weather-skill
git add .
git commit -m "feat: add weather by coordinates skill"
git push origin add/my-weather-skill
The repo has a PR template that asks for:
- One-liner description
- Link to CI badge in your repo
- Why the skill is useful (bullet list)
- Checklist confirm (metadata, tests, license, docs)
After CI and security review complete, a maintainer merges. GitHub Actions publishes the package to the ClawHub registry, tags the commit, and comments the final registry URL. Within ten minutes it appears in the ClawCloud UI under “Community → New”.
5. Semantic Versioning and Breaking Changes
Once public, you can’t erase 1.0.0. ClawHub keeps every tagged version so agents don’t break. Follow semver religiously:
- Patch (1.0.1): bug fix, no new inputs/outputs.
- Minor (1.1.0): new optional input, new output, performance.
- Major (2.0.0): remove or rename anything, change default behavior.
Update skill.json and git tag:
npm version minor # bumps package.json too
git push --follow-tags
OpenClaw’s loader resolves ^1.0.0 ranges, so agents on 1.x won’t see 2.0.0 unless the owner opts in. This saves you angry Telegram DMs.
6. Keeping Up with OpenClaw Core Releases
OpenClaw ships a minor every Thursday (UTC). New APIs stay behind feature flags for one release, then go default. To verify your skill still builds:
- Enable Renovate in your repo. The default config opens PRs when
openclawdeps bump. - Subscribe to “Skill Breakers” label on the main repo. These issues list deprecations.
- Run nightly CI on
openclaw@canary. Example GitHub Action:
name: nightly-canary
on:
schedule:
- cron: '0 3 * * *'
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm install openclaw@canary --save-exact
- run: npm test
When the canary breaks, you get a failing badge before users file issues.
7. Responding to Issues and PRs From the Community
Published skills sometimes take off. The weather skill sat at 50 installs for weeks, then a WhatsApp automation blogged it and it jumped to 2,300. A few lessons:
- Label your GitHub issues with
triage-neededso you can filter. - Use discussions for questions; keep issues for bugs.
- Automate sanity tests on external PRs. Example
pull_request_targetworkflow that runsnpm testwithout giving write perms. - Changelog first: add an unreleased section in
CHANGELOG.md. Reviewers look for it.
8. Deprecating or Handing Off a Skill
Life happens. If you can’t maintain the skill:
- Mark the repo
ARCHIVEDin the README header. - Open an issue in
openclawhub/skillstitled “Looking for Maintainer: my-weather-skill”. - Add
"deprecated": trueand a note toskill.json. Users get a yellow banner in the UI. - Transfer npm ownership (
npm owner add <user> my-weather-skill).
This avoids orphaned installs and keeps the catalog clean.
9. Checklist Before You Hit “Create Pull Request”
- [ ] All tests pass locally on Node 22
- [ ] Coverage ≥ 80%
- [ ]
skill.jsonvalidates - [ ] No hard-coded secrets
- [ ] README has install + usage + GIF
- [ ] LICENSE is OSI-approved
- [ ] Changelog updated
- [ ] Version bumped
That’s it. Publish, wait for the green checkmarks, answer reviewer comments, and your skill is live. Next time you refresh ClawCloud, search your skill name, click “Install”, and watch users in real-time. Good luck, and see you in the PR queue.