With your new file open in a text editor, add an empty <script></script> tag between the second </script> tag and the closing </body> tag. Then, type out the following code inside the new <script> tags.

Why type it out instead of copy and paste?

Typing forces you to process each of the individual commands, drilling them into your head in the process – while copying and pasting just gives you a short feeling of cleverness and a shot of dopamine. And if you just want dopamine, quit reading and play flappy bird or something.

// The `React` variable is set by the first `<script>` tag// in the above HTML file.let createElement = React.createElement
let rootElement =createElement('div',{},createElement('h1',{},"Contacts"),createElement('ul',{},createElement('li',{},createElement('a',{ href:'mailto:james@frontarm.com'},"James Nelson",),),createElement('li',{},createElement('a',{ href:'mailto:me@example.com'},"Me"))))// The `ReactDOM` variable is set by the second `<script>` tag// in the above HTML filelet domNode = document.getElementById('root')
ReactDOM.render(rootElement, domNode)

Phew, that took some effort. But hopefully after typing createElement() over and over, you’ll have gotten some idea of what it does. If not, I’ll explain in a moment. But first…

If you had trouble getting it work in the browser, try clearing the editor above and typing out the example there - the preview will update as you type. And once you’ve got it working, copy it over to your HTML file and try again.

Did you get it to work? Then congratulations! You’ve build a simple React app - without using JSX, Webpack, or even NPM! But what is actually going on here?

At it’s core, React is a library for creating and updating HTML markup.

ReactDOM.render() is the function that does the creating and updating. It takes a React Element object — the thing returned by createElement() — and uses this to update the page’s markup via the DOM node passed in as the second argument.

But wait a moment, isn’t React.createElement() creating elements? It is! But maybe not in the way you’d expect.

The React Element objects that React.createElement() returns are just plain old JavaScript objects that describe the DOM nodes that you’d like ReactDOM.render() to create. They’re not DOM nodes, and not added to the document. They’re just objects, with the properties type and props. For example:

{// The type of element to use. It can be the name of a HTML element,// or can be a custom type (which we'll get to later).
type:'a',// Configures the created HTML element's attributes and children.
props:{
href:'https://xkcd.com/221/',// If specified, this will contain the element's content. It can be// a string, an array, or another React Element.
children:{
type:'img',
props:{
src:"https://imgs.xkcd.com/comics/random_number.png",
alt:"RFC 1149.5 specifies 4 as the standard IEEE-vetted random number.",}},},}

The React.createElement() function takes three arguments: type, props, and children. And returns an object just like the one above.

React.createElement(type, props, children)

You can get a feel for this by passing different parts of a returned Element object to console.log(). Try changing it yourself by changing the console.log() statements below!

The React.createElement() function is The Most Important of React’s three fundamental concepts: elements, components, and component instances.

Learning the fundamentals is a great way to boost your understanding of the rest of React’s ecosystem. As a bonus, the fundamentals rarely change. In fact, other than the URLs in the <script> tags, the exercise’s code is unchanged from a similar guide I wrote 3 years ago!

Do you want to invest in a deeper understanding of React’s fundamentals, and gain an important skill that’ll stay with you for years? Then click through to my React (without the buzzwords) course. You’ve just worked through most of the first two lessons, so you’re off to a great start!