blog

  • Home
  • blog
  • 3 Lightweight React Alternatives: Preact, VirtualDom & Deku

3 Lightweight React Alternatives: Preact, VirtualDom & Deku

This article was peer reviewed by Craig Bilner and Bruno Mota. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

React’s declarative components and virtual DOM rendering have taken the world of frontend development by storm, but it’s not the only library built on those ideas. Today we’ll explore what it’s like to build an application in three other React-like alternatives.

We’re going to assume that you’re already familiar with React and the terminology that’s used in its ecosystem. If you need to get up to scratch or just refresh, then check out one of our earlier articles.

Overview

Let’s get started with a high level overview of the libraries we’ll be comparing.

Deku (2.0.0-rc15)

Deku on npm

Deku aims to be a more functional alternative to React. It prevents components from having local state, which allows all components to be written as pure functions that communicate with an external state management solution like Redux.

Preact (4.1.1)

Preact on npm

Preact is an attempt to emulate the core functionality of React using as little code as possible. Assuming that you will be using ES2015, Preact takes some shortcuts and trims down React’s original feature set to produce a tiny library which weighs in at only 3KB.

Virtual-DOM (2.1.1)

virtual-dom on npm

Where React, Deku and Preact give you a component abstraction above a virtual DOM, the virtual-dom package gives you the lower level tools you’ll need to create, compare and render trees of virtual DOM nodes yourself. (This isn’t the same thing as the virtual DOM that React and Preact are built on!)

[author_more]

A low level library like Virtual-DOM might seem like an odd alternative to React, but if you’re interested in writing performant mobile web experiences, then watching Pocket-sized JS is a great place to start. In fact, this talk is the reason we’ve included Virtual-DOM as a comparison.

We’ll use each of these libraries to build a component, structure our data flow and finally look at the size and performance of each application.

Components

Here’s a React component that will render some Markdown, using the marked library.

import React from 'react';
import marked from 'marked';

const Markdown = React.createClass({
  propTypes: {
    text: React.PropTypes.string
  },
  getDefaultProps() {
    return { text: '' };
  },
  render() {
    return (
      <div
        dangerouslySetInnerHTML={{
          __html: marked(this.props.text)
        }}>
      </div>
    );
  }
});

We’re using prop validation to have the component warn us if it receives a prop of the wrong type. It also implements a getDefaultProps() method which allows us to provide default values for our component, in the event that none are passed in. Finally, we implement a render method, which returns the user interface for this component.

To prevent React from escaping our Markdown when we render it, we need to pass it to the dangerouslySetInnerHTML property.

Deku

Next up, we’ll implement the same component with Deku.

/** @jsx element */
import { element } from 'deku';
import marked from 'marked';

const Markdown = {
  render({ props: { text='' } }) {
    return <div innerHTML={marked(text)}></div>;
  }
};

The first line is a compiler pragma which tells our compiler to transform JSX like <h1>Hello</h1> into element('h1', null, 'Hello') rather than React.createElement('h1', null, 'Hello'), which allows us to use JSX with Deku instead of React. This option can also be configured with a .babelrc file.

Compared to React, our Deku component is definitely simpler. Deku components don’t have an instance you can reference with this, meaning that all the data the component might need will be passed into the method as an object called model. This object contains our component’s props and we can use destructuring syntax to extract the text prop.

Deku doesn’t have prop validation, but we can at least simulate getDefaultProps() by providing default values in these destructuring assignments.

Preact

Next up is Preact.

/** @jsx h */
import { h, Component } from 'preact';
import marked from 'marked';

class Markdown extends Component {
  render() {
    const { text='' } = this.props;
    return (
      <div
        dangerouslySetInnerHTML={{
          __html: marked(text)
        }}>
      </div>
    );
  }
}

Again, we need to tell the compiler to turn JSX into something Preact understands. Preact components are very similar to React’s ES2015 class components and we were able to copy most of our rendering code from earlier. Like Deku, Preact does not support prop validation or default properties, but we can again simulate default props with destructuring assignments.

Virtual-DOM

Finally, we’ll take look at Virtual-DOM.

/** @jsx h */
import { h } from 'virtual-dom-util';
import marked from 'marked';

function Markdown({ text='' }) {
  return <div innerHTML={marked(text)}></div>;
}

We aren’t provided with any tools for structuring our components, so you won’t see constructs like this, props or state here. In fact, these “components” are just functions which return trees of virtual DOM nodes.

The native way to create virtual DOM nodes isn’t compatible with JSX, so we’re using the virtual-dom-util package to provide us with a JSX compatible alternative. We don’t actually need to import the virtual-dom package until we render our component.

Continue reading %3 Lightweight React Alternatives: Preact, VirtualDom & Deku%

LEAVE A REPLY