--- title: Plugin reference description: Local plugin files, client and server runtimes, platform limits, contributions, RPCs, lifecycle, hosts, and CLI commands. nav: Reference order: 46 category: Plugins --- # Plugin reference Migrating an existing plugin? Follow the standalone [runtime-entry migration guide](/docs/plugins/migration). Local plugins are directory sources installed into one Paseo daemon. A plugin can contribute: - React Native surfaces and sidebar items to Paseo clients; - workspace and agent panels opened as workspace tabs; - global, workspace, and agent actions in the Command Center; - slash commands in the message composer; - transformed and daemon-pushed agent timeline rows; - light and dark themes in Settings → Appearance; - schema-validated RPC handlers running beside the daemon; - normal Paseo operations through the TypeScript SDK; - searchable external resources in the message composer. Plugin code is trusted and unsandboxed. Client surfaces run in the Paseo app. Backend contributions run in a subprocess with access to the daemon machine, including its files, processes, credentials, and network. ## Project files `paseo plugin init /absolute/path/to/my-plugin` creates: ```text my-plugin/ paseo-plugin.json index.client.tsx index.server.ts client/greeting.tsx server/greeting.ts shared/greeting.ts package.json tsconfig.json ``` The required root manifest is `paseo-plugin.json`. It contains the default plugin ID: ```json { "id": "my-plugin" } ``` | Entry | Runtime | Receives | Required | | ------------------ | --------------------- | --------------------- | ----------------------------------------------------------------- | | `index.client.tsx` | Paseo app, per client | `PluginClientContext` | When the plugin has any UI, callback, theme, or attachment source | | `index.server.ts` | Daemon subprocess | `PluginServerContext` | When the plugin handles RPCs | At least one entry is required; both accept `.ts` or `.tsx`. A directory that still has only the old `index.ts` fails to load and points at the [migration guide](/docs/plugins/migration). Plugin, surface, sidebar-item, workspace-panel, Command Center item, attachment-source, and slash-command IDs start with a lowercase letter and contain lowercase letters, numbers, or hyphens. The generated `package.json` installs `@getpaseo/plugin` and the other host modules as development dependencies for local typechecking and tests. Paseo supplies their runtime instances. Consumers do not install them when adding the plugin. Every other module lives in one of three directories. Nesting inside them is fine; a module at the plugin root is a compile error. | Directory | Compiled into | Use it for | | --------- | ------------------ | -------------------------------------------------------------------- | | `client/` | App bundle only | React, React Native, hooks, styles, surfaces, panels, and callbacks. | | `server/` | Daemon bundle only | Node APIs, local resources, credentials, and RPC handlers. | | `shared/` | Both | Zod RPC contracts and plain values imported by both runtimes. | ## Runtime modules Paseo builds each bundle from its matching entry. An import from `client/` into the daemon bundle, from `server/` into the app bundle, or of a `node:` module anywhere in the app bundle is a compile error. Keep `shared/` free of Node and React Native runtime code. ### Client runtime Paseo provides these modules to client code: | Module | Use it for | | ------------------------------- | ------------------------------------------------------------------------------------------------------ | | `@getpaseo/plugin` | Contribution contracts, `defineRpc`, `defineAttachmentSource`, `RpcInput`, `RpcOutput`, and data hooks | | `@getpaseo/plugin/react-native` | Paseo UI components and UI hooks | | `@getpaseo/plugin/server` | Handler-only types such as `PluginHandlerContext` | | `@tanstack/react-query` | Request state and caching | | `react` | Components and hooks | | `react/jsx-runtime` | Compiled JSX | | `react-native` | Cross-platform UI | | `zod` | Shared schemas | These exact module specifiers use the host's runtime instances. A client bundle that requests another host module fails with `Module "" is not available in plugin client code`. Do not import `lucide-react-native`, `react-native-svg`, or DOM libraries. Set contribution `icon` fields to a [Lucide icon name](https://lucide.dev/icons/); Paseo validates the name and renders the icon. ### Cross-platform rules Client code runs on iOS, Android, and in browsers through React Native Web. A component that works in your browser and crashes on a phone is the most common plugin bug. The rules: | Do | Do not | | -------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | `View`, `Text`, `Pressable`, `ScrollView`, `TextInput` from `react-native` | `
`, ``, `