# Best Practices for Writing Reusable Skills in the PM‑Skills Marketplace

> Learn best practices for writing reusable skills with YAML headers, generic prompts, and explicit variables for Claude, Gemini, and other AI assistants. Maximize portability and efficiency.

- Repository: [Pawel Huryn/pm-skills](https://github.com/phuryn/pm-skills)
- Tags: best-practices
- Published: 2026-07-06

---

**Write self‑contained skills using the canonical [`SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/SKILL.md) format with YAML headers, generic prompt language, and explicit `$VARIABLE` inputs to maximize portability across Claude, Gemini, and other AI assistants.**

The `phuryn/pm-skills` repository organizes product management expertise as a modular collection of plugins, skills, and commands. Following best practices for writing reusable skills ensures your contributions remain discoverable, composable, and portable across the entire marketplace without duplication or environment‑specific modifications.

## Understand the Core Architecture

A **skill** is a self‑contained knowledge module that Claude or other AI assistants invoke automatically, while a **command** is a user‑triggered workflow that strings together one or more skills. Skills reside in `<plugin>/skills/<skill‑name>/SKILL.md`, whereas commands reference these skills using the `/plugin-name:skill-name` syntax. Keeping skills atomic and independent of specific commands maximizes reusability across the ecosystem.

## Follow the Universal SKILL.md Format

Every reusable skill must live in a standardized path and begin with a YAML header that declares its identity.

### File Location and Naming Convention

Place each skill in `<plugin>/skills/<skill‑name>/SKILL.md`. For example, the resume review skill is implemented at [`pm-toolkit/skills/review-resume/SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/pm-toolkit/skills/review-resume/SKILL.md). This predictable structure allows the marketplace loader to index skills automatically.

### YAML Header Requirements

Start every [`SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/SKILL.md) with a frontmatter block containing `name` and `description`:

```yaml
---
name: review-resume
description: "Comprehensive PM resume review and tailoring..."
---

```

This header serves as the single source of truth for the skill’s identifier. Other plugins reference it via `/pm-toolkit:review-resume` without knowing its internal file path, enabling seamless cross‑plugin invocation.

## Design for Domain Specificity and Clarity

Reusable skills should encapsulate precise, well‑defined product management concepts that transfer across industries.

### Encapsulate Single Domains

Each skill should address one atomic piece of knowledge—such as `xyz+s-formula`, `opportunity-solution-tree`, or `pricing-strategy`. The main repository README catalogs these distinct capabilities under “Available Plugins.” When a skill performs a single function, any command can import that capability without dragging in unrelated logic.

### Use Generic, Context‑Independent Language

Write prompt guidance using terminology that applies to any product or industry. Declare inputs like `$RESUME` and `$JOB_POSTING` rather than hard‑coding specific roles or companies. This ensures the skill adapts to user context automatically, whether invoked for a fintech startup or an enterprise SaaS platform.

## Implement Robust Input and Output Contracts

Explicit interfaces allow commands to pass data reliably and parse results consistently.

### Declare Explicit Input Arguments

Define required and optional variables using the consistent `$VARIABLE` syntax. The `review-resume` skill demonstrates this pattern:

```markdown

## Input Arguments

- $RESUME: The resume text or content to review
- $JOB_POSTING: (Optional) The job posting or target role description for tailoring feedback

```

When composing commands, you forward these variables directly:

```markdown

# Command: /explain-concept

This command asks Claude to run `my-skill` with the topic supplied by the user.

```

/my-skill $TOPIC="North Star metric"

```

```

### Structure Responses for Downstream Composition

Organize output into clear sections such as Introduction, Detailed Feedback, and Conclusion. This structure enables commands to concatenate multiple skill outputs or allows downstream models to parse results programmatically. Avoid free‑form paragraphs that complicate automated processing.

## Ensure Cross‑Platform Portability

Reusable skills must execute in any AI assistant environment—Claude, Gemini, or OpenCode—without modification.

- **Avoid hard‑coded file paths** that may not exist in the target environment.
- **Never embed secrets or API keys** inside skill definitions.
- **Keep logic purely declarative**; rely on the AI to interpret instructions rather than executing environment‑specific code.

## Register Skills in plugin.json

Each plugin declares its exported skills in `*.claude-plugin/plugin.json`. Include reusable skills in the `exports` array to make them discoverable during automatic loading.

For example, [`pm-toolkit/.claude-plugin/plugin.json`](https://github.com/phuryn/pm-skills/blob/main/pm-toolkit/.claude-plugin/plugin.json) lists available skills for the toolkit plugin. When a skill is shared across multiple plugins, register it in each plugin’s [`plugin.json`](https://github.com/phuryn/pm-skills/blob/main/plugin.json) file to maintain visibility in the marketplace index.

## Validate Skills Automatically

Before publishing, verify that your skill adheres to marketplace standards. The repository includes [`tests/test_validator.py`](https://github.com/phuryn/pm-skills/blob/main/tests/test_validator.py), which checks skill loading consistency and ensures reusable skills do not cause import collisions or naming conflicts.

Run the skill in isolation via its corresponding command or by directly prompting Claude with the skill name. Confirm that:
1. The output follows the declared response structure.
2. All `$VARIABLE` inputs are respected and processed.
3. No environment‑specific errors occur.

## Summary

- **Standardize on [`SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/SKILL.md)** with YAML headers in `<plugin>/skills/<skill‑name>/SKILL.md` for automatic discovery.
- **Encapsulate single domains** using generic, industry‑independent language and explicit `$VARIABLE` inputs.
- **Structure outputs** into predictable sections to support downstream command composition.
- **Register exports** in `*.claude-plugin/plugin.json` to publish skills across the marketplace.
- **Validate** using [`tests/test_validator.py`](https://github.com/phuryn/pm-skills/blob/main/tests/test_validator.py) and isolated testing to ensure cross‑platform compatibility.

## Frequently Asked Questions

### What is the difference between a skill and a command in PM‑Skills?

A **skill** is a self‑contained knowledge module stored in [`SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/SKILL.md) that performs a specific product management function, while a **command** is a user‑triggered workflow defined in a separate markdown file that invokes one or more skills to complete a complex task. Skills are the reusable building blocks; commands are the orchestration layer.

### How do I make a skill available to other plugins?

Add the skill’s identifier to the `exports` array in your plugin’s `*.claude-plugin/plugin.json` file. For example, [`pm-toolkit/.claude-plugin/plugin.json`](https://github.com/phuryn/pm-skills/blob/main/pm-toolkit/.claude-plugin/plugin.json) exports the `review-resume` skill, allowing other plugins to invoke it via `/pm-toolkit:review-resume` without duplicating the skill file.

### Can skills written for Claude work in other AI assistants?

Yes, provided you follow the portability guidelines. The canonical [`SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/SKILL.md) format is platform‑agnostic. The repository provides shell snippets for copying skills to OpenCode, Gemini, and other ecosystems, but this only works if you avoid hard‑coded paths, environment variables, and assistant‑specific syntax in your skill definitions.

### How do I test a skill before submitting it to the marketplace?

Run the skill in isolation by invoking it directly through Claude or by executing its associated command. Verify that the YAML header parses correctly, all `$VARIABLE` inputs produce expected outputs, and the response structure matches your documentation. Additionally, run [`tests/test_validator.py`](https://github.com/phuryn/pm-skills/blob/main/tests/test_validator.py) to catch naming collisions or schema violations before submission.