Configure a reusable Plugin for each project. Package a greeting command and set
its options to print Welcome.
Start with a working PathMX project.
A package can export a schema-validated factory using definePlugin. Core reads
its options from package.json under pathmx.plugins[packageName], validates them,
and constructs an ordinary Plugin. Options are inferred from the schema, including
defaults.
Create a sibling directory named greeting beside your project. In that directory,
create package.json:
{
"name": "@example/greeting",
"version": "1.0.0",
"type": "module",
"exports": { ".": "./plugin.ts" },
"pathmx": { "plugin": "." },
"peerDependencies": { "@pathmx/core": "^0.6.0" },
"dependencies": { "zod": "^4.4.3" }
}
The exports entry exposes the factory; pathmx.plugin identifies that export as
the package Plugin. Create greeting/plugin.ts:
import { definePlugin } from "@pathmx/core"
import * as z from "zod/mini"
export default definePlugin({
config: z.strictObject({
label: z._default(z.string(), "Hello"),
}),
create(config) {
return {
id: "greeting",
commands(group) {
group.command("hello").action(() => console.log(config.label))
},
}
},
})
From your consuming project root, install the local package:
bun add ../greeting
Add its activation and options to your project's package.json, preserving the
existing dependencies and scripts:
{
"pathmx": {
"plugins": {
"@example/greeting": { "label": "Welcome" }
}
}
}
Run the command from that project root:
bun run pmx greeting hello
It prints Welcome. Change label to change the greeting; use {} for the default
Hello. A number instead of a string reports the invalid manifest option path.
The same exported factory is callable in plugins/greeting.plugin.ts:
import GreetingPlugin from "@example/greeting"
export default GreetingPlugin({ label: "Welcome" })
Both paths validate the options. Calling without arguments validates {}; required
options still fail. Direct overrides do not merge manifest settings automatically.
Ordinary Plugins and presets without a configuration schema accept only {}.
A configured factory's create(config) may return a Plugin, a factory, or an
ordered Plugin preset. For example, Analytics composes its collector and page Event
namespace through the same configured factory:
import Analytics from "@pathmx/analytics"
export default Analytics({ retainDays: 90, actors: false })
Save this as plugins/analytics.plugin.ts when configuring Analytics programmatically;
choose either this entrypoint or its manifest activation.
Manifest options are JSON data. Runtime services and callbacks belong in
programmatic composition. Configuration is resolved during construction and is not
a mutable global registry. Browser publication currently rejects nonempty manifest
options rather than implicitly publishing them or reconstructing different defaults.
For a browser publication, omit this
package from pathmx.plugins and use the repository Plugin above to explicitly
compose its options. Keep it installed as a dependency. Repository Plugin code and
its options are bundled for the browser, so include only public values and
browser-compatible behavior; credentials and server-only services stay on the
server.