diff --git a/mode/jsx/jsx.js b/mode/jsx/jsx.js
index af0e26338ad9ffa1d2f7ca69b3628f51a6938273..758cf11cbf98e224afae43c51ff7bb9ab83c35bd 100644
--- a/mode/jsx/jsx.js
+++ b/mode/jsx/jsx.js
@@ -53,7 +53,22 @@
 
       if (stream.peek() == "{") {
         xmlMode.skipAttribute(cx.state)
-        state.context = new Context(CodeMirror.startState(jsMode, flatXMLIndent(cx.state)),
+
+        var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
+        // If JS starts on same line as tag
+        if (xmlContext && stream.string.slice(0, stream.pos).match(/>\s*$/)) {
+          while (xmlContext.prev && !xmlContext.startOfLine)
+            xmlContext = xmlContext.prev
+          // If tag starts the line, use XML indentation level
+          if (xmlContext.startOfLine) indent -= config.indentUnit
+          // Else use JS indentation level
+          else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
+        // Else if inside of tag
+        } else if (cx.depth == 1) {
+          indent += config.indentUnit
+        }
+
+        state.context = new Context(CodeMirror.startState(jsMode, indent),
                                     jsMode, 0, state.context)
         return null
       }
diff --git a/mode/jsx/test.js b/mode/jsx/test.js
index 0ea9901784dffce899d12a6b249afd4d19b202e5..c54a8b24c9fe692de92dbc24a14557826a06644a 100644
--- a/mode/jsx/test.js
+++ b/mode/jsx/test.js
@@ -57,8 +57,8 @@
   MT("indent_js",
      "([bracket&tag <][tag foo][bracket&tag >]",
      "    [bracket&tag <][tag bar] [attribute baz]={[keyword function]() {",
-     "      [keyword return] [number 10]",
-     "    }}[bracket&tag />]",
+     "        [keyword return] [number 10]",
+     "      }}[bracket&tag />]",
      "  [bracket&tag </][tag foo][bracket&tag >])")
 
   MT("spread",