{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "typescript-docs",
  "title": "TypeScript",
  "description": "Configure TypeScript (tsconfig) for using Plate, including module resolution solutions.",
  "files": [
    {
      "path": "../../content/docs/(guides)/typescript.mdx",
      "content": "---\ntitle: TypeScript\ndescription: Configure TypeScript (tsconfig) for using Plate, including module resolution solutions.\n---\n\nPlate provides ESM packages, which require certain TypeScript (and bundler) configurations to ensure compatibility, especially when importing subpath modules like `platejs/react`. Below are several solutions and workarounds to make TypeScript happy.\n\n## Quick Summary\n\n1. **Recommended (Easiest):** Use TypeScript **5.0+** and set `\"moduleResolution\": \"bundler\"` in your `tsconfig.json`.\n2. **Alternate (Node resolution):** Keep `\"moduleResolution\": \"node\"` and map paths to `dist/react` (and potentially alias them in your bundler config).\n3. **Up-to-date Packages:** Use `depset` to upgrade Plate dependencies.\n\n\n## Recommended: `\"moduleResolution\": \"bundler\"`\n\nThe simplest approach for modern bundlers (Vite, Next.js 14, etc.) is to enable the new TypeScript \"bundler\" resolution mode. Example:\n\n```jsonc\n// tsconfig.json\n{\n  \"compilerOptions\": {\n    // ...\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"bundler\",\n    // ...\n  }\n}\n```\n\nThis aligns TypeScript's resolution logic more closely with modern bundlers and ESM packages. Below is a working excerpt from [Plate template](https://github.com/udecode/plate-template):\n\n```jsonc\n{\n  \"compilerOptions\": {\n    \"strict\": false,\n    \"strictNullChecks\": true,\n    \"allowUnusedLabels\": false,\n    \"allowUnreachableCode\": false,\n    \"exactOptionalPropertyTypes\": false,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitOverride\": true,\n    \"noImplicitReturns\": false,\n    \"noPropertyAccessFromIndexSignature\": false,\n    \"noUncheckedIndexedAccess\": false,\n    \"noUnusedLocals\": false,\n    \"noUnusedParameters\": false,\n\n    \"isolatedModules\": true,\n\n    \"allowJs\": true,\n    \"checkJs\": false,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"jsx\": \"preserve\",\n    \"module\": \"esnext\",\n    \"target\": \"es2022\",\n    \"moduleResolution\": \"bundler\",\n    \"moduleDetection\": \"force\",\n    \"resolveJsonModule\": true,\n    \"noEmit\": true,\n    \"incremental\": true,\n    \"sourceMap\": true,\n\n    \"baseUrl\": \"src\",\n    \"paths\": {\n      \"@/*\": [\"./*\"]\n    }\n  },\n  \"include\": [\n    \"next-env.d.ts\",\n    \".next/types/**/*.ts\",\n    \"src/**/*.ts\",\n    \"src/**/*.tsx\"\n  ],\n  \"exclude\": [\"node_modules\"]\n}\n```\n\n- **`\"moduleResolution\": \"bundler\"`** was introduced in TypeScript 5.0.\n- If your TS version is older than 5.0, you **must** upgrade or stick to `\"moduleResolution\": \"node\"` plus manual path aliases.\n\n```jsonc\n// package.json\n{\n  \"devDependencies\": {\n    \"typescript\": \"^5.0.0\"\n  }\n}\n```\n\nIf you see an error like `TS5023: Unknown compiler option 'moduleResolution'` (for `bundler`), it likely means your TypeScript version is below 5.0.\n\n## Workaround: `\"moduleResolution\": \"node\"` + Path Aliases\n\nIf upgrading your entire project to TS 5.0 or changing the resolution mode is not possible:\n\n1. Keep `\"moduleResolution\": \"node\"`.\n2. Map each Plate subpath import to its `dist/react` types in `tsconfig.json` using `paths`.\n3. Alias these paths in your bundler config.\n\n### Example `tsconfig.json`\n\n```jsonc\n{\n  \"compilerOptions\": {\n    \"moduleResolution\": \"node\",\n    \"paths\": {\n      \"platejs/react\": [\n        \"./node_modules/platejs/dist/react/index.d.ts\"\n      ],\n      \"@platejs/core/react\": [\n        \"./node_modules/@platejs/core/dist/react/index.d.ts\"\n      ],\n      \"@platejs/list/react\": [\n        \"./node_modules/@platejs/list/dist/react/index.d.ts\"\n      ]\n      // ...repeat for all @platejs/*/react packages\n    }\n  }\n}\n```\n\n### Example `vite.config.ts`\n\n```ts\nimport { defineConfig } from 'vite';\nimport path from 'path';\n\nexport default defineConfig({\n  resolve: {\n    alias: {\n      'platejs/react': path.resolve(\n        __dirname,\n        'node_modules/platejs/dist/react'\n      ),\n      '@platejs/core/react': path.resolve(\n        __dirname,\n        'node_modules/@platejs/core/dist/react'\n      ),\n      '@platejs/list/react': path.resolve(\n        __dirname,\n        'node_modules/@platejs/list/dist/react'\n      ),\n\n      // Non-/react base aliases:\n      'platejs': path.resolve(\n        __dirname,\n        'node_modules/platejs'\n      ),\n      '@platejs/core': path.resolve(\n        __dirname,\n        'node_modules/@platejs/core'\n      ),\n      '@platejs/list': path.resolve(\n        __dirname,\n        'node_modules/@platejs/list'\n      )\n    }\n  }\n});\n```\n\n**Note:**\n- You must do this for every `@platejs/*/react` import you use.  \n- For testing/Jest, replicate these aliases via `moduleNameMapper` or similar.\n\n## Ensure Matching Plate Versions\n\nSay you're upgrading one package to `52.0.1`, double-check that all your `platejs*` packages are on the **latest version up to `52.0.1`** (one package could stay at `52.0.0` if it has no `52.0.1` release). Mixing versions often leads to mismatches.\n\nTo easily manage and synchronize your `platejs*` package versions, you can use the `depset` CLI. For example, to ensure all your `@platejs/*` scope packages are aligned to the latest compatible with version `52.x.y`:\n\n```bash\nnpx depset@latest @platejs 52 && npx depset@latest platejs 52\n```\n\nOr, for a specific version like `52.0.1` (this will set all packages in the scope to `52.0.1` if available, or the latest before it if not):\n\n```bash\nnpx depset@latest @platejs 52.0.1 && npx depset@latest platejs 52.0.1\n```\n\nThis helps prevent version conflicts by ensuring all related Plate packages are on compatible versions.\n\n## FAQ\n\n> I updated `moduleResolution` to `bundler` but it broke my older imports.\"\n\nIf your codebase has older TS usage or relies on `node` resolution, try the path alias approach or fully migrate to a TS 5+ / ESM environment.\n\n> \"I'm seeing `TS2305` about missing exports. Is that a resolution error or a real missing export?\"  \n\nIt can be either:\n- If the entire package is \"not found,\" it's likely a resolution issue.  \n- If it's specifically \"no exported member,\" double-check that you spelled the import correctly (no typos) and that your installed version actually has that export.\n\n> \"Which minimum TS version do I need for `moduleResolution: bundler`?\"  \n\nTypeScript 5.0 or higher.\n\n> \"We switched to bundler resolution, but some older libraries in our project break.\"  \n\nIf your older libraries aren't ESM-friendly, you might stick to `node` resolution and do manual path aliases. Some large codebases gradually upgrade or create separate build pipelines for legacy code.\n\n> \"We see the error in Jest but not in Vite.\"  \n\nYou'll need to replicate your alias/resolution changes for Jest. For example:\n\n```js\n// jest.config.js\nmodule.exports = {\n  // ...\n  moduleNameMapper: {\n    '^platejs/react$': '<rootDir>/node_modules/platejs/dist/react',\n    '^@platejs/core/react$': '<rootDir>/node_modules/@platejs/core/dist/react',\n    // ...\n  }\n};\n```\n",
      "type": "registry:file",
      "target": "content/docs/plate/(guides)/typescript.mdx"
    }
  ],
  "type": "registry:file"
}