How to migrate from CKEditor to SynapEditor

migrate from ckeditor to synapeditor.png

Switching rich text editors sounds like a big job, but most of the work is a straightforward, one-to-one swap. This guide gives you the step-by-step instructions to move an existing CKEditor 5 integration over to SynapEditor — from loading the library, through the toolbar and content APIs, to a complete working example you can copy and run.

Which is better – CKEditor or SynapEditor?

Both CKEditor and SynapEditor deserve recognition. They are mature, capable editors, and if you already have CKEditor running, it clearly does a lot right. So the question isn't really "which is better" in the abstract — it's which one fits where your product is heading.

Two differences tend to drive the decision:

  • Licensing and support. CKEditor 4 reached end of life in 2023, and security fixes now sit behind a paid Extended Support agreement. If you're revisiting the integration anyway, it's a natural moment to reconsider the editor itself.
  • Office documents. This is where SynapEditor stands apart. It imports a broad range of office formats — MS Word (.doc, .docx), PowerPoint (.ppt, .pptx), Excel (.xls, .xlsx), HWP/HWPX, ODT, and HTML — and exports to Word (.docx) with formatting preserved. If your users upload real documents and expect the layout to survive, that capability is hard to replicate with a general-purpose web editor.

If you want a deeper feature-by-feature look, see the SynapEditor feature pages. Otherwise, let's migrate.

How to migrate from CKEditor 5 to SynapEditor

1. Start with the installation

CKEditor 5 loads from a single script. SynapEditor loads from a script and a stylesheet — the UI is styled by that CSS, so both tags are required.

CKEditor Code

<div id="editor"></div>
<script src="https://cdn.ckeditor.com/ckeditor5/xx.x.x/classic/ckeditor.js"></script>
<script>
  ClassicEditor.create(document.querySelector('#editor'));
</script>

SynapEditor Code

<div style="width: 100%; height: 700px; margin: 0 auto;">
  <div id="synapEditor"></div>
</div>
<script src="https://cdn.synapeditor.com/latest/synapeditor.min.js"></script>
<link rel="stylesheet" href="https://cdn.synapeditor.com/latest/synapeditor.min.css">
<script>
  var config = {
    'editor.license': {
      company: 'YOUR_COMPANY',
      key: ['YOUR_LICENSE_KEY']
    },
    'editor.license.load.api': {
      url: 'https://www.synapeditor.com/api/v1/load-check',
      apiKey: 'YOUR_API_KEY'
    }
  };

  var editor = new SynapEditor('synapEditor', config);
</script>

Two things to note about SynapEditor here:

  • Construction is synchronous. new SynapEditor(...) returns the instance immediately — there is no Promise to .then() like CKEditor 5's create().
  • The license is required and is an object, not a string — a company name and a key array. Every other config key is optional; leave it out and the editor uses a sensible built-in default.

Most SynapEditor licenses also require a server-side validation call, so you'll set editor.license.load.api alongside editor.license. You can issue both the license and its API key at Get Started.

2. Toolbar options

Both editors build the toolbar from a list of button names, so this step is mostly translating names. In SynapEditor, the toolbar is set through the editor.toolbar config key.

CKEditor Code

ClassicEditor.create(document.querySelector('#editor'), {
  toolbar: ['bold', 'italic', 'underline', '|', 'numberedList', 'bulletedList']
});

SynapEditor Code

// The license can be defined separately and managed apart from your feature config
var synapEditorLicense = {
  'editor.license': {
    company: 'YOUR_COMPANY',
    key: ['YOUR_LICENSE_KEY']
  },
  'editor.license.load.api': {
    url: 'https://www.synapeditor.com/api/v1/load-check',
    apiKey: 'YOUR_API_KEY'
  }
};

var config = {
  'editor.toolbar': [
    'bold', 'italic', 'underline', '|',
    'numberedList', 'bulletList'
  ]
};

// Merge the two when you create the editor
var editor = new SynapEditor('synapEditor', Object.assign({}, synapEditorLicense, config));

Keeping the license in its own object and merging it with Object.assign at creation time keeps the key in one place — out of your page-level config, and easy to share across pages or swap per environment. In the editor.toolbar array, '|' inserts a separator inside a row and '-' forces a line break onto a new row. There's also a separate 'editor.mobile.toolbar' config for touch devices, grouped into main, text, table, div, image, and video sections.

3. Handle content and events

The last piece is reading and writing content and reacting to edits. The method names differ from CKEditor, so this is the part to search-and-replace carefully.

CKEditor Code

// Read and write
var html = editor.getData();
editor.setData('<p>New content</p>');

// React to edits
editor.model.document.on('change:data', function () {
  console.log('Content changed');
});

SynapEditor Code

// Read and write
var html = editor.getPublishingHtml();
editor.openHTML('<p>New content</p>');

// React to edits
editor.setEventListener('afterEdit', function () {
  console.log('Content changed');
});

You can also register listeners up front by passing them as the fourth constructor argument — see the complete example below.

A quick reference for the calls you're most likely to port:

TaskCKEditor 5SynapEditor
Read contenteditor.getData()editor.getPublishingHtml()
Write contenteditor.setData(html)editor.openHTML(html)
Insert at cursoreditor.model.insertContent(...)editor.insertHTML(html)
Content changedchange:dataafterEdit
Run a built-in commandeditor.execute('bold')editor.execCommand('bold')
Read-only on / offenableReadOnlyMode(id) / disable…editor.setMode('readonly') / setMode('edit')
Destroyeditor.destroy()editor.destroy()

Complete example

Here is a full, runnable page — the CKEditor equivalent ported to SynapEditor.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <script src="https://cdn.synapeditor.com/latest/synapeditor.min.js"></script>
  <link rel="stylesheet" href="https://cdn.synapeditor.com/latest/synapeditor.min.css">
</head>
<body>
  <div style="width: 100%; height: 700px; margin: 0 auto;">
      <div id="synapEditor"></div>
  </div>

  <script>
    var config = {
      'editor.license': {
        company: 'YOUR_COMPANY',
        key: ['YOUR_LICENSE_KEY']
      },
      'editor.license.load.api': {
        url: 'https://www.synapeditor.com/api/v1/load-check',
        apiKey: 'YOUR_API_KEY'
      }
    };

    var html = '<p>Initial content</p>';

    var eventListeners = {
      'initialized': function () {
        console.log('Editor is ready');
      },
      'afterEdit': function () {
        console.log('Content changed');
      }
    };

    var editor = new SynapEditor('synapEditor', config, html, eventListeners);
  </script>
</body>
</html>

Want to see it running before you wire it up? Try the live editor on the SynapEditor demo page.

Ready to build? Head to Get Started to grab your license and API keys and stand up a local development environment in minutes.