--- title: TypeScript Plugin (Experimental) label: TypeScript Plugin order: 30 desc: IDE support for PayloadComponent import paths – inline validation, autocomplete, and go-to-definition. keywords: headless cms, typescript, documentation, ide, plugin, autocomplete, validation, import paths --- **Experimental** — This plugin is experimental and may change in future releases. Please [report any issues](https://github.com/payloadcms/payload/issues) you encounter. Payload ships an optional TypeScript Language Service Plugin (`@payloadcms/typescript-plugin`) that enhances your IDE experience when working with [Custom Components](../custom-components/overview). It understands Payload's `PayloadComponent` import path conventions and provides: - **Path validation** — red squigglies when a component path doesn't resolve to a real file - **Export validation** — errors when the named export doesn't exist in the target module, with "Did you mean?" suggestions - **Autocomplete** — file and directory suggestions while typing the path, and export name suggestions after `#` - **Go-to-definition** — Ctrl/Cmd+click on a component path string to jump to the component's source ## Installation Install the plugin as a dev dependency: ```bash pnpm add -D @payloadcms/typescript-plugin ``` Then add it to the `plugins` array in your `tsconfig.json`: ```json { "compilerOptions": { "plugins": [{ "name": "next" }, { "name": "@payloadcms/typescript-plugin" }] } } ``` ### VS Code / Cursor Setup TypeScript language service plugins only load when the editor uses the **workspace version** of TypeScript (the one installed in your project's `node_modules`). By default, VS Code uses its own bundled version which won't load the plugin. To switch: open the command palette (`Cmd+Shift+P`) and run **"TypeScript: Select TypeScript Version"**, then choose **"Use Workspace Version"**. For teams, add the following to `.vscode/settings.json` so everyone is prompted to switch: ```json { "typescript.tsdk": "node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true } ``` After selecting the workspace version, restart the TypeScript server (`Cmd+Shift+P` → "TypeScript: Restart TS Server"). TypeScript Language Service Plugins only run inside your IDE. They do not affect `tsc` compilation or your build output. ## Supported Path Conventions The plugin supports all of Payload's component path formats: | Format | Example | Resolution | | ----------------------- | ---------------------------------- | ------------------------------ | | Absolute (from baseDir) | `'/components/MyField#MyField'` | Resolved relative to `baseDir` | | Relative | `'./components/MyField#MyField'` | Resolved relative to `baseDir` | | tsconfig alias | `'@/components/MyField#MyField'` | Resolved via tsconfig `paths` | | Package import | `'@payloadcms/ui/rsc#MyComponent'` | Resolved via node_modules | | Default export | `'/components/MyField'` | Uses `default` export | Both the **string form** and the **object form** are supported: ```ts // String form { admin: { components: { Field: '/components/MyField#MyField', } } } // Object form { admin: { components: { Field: { path: '/components/MyField', exportName: 'MyField', } } } } ``` ## Configuration ### Base Directory The plugin automatically detects `baseDir` by walking up from the current file to find the nearest `payload.config.ts`. Absolute paths (starting with `/`) and relative paths (starting with `./`) are resolved relative to this directory. If your project uses a non-standard layout, you can override `baseDir` in the plugin config: ```json { "compilerOptions": { "plugins": [ { "name": "@payloadcms/typescript-plugin", "baseDir": "./src" } ] } } ``` The `baseDir` path is relative to the `tsconfig.json` location. ## How It Works The plugin detects `PayloadComponent` positions by checking the contextual type of string literals in your config. Any string typed as `PayloadComponent`, `CustomComponent`, or any type that resolves to the same `false | RawPayloadComponent | string` union shape is automatically validated. This means the plugin works everywhere Payload expects a component path — collection field components, global components, admin panel components, dashboard widgets, and custom views — without needing to hardcode specific config positions.