From 6171a6837686b4f54d1ebfed6c79e9c02fb60e4d Mon Sep 17 00:00:00 2001 From: Vishal Kumar Singh Date: Wed, 6 May 2026 11:48:41 +0530 Subject: [PATCH 1/3] docs(plugins-development): document tsconfig setup for local TypeScript plugins (#3025) --- .../plugins-development/create-a-plugin.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docusaurus/docs/cms/plugins-development/create-a-plugin.md b/docusaurus/docs/cms/plugins-development/create-a-plugin.md index 4d8cf29c07..4cc7ab65c9 100644 --- a/docusaurus/docs/cms/plugins-development/create-a-plugin.md +++ b/docusaurus/docs/cms/plugins-development/create-a-plugin.md @@ -237,6 +237,31 @@ export default { This object includes methods to register your plugin with the admin application, perform bootstrapping actions, and handle translations. For more details, please refer to the [Admin Panel API reference](/cms/plugins-development/admin-panel-api). +### TypeScript configuration + +For a TypeScript local plugin, the project-level TypeScript configuration handles compilation, so you do not need a per-plugin `tsconfig.json` once you are using the `strapi-server.ts` / `strapi-admin.ts` entry points described above. Two pieces have to be in place: + +1. **Server-side compilation** is delegated to the project's root `./tsconfig.json`. The default Strapi configuration already excludes `src/plugins/**`, which is what you want here: the plugin's server-side TypeScript is then compiled by the project's regular build pipeline. +2. **Admin-side compilation** (including `.tsx` files for components) is handled by `./src/admin/tsconfig.json`, which extends `@strapi/typescript-utils/tsconfigs/admin` and is the file responsible for JSX. Make sure its `include` array picks up your plugin's admin sources, for example by adding `../plugins/**/admin/src/**/*`: + +```json title="./src/admin/tsconfig.json" +{ + "extends": "@strapi/typescript-utils/tsconfigs/admin", + "include": [ + "../plugins/**/admin/src/**/*", + "./" + ], + "exclude": [ + "node_modules/", + "build/", + "dist/", + "**/*.test.ts" + ] +} +``` + +Without that `include` entry, admin TypeScript files in the plugin compile under the server-side `tsconfig.json` and produce errors such as `TS6142: ... but --jsx is not set` and `TS2307: Cannot find module @strapi/strapi/admin or its corresponding type declarations`. As noted in [Configuration with a local plugin](#configuration-with-a-local-plugin), do not add `@strapi/strapi` as a dev dependency inside the plugin: it should use the same instance of `@strapi/strapi` as the main application. + :::tip For a complete example of how to structure your local plugin in a monorepo environment, please check out our . ::: \ No newline at end of file From dca15f30bd75a07d0cb112d90041b01d5cb7287c Mon Sep 17 00:00:00 2001 From: Vishal Kumar Singh Date: Wed, 6 May 2026 16:33:54 +0530 Subject: [PATCH 2/3] docs(plugins-development): clarify root tsc scope vs plugin server entry (#3025) --- docusaurus/docs/cms/plugins-development/create-a-plugin.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/plugins-development/create-a-plugin.md b/docusaurus/docs/cms/plugins-development/create-a-plugin.md index 4cc7ab65c9..100370a84c 100644 --- a/docusaurus/docs/cms/plugins-development/create-a-plugin.md +++ b/docusaurus/docs/cms/plugins-development/create-a-plugin.md @@ -239,9 +239,9 @@ This object includes methods to register your plugin with the admin application, ### TypeScript configuration -For a TypeScript local plugin, the project-level TypeScript configuration handles compilation, so you do not need a per-plugin `tsconfig.json` once you are using the `strapi-server.ts` / `strapi-admin.ts` entry points described above. Two pieces have to be in place: +For a TypeScript local plugin you usually keep a single project-level setup instead of adding another `tsconfig.json` inside each plugin, once the `strapi-server.ts` / `strapi-admin.ts` exports from the earlier sections are in place. Two pieces have to be in place: -1. **Server-side compilation** is delegated to the project's root `./tsconfig.json`. The default Strapi configuration already excludes `src/plugins/**`, which is what you want here: the plugin's server-side TypeScript is then compiled by the project's regular build pipeline. +1. **Root `./tsconfig.json` covers the host app's server TypeScript only.** `strapi develop` calls `@strapi/typescript-utils/compile`, which drives `tsc` using that file. Official templates intentionally `exclude` `src/plugins/**`, and the `create-strapi-app` starter labels that as keeping plugins out of the server compilation pass, which means those paths are not part of the root `tsc` emit graph. At runtime Strapi still loads each plugin's `strapi-server.js` through `loadPlugins` in `packages/core/core/src/loaders/plugins/index.ts`, so any server TypeScript still has to arrive as the `.js` entrypoint Node can `require` (the stock `examples/getstarted` local plugin ships `strapi-server.js`, or you add a small plugin-local build / SDK packaging step if you author `.ts`). 2. **Admin-side compilation** (including `.tsx` files for components) is handled by `./src/admin/tsconfig.json`, which extends `@strapi/typescript-utils/tsconfigs/admin` and is the file responsible for JSX. Make sure its `include` array picks up your plugin's admin sources, for example by adding `../plugins/**/admin/src/**/*`: ```json title="./src/admin/tsconfig.json" From 335e18e647aae19abce46a45d988eac2b34cb820 Mon Sep 17 00:00:00 2001 From: Vishal Kumar Singh Date: Wed, 6 May 2026 16:52:45 +0530 Subject: [PATCH 3/3] docs(plugins-development): document narrow root exclude for plugin server TS (#3025) --- .../cms/plugins-development/create-a-plugin.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docusaurus/docs/cms/plugins-development/create-a-plugin.md b/docusaurus/docs/cms/plugins-development/create-a-plugin.md index 100370a84c..9b9a2c498f 100644 --- a/docusaurus/docs/cms/plugins-development/create-a-plugin.md +++ b/docusaurus/docs/cms/plugins-development/create-a-plugin.md @@ -239,10 +239,9 @@ This object includes methods to register your plugin with the admin application, ### TypeScript configuration -For a TypeScript local plugin you usually keep a single project-level setup instead of adding another `tsconfig.json` inside each plugin, once the `strapi-server.ts` / `strapi-admin.ts` exports from the earlier sections are in place. Two pieces have to be in place: +These notes apply when you follow the `strapi-server.ts` / `strapi-admin.ts` entry points from the earlier sections and keep TypeScript sources in the app plus local plugin folders instead of adding another `tsconfig.json` inside every plugin. -1. **Root `./tsconfig.json` covers the host app's server TypeScript only.** `strapi develop` calls `@strapi/typescript-utils/compile`, which drives `tsc` using that file. Official templates intentionally `exclude` `src/plugins/**`, and the `create-strapi-app` starter labels that as keeping plugins out of the server compilation pass, which means those paths are not part of the root `tsc` emit graph. At runtime Strapi still loads each plugin's `strapi-server.js` through `loadPlugins` in `packages/core/core/src/loaders/plugins/index.ts`, so any server TypeScript still has to arrive as the `.js` entrypoint Node can `require` (the stock `examples/getstarted` local plugin ships `strapi-server.js`, or you add a small plugin-local build / SDK packaging step if you author `.ts`). -2. **Admin-side compilation** (including `.tsx` files for components) is handled by `./src/admin/tsconfig.json`, which extends `@strapi/typescript-utils/tsconfigs/admin` and is the file responsible for JSX. Make sure its `include` array picks up your plugin's admin sources, for example by adding `../plugins/**/admin/src/**/*`: +1. **Admin-side compilation** lives in `./src/admin/tsconfig.json`, which extends `@strapi/typescript-utils/tsconfigs/admin` and owns JSX settings. Add your plugin admin tree to `include`, for example `../plugins/**/admin/src/**/*`, so `.tsx` files are not parsed under the server program (which produces `TS6142` / missing `@strapi/strapi/admin` type errors otherwise). ```json title="./src/admin/tsconfig.json" { @@ -260,7 +259,15 @@ For a TypeScript local plugin you usually keep a single project-level setup inst } ``` -Without that `include` entry, admin TypeScript files in the plugin compile under the server-side `tsconfig.json` and produce errors such as `TS6142: ... but --jsx is not set` and `TS2307: Cannot find module @strapi/strapi/admin or its corresponding type declarations`. As noted in [Configuration with a local plugin](#configuration-with-a-local-plugin), do not add `@strapi/strapi` as a dev dependency inside the plugin: it should use the same instance of `@strapi/strapi` as the main application. +2. **Server-side TypeScript** can follow either of these layouts: + + - **Starter-default path:** keep the generated root `exclude` entry for `src/plugins/**`. The root `tsc` pass that `strapi develop` runs through `@strapi/typescript-utils/compile` will not emit plugin server sources, so you ship a runtime `strapi-server.js` next to the plugin `package.json` (see `examples/getstarted`) or run a **dedicated compile step** inside the plugin that outputs that file before boot. + + - **Monorepo path without a second server bundler:** narrow the root exclude list so only admin assets stay out of the server program, for example replace `src/plugins/**` with `src/plugins/**/admin`. Root `tsc` can then emit `src/plugins//server/**/*.ts` into `dist/`, and your plugin `package.json` `exports["./strapi-server"].require` can target that emitted file. A worked example lives in the Strapi community repo: . Double-check `rootDir`, `outDir`, and Strapi upgrades whenever you diverge from the default template. + +Regardless of which server path you pick, runtime resolution still flows through `loadPlugins` in Strapi core, which ultimately `require`s the `strapi-server` export your `package.json` exposes. + +Without the admin `include` line from step 1, admin TypeScript files in the plugin compile under the server-side `tsconfig.json` and produce errors such as `TS6142: ... but --jsx is not set` and `TS2307: Cannot find module @strapi/strapi/admin or its corresponding type declarations`. As noted in [Configuration with a local plugin](#configuration-with-a-local-plugin), do not add `@strapi/strapi` as a dev dependency inside the plugin: it should use the same instance of `@strapi/strapi` as the main application. :::tip For a complete example of how to structure your local plugin in a monorepo environment, please check out our .