# Build your first plugin

Create, build, test and enable a small plugin with the loam command line, then run its command.

This page builds a plugin called `word-count`. It adds one command, `word-count.hello`, and uses the four `loam plugin` commands you need for every plugin: `new`, `build`, `test` and `enable`. The output blocks are what `loam` printed for this plugin. The examples use `--vault ~/Notes`; you can leave it out when you run from inside the vault.

## Before you start

- Swift 6.2 on your PATH. Xcode or the Command Line Tools provide it, and Loam builds plugins with it.
- The `loam` command on your PATH. The [install command](/docs/install) links it into `~/.local/bin`. Otherwise, Settings > Developers in the app puts it on your PATH.
- A network connection for the first build. It downloads the SDK's dependencies, such as swift-markdown and Yams, from GitHub.

## Create, build and test

1. Create the package: `loam --vault ~/Notes plugin new word-count`.
2. Open `.loam/plugins/word-count/Sources/WordCount/WordCountPlugin.swift`. The command is already there. Change its text if you want.
3. Build it: `loam --vault ~/Notes plugin build word-count`. Wait for `"ok" : true`. The first build takes a few minutes.
4. Test it: `loam --vault ~/Notes plugin test word-count`. Wait for `"ok" : true`.

`plugin new` writes this package, relative to your vault:

```text
.loam/plugins/word-count/
  plugin.json
  Package.swift
  Sources/WordCount/WordCountPlugin.swift
  Tests/WordCountTests/WordCountPluginTests.swift
  README.md
  .gitignore
```

It prints the new id and its folder:

```text
{
  "id" : "word-count",
  "path" : "/Users/you/Notes/.loam/plugins/word-count"
}
```

The generated command is in `WordCountPlugin.swift`. Its `summary` is what agents read:

**Sources/WordCount/WordCountPlugin.swift**

```swift
public func activate(context: PluginContext) throws {
    let vault = context.vault
    try context.registerCommand(Command(
        id: "word-count.hello",
        title: "Word Count: say hello",
        summary: "Says hello and how many notes the vault has. No arguments; optional: name."
    ) { arguments in
        let notes = try vault.markdownPaths().count
        return "Hello \(arguments["name"] ?? "from Word Count"). Notes in this vault: \(notes)."
    })
}
```

Build prints `ok` and the library it compiled. Its `log` holds the Swift build output, shortened here:

```text
{
  "id" : "word-count",
  "library" : "/Users/you/Notes/.loam/cache/plugins/word-count/libWordCountPlugin.dylib",
  "log" : "<the Swift build output>",
  "ok" : true
}
```

## Enable and run it

1. Check the permissions. The template sets `"permissions": ["vault.read"]` in `plugin.json`, because this command reads your notes. Keep it unless you remove the command.
2. Enable the plugin: `loam --vault ~/Notes plugin enable word-count`.
3. Run the command: `loam --vault ~/Notes word-count.hello name=Ada`.

`plugin enable` prints what started:

```text
{
  "activated" : [
    "word-count"
  ],
  "active" : true,
  "enabled" : "word-count"
}
```

The command prints one line. The count is 0 in this example because the test vault is empty:

```text
Hello Ada. Notes in this vault: 0.
```

## Next steps

Read [Anatomy of a plugin](/docs/plugins/anatomy) for each file in the package, then [Plugin commands](/docs/plugins/commands) to add more. Before you share the plugin, read [Share and install plugins](/docs/plugins/share).

> **Tip:** For AI agents: `loam guide plugins` has these steps with the rules that `loam plugin build` checks.
