# How to Create Custom Skills Using the `skills init` Command

> Learn to create custom skills easily with the skills init command. This tool scaffolds a complete skill, including the SKILL.md file, to get you started fast.

- Repository: [Vercel Labs/skills](https://github.com/vercel-labs/skills)
- Tags: how-to-guide
- Published: 2026-04-23

---

**The `skills init` command scaffolds a complete skill by generating a [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) file with front-matter template in either a new folder or the current directory.**

The `skills init` command is the fastest way to bootstrap a custom skill in the Vercel Labs skills ecosystem. This CLI tool creates a self-contained instruction bundle for AI agents, complete with the required metadata structure that downstream tools expect. Understanding how `skills init` works internally helps you integrate it into workflows and customize the output for your organization's needs.

## What `skills init` Creates

When you run `skills init`, the CLI generates a [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) file containing:

- **Required front-matter**: `name` and `description` fields for skill discovery
- **Structured sections**: `When to use`, `Instructions`, and other standard blocks
- **Placeholder content**: Ready for you to replace with your specific guidance

This consistent layout ensures compatibility with commands like `skills add`, `skills list`, and the broader skill discovery pipeline.

## How the `skills init` Command Works Internally

The initialization flow is implemented entirely within [`src/cli.ts`](https://github.com/vercel-labs/skills/blob/main/src/cli.ts) in a dedicated `runInit` function. Here's the step-by-step execution:

### 1. CLI Dispatch

The main CLI entry point detects the `init` sub-command and delegates to `runInit`:

```typescript
// src/cli.ts lines 66-70
if (command === 'init') {
  await runInit(args);
  process.exit(0);
}

```

### 2. Path Resolution

`runInit` determines where to create the skill based on whether you provided a name argument:

```typescript
// src/cli.ts lines 222-229
const cwd = process.cwd();
const skillName = args[0] || basename(cwd);
const hasName = args[0] !== undefined;
const skillDir = hasName ? join(cwd, skillName) : cwd;
const skillFile = join(skillDir, 'SKILL.md');

```

**Key behavior**: With a name argument, it creates a new folder; without one, it places [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) directly in the current directory.

### 3. Safety Check

The command prevents accidental overwrites:

```typescript
// src/cli.ts lines 231-234
if (existsSync(skillFile)) {
  console.log(chalk.yellow(`⚠️  SKILL.md already exists at ${skillFile}`));
  process.exit(1);
}

```

### 4. Directory Creation

When needed, the folder is created recursively:

```typescript
// src/cli.ts lines 236-238
if (hasName) {
  mkdirSync(skillDir, { recursive: true });
}

```

### 5. Template Generation and Writing

The [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) content is assembled as a string (lines 240-258) and written to disk:

```typescript
// src/cli.ts line 260
writeFileSync(skillFile, skillTemplate);

```

### 6. Next Steps Guidance

Finally, the CLI prints actionable instructions:

```typescript
// src/cli.ts lines 262-281
console.log(chalk.green(`✅ Created ${skillFile}`));
console.log(chalk.dim('\nNext steps:'));
console.log(`  1. Edit ${chalk.cyan('SKILL.md')} to add your instructions`);
console.log(`  2. Update the front-matter (name, description, etc.)`);
console.log(`  3. Run ${chalk.cyan('skills add')} to register your skill`);

```

## Practical Usage Examples

### Create a Skill in a New Folder

```bash
npx skills init my-awesome-skill

```

Creates [`./my-awesome-skill/SKILL.md`](https://github.com/vercel-labs/skills/blob/main/./my-awesome-skill/SKILL.md) with the starter template.

### Create a Skill in the Current Directory

```bash
npx skills init

```

Creates [`./SKILL.md`](https://github.com/vercel-labs/skills/blob/main/./SKILL.md) directly.

### Edit the Generated Skill

```bash
code my-awesome-skill/SKILL.md  # VS Code

# or

vim my-awesome-skill/SKILL.md   # Terminal editor

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`src/cli.ts`](https://github.com/vercel-labs/skills/blob/main/src/cli.ts) — `runInit` function | Core logic: argument parsing, file/folder creation, template writing, user guidance |
| [`src/cli.ts`](https://github.com/vercel-labs/skills/blob/main/src/cli.ts) — main command dispatch | Routes `init` sub-command to `runInit` |
| [`package.json`](https://github.com/vercel-labs/skills/blob/main/package.json) | Provides version info for CLI telemetry |
| `README` | Documents high-level `skills` CLI usage |

## Summary

- **`skills init`** is the primary CLI command for bootstrapping custom skills in the Vercel Labs ecosystem
- The command generates a complete **[`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md)** file with required front-matter and structured sections
- **Path resolution logic**: name argument creates a new folder; no argument uses current directory
- **Safety features**: prevents overwriting existing [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) files
- **Implementation**: entirely contained in `runInit` within [`src/cli.ts`](https://github.com/vercel-labs/skills/blob/main/src/cli.ts) for maintainability and testability
- **Next steps**: edit front-matter, add instructions, then register with `skills add`

## Frequently Asked Questions

### What happens if I run `skills init` in a directory that already has a [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) file?

The command detects the existing file and aborts with a warning message. As implemented in [`src/cli.ts`](https://github.com/vercel-labs/skills/blob/main/src/cli.ts) lines 231-234, it checks `existsSync(skillFile)` and exits with code 1 rather than overwriting your work.

### Can I use `skills init` programmatically instead of through the CLI?

Yes. Since `runInit` is a regular exported function in [`src/cli.ts`](https://github.com/vercel-labs/skills/blob/main/src/cli.ts), you can import and invoke it directly from other scripts or CI jobs. Pass an array of string arguments matching what you'd type on the command line.

### What front-matter fields does the generated [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) include?

The template includes `name` and `description` as required fields, plus placeholder sections for usage conditions and detailed instructions. You should customize these before running `skills add` to register your skill.

### Does `skills init` create any files besides [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md)?

No. The command only creates the [`SKILL.md`](https://github.com/vercel-labs/skills/blob/main/SKILL.md) file and optionally the containing folder if you provided a skill name. It does not generate additional configuration files, test stubs, or documentation beyond what's in the template.