diff --git a/api/db/dev/.gitkeep b/api/db/dev/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/api/db/production/.gitkeep b/api/db/production/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/app/components/SimpleEditor/Editor.js b/app/components/SimpleEditor/Editor.js
index 181f7f5594fc6415c09908ec378bda354ece35d6..ac7e0183fa63d4abea6bff0ac80cd392e3123ab9 100644
--- a/app/components/SimpleEditor/Editor.js
+++ b/app/components/SimpleEditor/Editor.js
@@ -123,6 +123,7 @@ class Editor extends ProseEditor {
   _renderEditor ($$) {
     const configurator = this.props.configurator
     const editing = this.props.disabled ? 'selection' : 'full'
+
     return $$(ContainerEditor, {
       editing: editing,
       documentSession: this.documentSession,
diff --git a/app/components/SimpleEditor/config.js b/app/components/SimpleEditor/config.js
index 0a80dcf194e4564fff922d7266afbfc32a9c3749..dcc9e237af43a3d736a0633a0bdf4f1ec438e6e7 100644
--- a/app/components/SimpleEditor/config.js
+++ b/app/components/SimpleEditor/config.js
@@ -20,7 +20,11 @@ import CommentPackage from './elements/comment/CommentPackage'
 import ExtractPackage from './elements/extract/ExtractPackage'
 import NotePackage from './elements/note/NotePackage'
 import SourceNotePackage from './elements/source_note/SourceNotePackage'
+
 import TrackChangePackage from './elements/track_change/TrackChangePackage'
+
+import ImagePackage from './elements/images/ImagePackage'
+
 // var DialoguePackage = require('./elements/dialogue/DialoguePackage')
 // var NumberedListPackage = require('./elements/numbered_list/NumberedListPackage')
 // var NoStyleListPackage = require('./elements/no_style_list/NoStyleListPackage')
@@ -56,7 +60,9 @@ let config = {
     config.import(NotePackage)
     config.import(SourceNotePackage)
     config.import(CommentPackage)
+
     config.import(TrackChangePackage)
+    config.import(ImagePackage)
 
     // config.import(DialoguePackage)
     // config.import(NoStyleListPackage)
diff --git a/app/components/SimpleEditor/elements/elements.scss b/app/components/SimpleEditor/elements/elements.scss
index 8105d4e9a5bedf9f2a263c9ca88a12fdfd71413a..520be25da67394599e515f6a3e2a15481910a33f 100644
--- a/app/components/SimpleEditor/elements/elements.scss
+++ b/app/components/SimpleEditor/elements/elements.scss
@@ -7,4 +7,8 @@
 // @import './no_style_list/noStyleList';
 // @import './numbered_list/numberedList';
 @import './source_note/sourceNote';
+
 @import './track_change/trackChange';
+
+@import './images/image';
+@import './images/insert-image-tool';
diff --git a/app/components/SimpleEditor/elements/images/Image.js b/app/components/SimpleEditor/elements/images/Image.js
new file mode 100644
index 0000000000000000000000000000000000000000..67e4d8abf4b73a449bc378fdb6884b3514cefe5d
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/Image.js
@@ -0,0 +1,11 @@
+import { DocumentNode } from 'substance'
+
+class Image extends DocumentNode {}
+
+Image.define({
+  type: 'image',
+  src: { type: 'string', default: 'http://' },
+  previewSrc: { type: 'string', optional: true }
+})
+
+export default Image
diff --git a/app/components/SimpleEditor/elements/images/ImageComponent.js b/app/components/SimpleEditor/elements/images/ImageComponent.js
new file mode 100644
index 0000000000000000000000000000000000000000..30c6a73209b57e0b944f7afb2008289c806ed999
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/ImageComponent.js
@@ -0,0 +1,51 @@
+import { BlockNodeComponent } from 'substance'
+
+class ImageComponent extends BlockNodeComponent {
+
+  didMount () {
+    super.didMount.call(this)
+    const { node } = this.props
+    node.on('src:changed', this.rerender, this)
+    // TODO: we should try to factor this out for reuse
+    node.on('upload:started', this.onUploadStarted, this)
+    node.on('upload:finished', this.onUploadFinished, this)
+  }
+
+  dispose () {
+    super.dispose.call(this)
+    const { node } = this.props
+    node.off(this)
+  }
+
+  render ($$) {
+    let el = super.render.call(this, $$)
+    el.addClass('sc-image')
+
+    el.append(
+      $$('img').attr({
+        src: this.props.node.src
+      }).ref('image')
+    )
+
+    if (this.state.uploading) {
+      let progressBar = $$('div')
+        .addClass('se-progress-bar')
+        .ref('progressBar')
+        .append('Uploading ...')
+      el.append(progressBar)
+    }
+
+    return el
+  }
+
+  onUploadStarted () {
+    this.setState({ uploading: true })
+  }
+
+  onUploadFinished () {
+    this.setState({})
+  }
+
+}
+
+export default ImageComponent
diff --git a/app/components/SimpleEditor/elements/images/ImageHTMLConverter.js b/app/components/SimpleEditor/elements/images/ImageHTMLConverter.js
new file mode 100644
index 0000000000000000000000000000000000000000..088352cacd44902b0aebb79054af991977bb1ead
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/ImageHTMLConverter.js
@@ -0,0 +1,18 @@
+/*
+ * HTML converter for Paragraphs.
+ */
+export default {
+
+  type: 'image',
+  tagName: 'img',
+
+  import: function (el, node) {
+    node.src = el.attr('src')
+    node.previewSrc = el.attr('data-preview-src')
+  },
+
+  export: function (node, el) {
+    el.attr('src', node.src)
+    if (node.previewSrc) el.attr('data-preview-src', node.previewSrc)
+  }
+}
diff --git a/app/components/SimpleEditor/elements/images/ImagePackage.js b/app/components/SimpleEditor/elements/images/ImagePackage.js
new file mode 100644
index 0000000000000000000000000000000000000000..ec44a1de8330e9df514135b4961802d617ee4280
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/ImagePackage.js
@@ -0,0 +1,24 @@
+import ImageNode from './Image'
+import ImageComponent from './ImageComponent'
+import ImageHTMLConverter from './ImageHTMLConverter'
+import InsertImageCommand from './InsertImageCommand'
+import InsertImageTool from './InsertImageTool'
+
+export default {
+  name: 'image',
+  configure: function (config) {
+    config.addNode(ImageNode)
+    config.addComponent('image', ImageComponent)
+    config.addConverter('html', ImageHTMLConverter)
+    config.addCommand('insert-image', InsertImageCommand)
+    config.addTool('insert-image', InsertImageTool)
+    config.addIcon('insert-image', { 'fontawesome': 'fa-image' })
+    config.addLabel('image', { en: 'Image' })
+    config.addLabel('insert-image', { en: 'Insert image' })
+  },
+  ImageNode: ImageNode,
+  ImageComponent: ImageComponent,
+  ImageHTMLConverter: ImageHTMLConverter,
+  InsertImageCommand: InsertImageCommand,
+  InsertImageTool: InsertImageTool
+}
diff --git a/app/components/SimpleEditor/elements/images/InsertImageCommand.js b/app/components/SimpleEditor/elements/images/InsertImageCommand.js
new file mode 100644
index 0000000000000000000000000000000000000000..c2a2f5d0ad2740f07c6b03cd35869ad99d7f5860
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/InsertImageCommand.js
@@ -0,0 +1,101 @@
+import { Command, pasteContent } from 'substance'
+
+class ImageCommand extends Command {
+  constructor () {
+    super({ name: 'insert-image' })
+  }
+
+  getCommandState (params) {
+    let sel = params.selection
+    let surface = params.surface
+    let newState = {
+      disabled: true,
+      active: false
+    }
+    if (sel && !sel.isNull() && !sel.isCustomSelection() &&
+        surface && surface.isContainerEditor()) {
+      newState.disabled = false
+    }
+    return newState
+  }
+
+  /**
+    Inserts (stub) images and triggers a fileupload.
+    After upload has completed, the image URLs get updated.
+  */
+  execute (params, context) {
+    let state = this.getCommandState(params)
+    // Return if command is disabled
+    if (state.disabled) return
+
+    let documentSession = params.documentSession
+    let sel = params.selection
+    let surface = params.surface
+    let fileClient = context.fileClient
+    let files = params.files
+
+    // can drop images only into container editors
+    if (!surface.isContainerEditor()) return
+
+    // creating a small doc where we add the images
+    // and then we use the paste transformation to get this snippet
+    // into the real doc
+    let doc = surface.getDocument()
+    let snippet = doc.createSnippet()
+
+    // as file upload takes longer we will insert stub images
+    let items = files.map(function (file) {
+      let node = snippet.create({ type: 'image' })
+      snippet.show(node)
+      return {
+        file: file,
+        nodeId: node.id
+      }
+    })
+
+    surface.transaction(function (tx) {
+      tx.before.selection = sel
+      return pasteContent(tx, {
+        selection: sel,
+        containerId: surface.getContainerId(),
+        doc: snippet
+      })
+    })
+
+    // start uploading
+    items.forEach(function (item) {
+      let nodeId = item.nodeId
+      // let file = item.file
+      console.log('item', item)
+      let node = doc.get(nodeId)
+      node.emit('upload:started')
+      // let node = doc.get(nodeId)
+      if (node) {
+        node.emit('upload:finished')
+        // documentSession.transaction(function (tx) {
+        //   tx.set([nodeId, 'src'],)
+        // })
+      }
+      // let channel = fileClient.uploadFile(file, function (err, url) {
+        // if (err) {
+        //   url = 'error'
+        // }
+        // get the node again to make sure it still exists
+        // let node = doc.get(nodeId)
+        // if (node) {
+        //   node.emit('upload:finished')
+        //   documentSession.transaction(function (tx) {
+        //     tx.set([nodeId, 'src'], url)
+        //   })
+        // }
+      // })
+    })
+
+    return {
+      status: 'file-upload-process-started'
+    }
+  }
+
+}
+
+export default ImageCommand
diff --git a/app/components/SimpleEditor/elements/images/InsertImageTool.js b/app/components/SimpleEditor/elements/images/InsertImageTool.js
new file mode 100644
index 0000000000000000000000000000000000000000..adfb46c4d198f83708a7264cfc982d7b82d59c37
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/InsertImageTool.js
@@ -0,0 +1,29 @@
+import { Tool } from 'substance'
+
+class InsertImageTool extends Tool {
+
+  getClassNames () {
+    return 'sc-insert-image-tool'
+  }
+
+  renderButton ($$) {
+    let button = super.renderButton($$)
+    let input = $$('input').attr('type', 'file').ref('input')
+      .on('change', this.onFileSelect)
+    return [button, input]
+  }
+
+  onClick () {
+    this.refs.input.click()
+  }
+
+  onFileSelect (e) {
+    let files = e.currentTarget.files
+    this.executeCommand({
+      files: Array.prototype.slice.call(files)
+    })
+  }
+
+}
+
+export default InsertImageTool
diff --git a/app/components/SimpleEditor/elements/images/image.scss b/app/components/SimpleEditor/elements/images/image.scss
new file mode 100644
index 0000000000000000000000000000000000000000..166907fe238872eb71f6aa3994d3a19cf51b2626
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/image.scss
@@ -0,0 +1,16 @@
+.sc-image {
+  display: block;
+  margin: 0 auto;
+  max-width: 100%;
+  position: relative;
+
+  img {
+    max-width: 1600px;
+  }
+
+  .se-progress-bar {
+    height: 300px;
+    width: 400px;
+  }
+
+}
diff --git a/app/components/SimpleEditor/elements/images/insert-image-tool.scss b/app/components/SimpleEditor/elements/images/insert-image-tool.scss
new file mode 100644
index 0000000000000000000000000000000000000000..d870d20466b53314c3daf02a9742026713810551
--- /dev/null
+++ b/app/components/SimpleEditor/elements/images/insert-image-tool.scss
@@ -0,0 +1,5 @@
+.sc-insert-image-tool > input {
+  left: -1000px;
+  position: fixed;
+  top: -1000px;
+}
diff --git a/config/dev.js b/config/dev.js
index 8f9fe04658aaebcb1efe93e9d85e772fe33958bc..6b5f464a6a91897c843437093a165420859ddb5e 100644
--- a/config/dev.js
+++ b/config/dev.js
@@ -12,7 +12,7 @@ module.exports = {
   },
   'pubsweet-backend': {
     dbPath: path.join(__dirname, '..', 'api', 'db'),
-    secret: 'c0d9a89b-fcce-49b3-83bc-0ccf3326d0ef',
+    secret: 'c2f6dba5-b5fa-418a-8dfe-430917a306ee',
     API_ENDPOINT: '/api'
   },
   'pubsweet-component-ink-backend': universal.inkBackend,
diff --git a/public/uploads/e417958680511ad409805ea6f23c35c7 b/public/uploads/e417958680511ad409805ea6f23c35c7
new file mode 100644
index 0000000000000000000000000000000000000000..3074ec8386b48ffeebc1fb63061235129dc2e141
Binary files /dev/null and b/public/uploads/e417958680511ad409805ea6f23c35c7 differ