Edit in JSFiddle

// React

var ReactElement = function(type, props) {
  this.type = type
  this.props = props
}

var createElement = function(type, config, children) {
  var props = {}
  for (propName in config) {
    props[propName] = config[propName]
  }
  props.children = children

  return new ReactElement(type, props)
}

var DOM = {};
['div', 'a', 'h1', 'p'].forEach(function(type) {
  DOM[type] = createElement.bind(null, type)
})

// ReactCompositeComponent ,ReactDOMComponent, ReactDOMTextComponent
var ReactDOMTextComponent = function(text) {
  this._currentElement = text
}

ReactDOMTextComponent.prototype.mountComponent = function(rootID) {
  this._rootID = rootID
  return ('<span data-reactid="' + rootID + '">' + this._currentElement + '</span>')
}

ReactDOMTextComponent.prototype.receiveComponent = function(nextText) {
  if(this._currentElement != nextText) {
    var node = React.getNode(this._rootID)
    node.innerHTML = nextText
  }
}

var ReactCompositeComponent = function(element) {
  this._currentElement = element
}

ReactCompositeComponent.prototype.mountComponent = function(rootID) {
  this._rootID = rootID

  var instance = new this._currentElement.type(this._currentElement.props, this)

  var renderedElement = instance.render()

  this._renderedComponent = instantiateReactComponent(renderedElement)

  return this._renderedComponent.mountComponent(rootID)
}

ReactCompositeComponent.prototype.receiveComponent = function(nextElement) {
  this._renderedComponent.receiveComponent(nextElement)
}

var ReactDOMComponent = function(element) {
  this._currentElement = element
}

ReactDOMComponent.prototype.mountComponent = function(rootID) {
  this._rootID = rootID

  var props = this._currentElement.props

  var tagOpen = '<' +
    this._currentElement.type +
    this.createMarkupForStyles(props) +
    ' data-reactid="' + this._rootID + '"' +
    '>'

  if(props.onClick) {
    ReactEventEmitter.putListener(rootID, 'onClick', props.onClick)
  }

  var tagClose = '</' + this._currentElement.type + '>'

  if(props.children) {
    this._renderedComponents = props.children.map(function(element){
      return instantiateReactComponent(element)
    })

    var subIndex = 0
    var tagContent = this._renderedComponents.map(function(component) {
      var nextID = rootID + '.' + subIndex++
      return component.mountComponent(nextID)
    }).join('')
  } else {
    var tagContent = ''
  }

  return tagOpen + tagContent + tagClose
}

ReactDOMComponent.prototype.receiveComponent = function(nextElement) {
  this._currentElement = nextElement

  var nextChildren = nextElement.props.children || []

  for(var i = 0; nextChildren.length > i; i++) {
    var childElement = nextChildren[i]
    var childComponent = this._renderedComponents[i]
    if (shouldUpdateReactComponent(childComponent._currentElement, childElement)) {
      childComponent.receiveComponent(childElement)
    }
  }
}

function shouldUpdateReactComponent(prevElement, nextElement) {
  if (prevElement != null && nextElement != null) {
    var prevType = typeof prevElement
    var nextType = typeof nextElement
    if (prevType == 'string' || prevType === 'number') {
      return nextType === 'string' || nextType === 'number'
    } else {
      return (
        nextType === 'object' &&
        prevElement.type === nextElement.type
      )
    }
    return false
  }
}

ReactDOMComponent.prototype.createMarkupForStyles = function(props) {
  if(props.className) {
    return ' class="' + props.className + '"'
  } else {
    return ''
  }
}

function instantiateReactComponent(node) {
  if(typeof node === 'object') {
    if (typeof node.type === 'string') {
      return new ReactDOMComponent(node)
    } else if (typeof node.type === 'function') {
      return new ReactCompositeComponent(node)
    }
  } else if (typeof node === 'string' || typeof node === 'number') {
    return new ReactDOMTextComponent(node)
  }
}

