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

# Testing a Custom Plugin

> Run and test a third-party driver plugin in a local debug build without a code signing error

# Testing a Custom Plugin

When you write your own driver plugin, you can run it inside a local debug build of TablePro before publishing it to the registry. If you package the plugin and install it the way the app installs a registry plugin, it fails with "Unable to install plug-in." The install path only accepts plugins signed by TablePro's signing team, and a plugin you just built locally is not signed by it.

The way around this is to let the plugin ship inside the app bundle instead of installing it as a user plugin. Add it to the **Copy Plug-Ins** build phase, then run the app. Plugins that live inside the app bundle load as built-in plugins, which are not put through the signature check.

## Steps

<Steps>
  <Step title="Add the plugin to Copy Plug-Ins">
    In Xcode, select the **TablePro** target, open the **Build Phases** tab, and add your `.tableplugin` bundle to the **Copy Plug-Ins** phase.
  </Step>

  <Step title="Run the app">
    Press `Cmd+R` to build and run. See [Building](/development/building) for the `-skipPackagePluginValidation` requirement on command-line builds.
  </Step>

  <Step title="Test the plugin">
    The plugin loads with the app. Create a connection for your database type and confirm the driver works.
  </Step>

  <Step title="Remove it after testing">
    Once the plugin works, remove it from the **Copy Plug-Ins** phase so it does not ride into a release build.
  </Step>
</Steps>

<Note>
  Keep the plugin in **Copy Plug-Ins** only while you are testing. Release builds distribute plugins through the [Plugin Registry](/development/plugin-registry), where every binary is signed.
</Note>

## Why the signing error happens

TablePro loads plugins from two locations, and treats them differently:

* **Inside the app bundle** (`PlugIns/`): loaded as built-in plugins. No signature check runs.
* **In the user plugins directory**: loaded as user-installed plugins. Each one must be signed by TablePro's signing team, or it is rejected.

Installing a plugin from the registry, or packaging your own to install the same way, goes through the user-installed path. A plugin you built locally does not carry TablePro's signature, so that path rejects it with "Unable to install plug-in."

Adding the plugin to **Copy Plug-Ins** avoids the check on two counts. The plugin lands in the app's `PlugIns/` directory, so it loads as a built-in plugin and the user-install signature check never runs. The phase also re-signs the plugin with the debug build's own signing identity (`CodeSignOnCopy`) as it copies it in.

## Alternative: allow unsigned user plugins

If you would rather keep developing the plugin from the user plugins directory, a debug build skips the signature check when the `TABLEPRO_ALLOW_UNSIGNED_PLUGINS` environment variable is set to `1`. Set it under **Product > Scheme > Edit Scheme > Run > Arguments**. This works in debug builds only. Release builds always verify the signature.

When the plugin is ready to ship, publish it through the registry so users receive a signed binary. See [Plugin Registry](/development/plugin-registry) for the manifest format and publishing flow.
