# Package ecosystems integration

How AXM links agent extensions and the packages they support across every major package ecosystem.

AXM makes it easy to ship agent skills, subagents, MCP server configurations,
and other extensions targeted for packages distributed on npm, crates.io, Maven,
NuGet.org, and numerous other package ecosystems. Likewise, package authors can
declare recommended extensions within their package metadata.

::repo-button[agentxm/polyglot-examples]{href="https://github.com/agentxm/polyglot-examples"}

## Linking extensions and packages

AXM links extensions and packages in two directions:

- **Recommended extensions** — a _package_ author declares, in their package's
  native metadata, which extensions they recommend for working with the package.
- **Companion packages** — an _extension_ author declares, on the extension
  manifest, which packages the extension is designed to work with.

Either declaration stands on its own. A package can recommend an extension it
doesn't own, and an extension can name a package whose author has never heard of
it. Both are unilateral discovery signals.

### Recommended extensions (package → extension)

A package author uses the portable `agentExtensions` contract v1. Every entry
has a qualified extension reference (`@owner/<type>/<name>`) and may carry a
self-describing source locator:

```jsonc
{
  "$schema": "https://axm.sh/schemas/agent-extensions.schema.json",
  "agentExtensions": [
    { "ref": "@agentxm/skills/axm", "versionRange": "^0.31.0" },
    {
      "ref": "@acme/packs/widget-kit",
      "source": {
        "type": "git",
        "url": "https://github.com/acme/widget-kit.git",
        "path": "packs/widget-kit",
        "revision": "v3.2.0",
      },
    },
  ],
}
```

A sourceless entry always resolves through the fixed AgentXM Registry at
`https://registry.agentxm.ai`; consumer settings never redirect it. An explicit
Registry source supplies `{ "type": "registry", "url": "..." }`. Git sources
accept `url` plus optional `path` and `revision`; path sources supply
`{ "type": "path", "path": "..." }`.

A recommendation can target any extension type — skill, MCP server, subagent,
rule, hook, knowledge bundle, or pack. When you want to recommend several
extensions, prefer a **pack**: it gives you one stable reference while letting
the contents evolve over time.

The recommendation-entry shape is identical everywhere. Each package format
embeds the array at its native custom-metadata point or ships the full contract
in `agent-extensions.json`; see each ecosystem's page for the exact field and
file. A malformed entry is diagnosed and ignored without hiding valid siblings.

### Companion packages (extension → package)

An extension author adds a `packages` array to the extension manifest
(`skill.json`, `pack.json`, `subagent.json`, etc.). Each entry is a
[Package URL](https://github.com/package-url/purl-spec) (purl) identifying the
package the extension targets:

```jsonc
{
  "packages": [{ "purl": "pkg:npm/%40agentxm/example-tinyflags" }],
}
```

### Official extensions

**Official** status is the one signal that both sides agree through the AgentXM
Registry. It is derived, not declared: when an extension names a package as a
companion **and** that package recommends the same extension from the fixed
AgentXM Registry, AXM marks the extension official for that package. Neither
author sets a flag. Git-sourced, path-sourced, and other-Registry
recommendations remain unilateral discovery signals and are never official.

## Versioning

Both sides default to **identity-only** references — no version pinning.

A recommendation is a discovery signal. AXM resolves it to the newest matching
extension version and pins that exact version in `axm.lock`, so the range never
controls what a user actually installs. An identity-only recommendation never
goes stale and always points at the current extension.

Likewise, a companion-package declaration usually means "this extension targets
this package," not "this extension is tied to a specific release." Do **not**
put `@version` on the purl — a versioned purl like
`pkg:npm/example-tinyflags@0.1.0` is an exact pin that goes stale on every
package release.

Add a bounded range only when there is a real compatibility constraint:

- On a Registry recommendation, use a semver `versionRange` (e.g. `"^1.0.0"`)
  only when your package genuinely pairs with a bounded major line of the
  extension. A `^major` range still lets the extension author ship minor and
  patch releases without you republishing. Avoid exact pins and `"*"` (which is
  equivalent to omitting the field). Git and path recommendations select
  revisions through their locator and do not accept `versionRange`.
- On a companion-package declaration, use a
  [VERS](https://github.com/package-url/vers-spec) `versionRange` whose scheme
  matches the purl ecosystem (e.g. `"vers:npm/>=1.0.0|<2.0.0"`) only when the
  extension depends on package APIs introduced or removed in a known range.

For pre-1.0 extensions, prefer identity-only: a caret range on a `0.x` version
(`^0.1.0` → `>=0.1.0 <0.2.0`) behaves almost like an exact pin and goes stale on
every minor release.

## Worked examples

The [`polyglot-examples`](https://github.com/agentxm/polyglot-examples)
repository is the canonical source for every ecosystem's metadata shape. Each
subdirectory pairs a small library (`*-lib`) that publishes a companion
extension set with a tiny consumer app (`*-app`) that uses it, wired with the
exact metadata AXM reads. Start with the two ecosystems documented in depth
here:

- [npm](/docs/package-ecosystems/npm)
- [PyPI](/docs/package-ecosystems/pypi)