diff --git a/app/components/elements/ReplyEditor.jsx b/app/components/elements/ReplyEditor.jsx
index 83b2e33af76467a7632609ccc63facd18d8ce450..c3b5dfdef146e07fef63938c05ee82c2cba47390 100644
--- a/app/components/elements/ReplyEditor.jsx
+++ b/app/components/elements/ReplyEditor.jsx
@@ -15,16 +15,16 @@ import {Set} from 'immutable'
 import {cleanReduxInput} from 'app/utils/ReduxForms'
 import Remarkable from 'remarkable'
 import {serverApiRecordEvent} from 'app/utils/ServerApiClient';
+import SlateEditor, {serializeHtml, deserializeHtml, getDemoState} from 'app/components/elements/SlateEditor'
 
 const remarkable = new Remarkable({ html: true, linkify: false })
-const RichTextEditor = process.env.BROWSER ? require('react-rte-image').default : null;
 const RTE_DEFAULT = false
 
 let saveEditorTimeout
 
 // removes <html></html> wrapper if exists
 function stripHtmlWrapper(text) {
-    const m = text.match(/<html>\n?([\S\s]+?)\n?<\/html>/m);
+    const m = text.match(/<html>\n*([\S\s]+?)?\n*<\/html>/m);
     return m && m.length === 2 ? m[1] : text;
 }
 
@@ -45,17 +45,16 @@ const isHtmlTest = text =>
     /^<p>[\S\s]*<\/p>/.test(text)
 
 function stateToHtml(state) {
-    let html = state.toString('html');
+    let html = serializeHtml(state)
     if (html === '<p></p>') html = '';
     if (html === '<p><br></p>') html = '';
     return html
 }
 
 function stateFromHtml(html = null) {
-    if(!RichTextEditor) return null;
     if(html && html.trim() == '') html = null
-    return html ? RichTextEditor.createValueFromString(html, 'html')
-                : RichTextEditor.createEmptyValue()
+    return html ? deserializeHtml(html)
+                : getDemoState()
 }
 
 class ReplyEditor extends React.Component {
@@ -163,6 +162,7 @@ class ReplyEditor extends React.Component {
                 if(rte) html = stripHtmlWrapper(html)
             }
 
+            console.log("initial reply body:", html || '(empty)')
             body.onChange(html)
             this.setState({
                 rte,
@@ -200,7 +200,7 @@ class ReplyEditor extends React.Component {
 
                 clearTimeout(saveEditorTimeout)
                 saveEditorTimeout = setTimeout(() => {
-                    // console.log('save formId', formId, JSON.stringify(data, null, 0))
+                    console.log('save formId', formId, JSON.stringify(data, null, 0))
                     localStorage.setItem('replyEditorData-' + formId, JSON.stringify(data, null, 0))
                 }, 350)
             }
@@ -308,11 +308,9 @@ class ReplyEditor extends React.Component {
                                 </div>
                             }
                             {process.env.BROWSER && rte ?
-                                <RichTextEditor ref="rte"
-                                    readOnly={loading}
-                                    value={this.state.rte_value}
-                                    onChange={this.onChange}
-                                    onBlur={body.onBlur} tabIndex={2} />
+                                <SlateEditor ref="rte"
+                                    initialState={this.state.rte_value}
+                                    onChange={this.onChange} />
                                 :
                                 <textarea {...cleanReduxInput(body)} disabled={loading} rows={isStory ? 10 : 3} placeholder={isStory ? 'Write your story...' : 'Reply'} autoComplete="off" ref="postRef" tabIndex={2} />
                             }
diff --git a/package.json b/package.json
index 00bc7a045948a556f8b1ce687184b0c176c781a7..be2cc7d384b123c897d3df60b3f1c78e1ea1709a 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,7 @@
     "react-intl": "^2.1.3",
     "react-medium-editor": "^1.8.0",
     "react-notification": "^5.0.7",
-    "react-overlays": "0.6.4",
+    "react-overlays": "0.6.10",
     "react-portal": "^2.2.1",
     "react-prop-types": "^0.3.0",
     "react-qr": "0.0.2",