> ## Documentation Index
> Fetch the complete documentation index at: https://voyant.travel/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Adapters and providers

> How to swap a vendor or infrastructure implementation inside a Voyant deployment: providers are the swap point, adapters connect the platform to an external system, and both are first-class deployment graph units.

Voyant keeps a deliberately small extension vocabulary. **Modules** are the components the platform is built from, and customization happens at two seams: **adapters and providers**, which change an implementation *inside* the deployment, and [**apps**](/docs/platform/extending/apps), which run entirely outside it.

This page covers the first seam.

<Note>
  **Plugins no longer exist.** Voyant used to have a generic plugin kind; it is retired, and a workspace package that declares `voyant.kind: "plugin"` now fails the architecture verification. Everything that used to be a plugin is an adapter, a provider, an extension, or an app. If you are migrating, the mapping is at the bottom of this page.
</Note>

## Which one do I need?

<CardGroup cols={2}>
  <Card title="Provider" icon="right-left">
    You want to replace one concrete implementation with another behind an existing contract. Payments, notifications, object storage, search.
  </Card>

  <Card title="Adapter" icon="plug">
    You want to talk to a specific external system, and that integration owns more than a single contract: routes, webhooks, subscribers, or several providers at once.
  </Card>

  <Card title="Extension" icon="pen">
    You want to change how an existing module behaves, not swap an implementation. See [Extensions](/docs/platform/fundamentals/extensions).
  </Card>

  <Card title="App" icon="grid-2">
    You are adding a genuinely new capability with its own records and lifecycle. Build it as an [app](/docs/platform/extending/apps) that runs outside the deployment.
  </Card>
</CardGroup>

<Note>
  **Modules are not an extension point.** They are the components the platform itself is built from, and a deployment cannot add, drop, or replace one. If you need new capability, build an [app](/docs/platform/extending/apps); if you need to change existing behavior, build an [extension](/docs/platform/fundamentals/extensions).
</Note>

The short test: if the question is *"how do I swap one implementation for another?"*, the answer is a **provider**. If the package exists primarily to talk to an external system, it is an **adapter**, even when it also ships providers.

## Providers

A provider implements a narrow contract for one execution seam and hides the vendor behind it. Nothing calling the contract should be able to tell which provider is selected.

Providers are first-class deployment graph units:

* `package.json#voyant.kind` is `"provider"`
* the graph manifest uses `schemaVersion: "voyant.provider.v1"`

A provider should implement one contract, stay focused on that seam, and keep vendor-specific detail entirely internal.

### Roles, not vendors

A provider role is defined by what it does, not by who supplies it. Object storage is one role with built-in values `memory` and `s3-compatible` — AWS S3, Cloudflare R2, Google Cloud Storage's XML API, MinIO and similar all configure the `s3-compatible` value through endpoint and credential settings rather than getting a role each.

This matters when you write application code: modules resolve logical stores such as `media` and `documents`. They never resolve a vendor bucket or a runtime binding. A custom storage package declares a selected `storage.object` provider factory and returns the same logical-store resolver contract.

Payments works the same way. [`@voyant-travel/payments`](https://github.com/voyant-travel/voyant/tree/main/packages/payments) defines the adapter contract — initiate, status, verify — plus the provider catalog and remote transport. Netopia and Voyant Pay are entries in that catalog, not bespoke integrations wired into the booking flow.

See [Choose or swap a provider](/docs/guides/swap-a-provider) for the mechanics.

## Adapters

An adapter connects Voyant to an external vendor or service. It is the right shape when the integration is broader than a single contract.

Adapters are first-class deployment graph units:

* `package.json#voyant.kind` is `"adapter"`
* the graph manifest uses `schemaVersion: "voyant.adapter.v1"`

An adapter may expose:

* one or more providers
* a small extension over an existing module
* route or webhook wiring
* subscriber or job wiring owned by the integration package

It may not introduce a new domain module by the back door. If the integration turns out to own its own records and lifecycle, it is a module, and it should be built as one.

[`@voyant-travel/voyant-connect-adapter`](https://github.com/voyant-travel/voyant/tree/main/packages/voyant-connect-adapter) is the reference example: it brings [Connect](/docs/connect/overview) supplier connectivity into a deployment on top of the external Connect SDK.

## Selection happens in the graph

Neither seam is a runtime plugin registry. Adapters and providers are ordinary units in the resolved deployment graph, selected when the deployment is composed. Object storage, key-value, rate limiting, and search all resolve this way.

Two consequences worth knowing up front:

* **A standard module cannot be dropped or replaced.** Substitution happens at adapters and providers, never at business modules. A deployment gets the same bookings module as everyone else; what it can change is which payment provider that module ends up calling.
* **Runtime contributors must declare every returned port on the owning graph unit.** A package cannot quietly contribute a capability it did not declare.

## Migrating from plugins

If you have a package that predates the retirement of the plugin kind, it maps to one of these:

| It used to...                                   | It is now                                           |
| ----------------------------------------------- | --------------------------------------------------- |
| Integrate a payment, search, or storage vendor  | A **provider**, or an **adapter** exposing one      |
| Talk to an external accounting or CRM system    | An **app**, if its code runs outside the deployment |
| Sync content from a CMS                         | An **app**                                          |
| Add behavior around an existing module          | An **extension**                                    |
| Introduce a new capability with its own records | A **module**                                        |

Accounting and CRM integrations such as SmartBill are **apps**, not adapters, because their code runs outside the Voyant process entirely. That distinction is the subject of the [next page](/docs/platform/extending/apps).

<CardGroup cols={2}>
  <Card title="Choose or swap a provider" icon="right-left" href="/docs/guides/swap-a-provider">
    The step-by-step version.
  </Card>

  <Card title="Apps" icon="grid-2" href="/docs/platform/extending/apps">
    The other seam: code that runs outside the deployment.
  </Card>
</CardGroup>
