{"id":12147,"library":"tinymce","title":"TinyMCE Rich Text Editor","description":"TinyMCE is a powerful, open-source JavaScript HTML WYSIWYG editor control that enables rich text editing capabilities directly within web applications. As of April 2026, the current stable version is 8.4.0, with TinyMCE 8 being the recommended branch for continued security updates and active development. The library maintains a consistent release cadence, frequently pushing updates and patches. TinyMCE differentiates itself as one of the most widely used and customizable editors globally, boasting over 350 million downloads annually and powering millions of products. It offers an extensive API with over 400 options, more than 50 plugins, and support for three distinct editing modes: classic, inline, and distraction-free. Its flexibility allows developers to configure the UI and functionality to match specific application needs, from simple text areas to complex document editors. TinyMCE is known for its scalability and enterprise-grade features, making it a robust choice for projects requiring advanced content creation and management tools. It provides integrations for popular frameworks like React, Vue, and Angular via dedicated wrapper packages.","status":"active","version":"8.4.0","language":"javascript","source_language":"en","source_url":"https://github.com/tinymce/tinymce","tags":["javascript","wysiwyg","tinymce","richtext","html","text","rich editor","rich text editor","typescript"],"install":[{"cmd":"npm install tinymce","lang":"bash","label":"npm"},{"cmd":"yarn add tinymce","lang":"bash","label":"yarn"},{"cmd":"pnpm add tinymce","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Primary import for modern ESM-compatible projects. While CommonJS `require` might work in some environments, it's generally discouraged for new development targeting bundlers.","wrong":"const tinymce = require('tinymce');","symbol":"tinymce","correct":"import tinymce from 'tinymce';"},{"note":"The `init` method is the core function for initializing an editor instance and is a property of the imported `tinymce` object. It should not be called globally unless TinyMCE is loaded as a global script.","wrong":"init({ /* settings */ });","symbol":"tinymce.init","correct":"tinymce.init({ /* settings */ });"},{"note":"For type-only imports in TypeScript, use `import type` to ensure they are stripped from the JavaScript output, preventing accidental runtime imports.","wrong":"import { EditorOptions } from 'tinymce';","symbol":"EditorOptions (TypeScript)","correct":"import type { EditorOptions } from 'tinymce';"},{"note":"When using TinyMCE via npm, plugins, themes, and icons are typically imported directly to be included in the bundle, rather than being dynamically loaded at runtime (though dynamic loading is also an option).","wrong":"tinymce.PluginManager.require('link');","symbol":"Specific plugins/themes/icons","correct":"import 'tinymce/themes/silver';\nimport 'tinymce/plugins/link';"}],"quickstart":{"code":"import tinymce from 'tinymce';\nimport 'tinymce/themes/silver';\nimport 'tinymce/icons/default';\nimport 'tinymce/plugins/advlist';\nimport 'tinymce/plugins/autolink';\nimport 'tinymce/plugins/lists';\nimport 'tinymce/plugins/link';\nimport 'tinymce/plugins/image';\nimport 'tinymce/plugins/charmap';\nimport 'tinymce/plugins/preview';\nimport 'tinymce/plugins/anchor';\nimport 'tinymce/plugins/searchreplace';\nimport 'tinymce/plugins/visualblocks';\nimport 'tinymce/plugins/code';\nimport 'tinymce/plugins/fullscreen';\nimport 'tinymce/plugins/insertdatetime';\nimport 'tinymce/plugins/media';\nimport 'tinymce/plugins/table';\nimport 'tinymce/plugins/help';\nimport 'tinymce/plugins/wordcount';\n\n// Ensure the DOM is fully loaded before initializing TinyMCE\ndocument.addEventListener('DOMContentLoaded', () => {\n  const textarea = document.createElement('textarea');\n  textarea.id = 'mytextarea';\n  textarea.value = '<p>Hello, <strong>TinyMCE</strong>!</p>';\n  document.body.appendChild(textarea);\n\n  tinymce.init({\n    selector: '#mytextarea',\n    plugins: 'advlist autolink lists link image charmap preview anchor searchreplace visualblocks code fullscreen insertdatetime media table help wordcount',\n    toolbar: 'undo redo | formatselect | bold italic backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | help',\n    menubar: 'file edit view insert format tools table help',\n    height: 500,\n    // Replace process.env.TINYMCE_API_KEY with your actual TinyMCE cloud API key for cloud deployments\n    // For self-hosted, this setting is not required unless using specific cloud services.\n    // If using the cloud CDN, ensure to load the script <script src=\"https://cdn.tiny.cloud/1/{YOUR_API_KEY}/tinymce/8/tinymce.min.js\"></script>\n    // and provide the key here: api_key: process.env.TINYMCE_API_KEY ?? ''\n  });\n});","lang":"typescript","description":"This quickstart demonstrates how to initialize TinyMCE in a web application using npm imports for the core, themes, and common plugins, setting up a basic editor on a dynamically created textarea. It includes typical toolbar and menubar configurations."},"warnings":[{"fix":"Review the official TinyMCE 8 migration guides and upgrade your project dependencies. Be aware of potential API changes and necessary configuration adjustments.","message":"Older versions of TinyMCE (pre-v8) are no longer receiving security updates or active maintenance. It is strongly recommended to upgrade to TinyMCE 8 to ensure access to critical security patches and ongoing support.","severity":"breaking","affected_versions":"<8.0.0"},{"fix":"Register for a free or paid API key at tiny.cloud and include it in your `tinymce.init` configuration (`api_key: 'YOUR_API_KEY'`) or ensure it's provided via the CDN URL.","message":"When deploying TinyMCE via their cloud service, an API key is mandatory. Without a valid API key, the editor will display a 'The API key is invalid' message or function with limitations.","severity":"gotcha","affected_versions":">=6.0.0"},{"fix":"Ensure all necessary assets are copied to your web server and that the `tinymce.init` configuration correctly specifies `skin_url`, `content_css`, and other relevant path options. When using npm, ensure your bundler (e.g., Webpack, Vite) is configured to handle asset imports and copying.","message":"Self-hosting TinyMCE requires careful management of asset paths (themes, skins, plugins, icons). Incorrect paths can lead to missing UI elements, non-functional plugins, or a broken editor interface.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"Optimize editor initialization by loading only necessary plugins, using a debounced input handler for large content, and considering lazy loading or chunking for extremely large documents if applicable.","message":"Performance can degrade with very large HTML content, numerous complex plugins, or highly customized UI components. This can manifest as slow initialization or sluggish editing experience.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"Review the TinyMCE feature matrix and licensing terms on tiny.cloud to understand which features are included in the open-source version and which require a subscription. Ensure your usage aligns with your licensing.","message":"While TinyMCE is open-source, certain advanced features or plugins are designated as 'premium' and require a paid license. Attempting to use these features without a valid license may result in watermarks, reduced functionality, or legal compliance issues.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"If using a script tag, ensure it's loaded before your initialization code, preferably at the end of `<body>` or using `defer`. If using npm, ensure `import tinymce from 'tinymce';` is at the top of your module and that `tinymce.init` is called after the DOM is ready (e.g., inside `DOMContentLoaded` event listener).","cause":"The TinyMCE script was not loaded, or the `tinymce` object was accessed before the script finished loading or before it was properly imported in an npm context.","error":"tinymce is not defined"},{"fix":"Verify that the plugin file exists at the expected path. If self-hosting, check `plugins` array in `tinymce.init` and ensure asset paths are correct. If bundling with npm, confirm the `import 'tinymce/plugins/[plugin_name]';` statement is present.","cause":"The specified plugin file could not be found or loaded. This often happens due to incorrect paths for self-hosted assets or missing imports in a bundled environment.","error":"Failed to load plugin: [plugin_name]"},{"fix":"Log in to tiny.cloud, verify your API key, and ensure your domain is correctly registered for that key. Update your `api_key` in `tinymce.init` or the CDN script URL if necessary.","cause":"The TinyMCE cloud API key provided is either incorrect, expired, or not authorized for the domain where the editor is being used.","error":"The API key is invalid or not registered for this domain."},{"fix":"Ensure that the HTML element specified by `selector` (e.g., '#mytextarea') exists in the DOM and is fully rendered before `tinymce.init()` is invoked. Wrap initialization in `document.addEventListener('DOMContentLoaded', ...)` or ensure it runs after the target element is present.","cause":"This can occur when the `selector` provided to `tinymce.init` does not match any existing DOM element, or the element is not yet available when `init` is called.","error":"TypeError: Cannot read properties of null (reading 'hasChildNodes')"}],"ecosystem":"npm"}