# How to Load Custom Skills from Extra Paths in Reasonix

> Learn how Reasonix loads custom skills from extra paths. Discover how to resolve, deduplicate, and scan custom skill directories for Markdown files.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: how-to-guide
- Published: 2026-06-24

---

**Reasonix loads custom skills from user-specified directories by resolving paths through `resolveCustomPaths`, deduplicating them with `dedupePaths`, and appending them as `ScopeCustom` roots in the discovery hierarchy, where they are scanned recursively for Markdown skill files.**

The DeepSeek-Reasonix engine extends its agent capabilities through *skills*—Markdown playbooks that define specialized behaviors. While the system automatically discovers skills from built-in collections and project-local conventions, you can **load custom skills from extra paths** by configuring the `skill.Store` with additional directory roots that are resolved, deduplicated, and integrated into the discovery pipeline.

## Configuring Custom Skill Paths

The entry point for loading external skills is the `skill.Options` struct passed when creating a new skill store.

### Setting Up CustomPaths in Options

The `CustomPaths` field accepts a slice of strings representing directories to scan. These entries may include absolute paths, paths relative to the project root, or `~`-prefixed shortcuts to the user's home directory.

In [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go), the `New` function processes these paths before the store initializes. The `resolveCustomPaths` helper (lines 3939-3959) expands tilde notation to the OS home directory and joins relative entries to the project base directory, converting all entries to absolute canonical paths.

### Path Deduplication and Normalization

After resolution, the system eliminates duplicate entries to prevent redundant scanning. The `dedupePaths` function (lines 3962-3974) filters the slice, ensuring each custom directory appears only once in the discovery list while preserving the original order of first occurrence.

## Discovery Hierarchy and Root Construction

Once paths are normalized, the skill store constructs an ordered list of directories to scan, establishing priority rules for skill resolution.

### How Store.roots() Orders Custom Paths

The `Store.roots()` method (lines 188-200 of [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go)) builds the discovery hierarchy by appending each processed custom path to the roots list with the `ScopeCustom` label. This placement ensures that custom skills take precedence over global home directory skills but yield priority to project-local convention directories (`.reasonix`, `.agents`, etc.), creating a clear override hierarchy.

### The ScopeCustom Label and Priority

When custom paths are added as roots, they receive the `ScopeCustom` identifier. This scope tag is stored in the `Skill.Scope` field during parsing, allowing the system to track origin and enforce precedence rules. If duplicate skill names exist across different scopes, the discovery ordering—project-local first, then custom paths, then global—determines which version the engine selects.

## Scanning and Loading Skill Files

With the root hierarchy established, the store recursively scans each custom directory for valid skill definitions.

### Directory Traversal with scanDir

For every root marked as `ScopeCustom`, the `scanDir` function (lines 445-475) walks the directory tree respecting the configured maximum depth. When it encounters a skill file (Markdown) or a skill directory containing a [`SKILL.md`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/SKILL.md) file, it triggers the parsing pipeline.

### Skill Parsing and Scope Assignment

The `readEntry` function parses discovered Markdown files into `skill.Skill` values, assigning the root's scope (`ScopeCustom`) to the resulting struct. This metadata ensures that when you invoke `Store.List()`, custom-loaded skills appear alongside built-in ones, with precedence rules already applied. Skills discovered in extra paths are immediately available to the model via the `/skill-name` command or the `run_skill` tool.

## Implementation Example

To load skills from user-specified directories, configure the `Options` struct with your custom paths before initializing the store:

```go
// Create a skill store that loads extra skills from two user‑specified dirs.
opts := skill.Options{
    HomeDir:      "",                // use the OS home dir
    ProjectRoot: "/my/project",     // optional project root
    CustomPaths: []string{
        "~/my‑skills",               // expands to $HOME/my‑skills
        "./extra‑skills",            // relative to the project root
    },
}
store := skill.New(opts)

// List all skills, including those from the extra paths.
for _, sk := range store.List() {
    fmt.Printf("%s (%s) – %s\n", sk.Name, sk.Scope, sk.Description)
}

```

This configuration expands `~/my-skills` to the absolute home directory path and resolves `./extra-skills` relative to `/my/project`, then scans both directories for Markdown skill files.

## Summary

- **Configure custom paths** using `skill.Options.CustomPaths`, which accepts absolute, relative, or `~`-prefixed directory strings.
- **Path resolution** occurs in `resolveCustomPaths` (lines 3939-3959), which expands shortcuts and normalizes entries to absolute paths.
- **Deduplication** is handled by `dedupePaths` (lines 3962-3974) to prevent redundant scanning of the same directory.
- **Discovery hierarchy** places custom paths between project-local and global directories via `Store.roots()` (lines 188-200), using the `ScopeCustom` label.
- **Recursive scanning** via `scanDir` (lines 445-475) loads Markdown skills from extra directories, making them available through `Store.List()` with proper precedence rules.

## Frequently Asked Questions

### How do I specify multiple custom skill directories in Reasonix?

Pass a slice of strings to `Options.CustomPaths` when creating the skill store. You can mix absolute paths, paths relative to the project root, and `~` shortcuts for the home directory. The system automatically resolves and deduplicates these entries before scanning.

### What happens if a custom skill has the same name as a built-in skill?

Reasonix resolves naming conflicts through scope precedence. Project-local skills take highest priority, followed by custom paths (`ScopeCustom`), then global home directory skills. If your custom path skill conflicts with a built-in one, the custom version wins because custom roots are scanned before the global home directory.

### Can I use relative paths for custom skill directories?

Yes. Relative paths in `CustomPaths` are resolved against the `ProjectRoot` field specified in `Options`. If you provide `./extra-skills` and set `ProjectRoot` to `/my/project`, the system scans `/my/project/extra-skills` according to the `resolveCustomPaths` implementation.

### Does Reasonix support nested directories within custom skill paths?

Yes. The `scanDir` function performs a recursive directory walk respecting the configured maximum depth, discovering skill files and [`SKILL.md`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/SKILL.md) entries at any level within your custom path hierarchy. This allows you to organize skills into subdirectories by category or function.