function createClass(spec) {
  var Constructor = function(props, updater) {
    this.props = props
    this.state = this.getInitialState ? this.getInitialState() : null
    this.updater = updater

    var self = this

    this.setState = function(states) {
      for (name in states) {
        self.state[name] = states[name]
      }

      self.updater.receiveComponent(self.render())
    }
  }
  Constructor.prototype = spec

  return Constructor
}

// diagram in ReactBrowserEventEmitter
var ReactEventEmitter = {
  listenerBank: {},

  putListener: function putListener(id, registrationName, listener) {
    var bankForRegistrationName =
      this.listenerBank[registrationName] || (this.listenerBank[registrationName] = {})

    bankForRegistrationName[id] = listener
  },

  getListener: function getListener(id, registrationName) {
    return this.listenerBank[registrationName][id]
  },

  trapBubbledEvent: function trapBubbledEvent(topLevelEventType, element) {
    var eventMap = {
      'onClick': 'click'
    }
    var baseEventType = eventMap[topLevelEventType]
    element.addEventListener(baseEventType, this.dispatchEvent.bind(this, topLevelEventType))
  },

  dispatchEvent: function dispatchEvent(eventType, event) {
    event.preventDefault()
    var id = event.target.getAttribute('data-reactid')
    var listener = this.getListener(id, eventType)
    if(listener) {
      listener(event)
    }
  }
}

var instancesByReactRootID = {}
var containersByReactRootID = {};
function registerComponent(component, container) {
  var reactRootID = getRootIDString(container)
  instancesByReactRootID[reactRootID] = component
  containersByReactRootID[reactRootID] = container
  return reactRootID
}

var containerIndex = 0
function getRootIDString(container) {
  return '.' + containerIndex++
}

function getNode(targetID) {
  var sequenceID = targetID.split('.')
  sequenceID.shift()

  var child = containersByReactRootID[targetID.slice(0, 2)]
  while(child) {
    var id = child.getAttribute('data-reactid')
    if (id === targetID) {
      return child
    } else if(child.children){
      child = child.children[sequenceID.shift()]
    } else {
      child = null
    }
  }
}

function render(element, container) {

  var topComponent = instantiateReactComponent(element)

  var reactRootID = registerComponent(topComponent, container)

  ReactEventEmitter.trapBubbledEvent('onClick', container)

  container.innerHTML = topComponent.mountComponent(reactRootID)
}

var React = {
  createElement: createElement,
  DOM: DOM,
  createClass: createClass,
  render: render,
  getNode: getNode,

  // for testing purpose
  ReactDOMTextComponent: ReactDOMTextComponent,
  ReactDOMComponent: ReactDOMComponent,
  ReactCompositeComponent: ReactCompositeComponent,
  instantiateReactComponent: instantiateReactComponent,
  instancesByReactRootID: instancesByReactRootID,
  containersByReactRootID: containersByReactRootID,
  ReactEventEmitter: ReactEventEmitter,
  shouldUpdateReactComponent: shouldUpdateReactComponent,
}

if(typeof module !== 'undefined') {
  module.exports = React
}

// example

var DOM = React.DOM
var App = React.createClass({
  getInitialState: function() {
    return {
      name: 'React',
        timestamp: 0
      }
    },
    handleClick: function() {
      this.setState({
        name: 'BOOOOOOOOOOOOOOOOM!!!!',
        timestamp: new Date().getTime() - this.props.start
      })
    },
    render: function() {
      return DOM.div(null, [
        DOM.h1(null, ['Welcome to ' + this.state.name + '!!']),
        DOM.div(null, [
          DOM.p(null, ["Watchout for what React you're using... it might not be real!"]),
          DOM.p(null, ["React is running for " + this.state.timestamp + "ms"])
        ]),
        DOM.a({ className: 'btn btn-default', onClick: this.handleClick.bind(this) }, ["Click me!!!"])
    ])
  }
})

var start = new Date().getTime()

React.render(
  React.createElement(App, { start: start }),
  document.getElementById('container')
)

<div id='container' class='container'></div>