---
title: "Quickstart"
description: "Install the plugin tool, scaffold a Rust plugin, build it, link it into OpenIDEA and run its commands."
---
This walkthrough creates a code plugin with two commands, tests it, builds it to WebAssembly and loads it into the IDE without installing it.
## Prerequisites
- OpenIDEA installed.
- Rust through [rustup](https://rustup.rs). `openidea-plugin build` adds the `wasm32-wasip2` target through rustup if it is missing; you can also add it yourself with `rustup target add wasm32-wasip2`.
```sh
cargo install --locked --git https://github.com/l0ng-ai/openidea ide-host --bin openidea-plugin
```
This builds the tool from the `main` branch. To match a released IDE, add `--tag v` (for example `--tag v0.1.40`). Each release also attaches a Linux x64 binary, `openidea-plugin-linux-x86_64.gz`.
`openidea-plugin --version` prints the tool version and the plugin API it checks against.
```sh
openidea-plugin new hello --id acme.hello
cd hello
```
The `command` template (the default) writes:
| File | What it is |
| --- | --- |
| `plugin.toml` | The manifest: id `acme.hello`, name `Hello`, two commands, the `editor.read` capability |
| `Cargo.toml` | A `cdylib` crate that depends on the SDK |
| `src/lib.rs` | The commands, plus unit tests against the SDK's mock host |
| `README.md`, `.gitignore` | |
The id is `.`. The publisher part (`acme`) is what you sign with when you publish; without `--id` the id is derived from the folder name. `--name` sets the display name.
The SDK dependency points at this repository at the tool's release tag (`{ git = "https://github.com/l0ng-ai/openidea", tag = "v…" }`). Pass `--sdk ` to use a local checkout instead.
Other templates: `--template theme`, `--template icon-theme`, `--template language`. They need no code.
```sh
cargo test
```
On your machine the SDK talks to a mock host, so the command logic is tested without the IDE. See [Testing and debugging](/en/plugins/testing).
```sh
openidea-plugin build
```
This runs `cargo build --release --target wasm32-wasip2`, copies the result to `dist/plugin.wasm` (the manifest's `wasm` path) and then runs `openidea-plugin check`, which validates the package exactly as installing would and prints what the user will be asked to grant:
```text
acme.hello 0.1.0 — Hello
code: dist/plugin.wasm (…, plugin API 1.4)
categories: tools
contributes 2 × commands
capability editor.read (required, Low risk): Read the focused editor's file and selection
ok
```
Use `openidea-plugin build --debug` for a debug build.
```sh
openidea-plugin link
```
`link` adds the folder to `links.json` in the IDE's plugins directory. Linked plugins are read from the folder itself, so you never reinstall while developing. `openidea-plugin links` lists linked folders and `openidea-plugin unlink` removes one.
The plugins directory is `$OPENIDEA_PLUGINS_DIR`, or `ai.l0ng.openidea/plugins` in your system's app data directory. A development build of OpenIDEA from source uses its own data directory: point `OPENIDEA_PLUGINS_DIR` at its `plugins` folder when you link. See [Data directories](/en/reference/data-directories).
1. Open **Settings › Plugins** (`⌘,` on macOS, `Ctrl+Alt+S` on Windows/Linux). The plugin is listed under **Linked for development** with the status **Needs permission**.
2. Select it and click **Review Permissions…**, then **Allow** in the *Allow Hello to run?* dialog.
3. Open Find Action (`⌘⇧A` / `Ctrl+Shift+A`) and run **Hello: Say Hello**. A notification says *Hello #1 from Hello!*.
4. Open any file and run **Hello: Line Count of Active File**. The command returns text, which the IDE shows to you.
## The edit loop
1. Change `src/lib.rs` (or `plugin.toml`).
2. Run `openidea-plugin build`.
3. In **Settings › Plugins**, select the plugin and click the **Reload from disk** button in its details, or run the **Reload Plugins** action from Find Action.
If something goes wrong, the plugin's details in **Settings › Plugins** show its status and why it failed. See [Testing and debugging](/en/plugins/testing) for logs.
## What is in the code
```rust
use openidea_plugin::{Error, Invocation, NotificationLevel, Plugin, host, register_plugin};
#[derive(Default)]
pub struct Main {
greetings: u32,
}
impl Plugin for Main {
fn run_command(&mut self, id: &str, ctx: &Invocation, _arg: Option<&str>) -> Result