JSX is a function call, which explains most of the rules

JSX looks like a template language embedded in JavaScript, which makes its rules look arbitrary and its errors look like parser bugs. It is not a template language. The transform rewrites each element into a function call with an object literal for the attributes, and nearly everything people trip over falls out of that one fact.

// what you write
var row = <li className="order" onClick={this.select}>{order.sku}</li>;

// what the transform emits
var row = React.DOM.li({className: "order", onClick: this.select}, order.sku);

// and for a component of your own, the tag name IS the variable
var panel = <OrderPanel order={order} />;
var panel = OrderPanel({order: order});

class becomes className and for becomes htmlFor because both are reserved words and these are keys in an object literal. render must return a single element because a function returns a single value, and two siblings would be two calls with nowhere to put the second. The braces are not interpolation syntax — they are the boundary between markup and an ordinary JavaScript expression, which is why if does not work inside them and the ternary does. Every tag must be closed, self-closing included, because this is a parser and not a string replacement. The one genuine convention rather than a consequence is capitalisation: a lowercase tag compiles to React.DOM.li and an uppercase one to the variable of that name in scope, so a component named in lowercase silently becomes an unknown HTML element.