In the sections below we will take a closer look at some of the differences between Marko and React.

Syntax

Both Marko and React JSX allow HTML markup and JavaScript to be combined into a single file and both support building web applications based on UI components. Marko utilizes an HTML-JS syntax while most React apps use the JSX syntax.

React JSX makes JavaScript more like HTML and Marko makes HTML more like JavaScript.

In the end, both Marko and React allow JavaScript and HTML to be intertwined.

Syntax: attributes

React JSX

In React JSX, all attribute values are parsed as string values unless {} is used.

Marko

With Marko, all attribute values are parsed as JavaScript expressions. The following Marko code is equivalent to the React JSX code above:

Syntax: inline JavaScript

React JSX

React JSX starts with JavaScript and allows XML elements to be inlined as shown below:

Marko

Marko starts out in HTML, but it allows JavaScript to be inlined in a clean and maintainable way. Unlike other template languages, Marko aims to allow the full power of JavaScript. The following Marko code is equivalent to the React JSX code above:

Lines prefixed with $ are directly added to the compiled JavaScript output inside the compiled render() function (for JavaScript code that should run for every render). Lines prefixed with static are directly added to the compiled JavaScript output outside the render() function (for code that should only run once when the template is loaded).

Syntax: HTML support

With Marko any valid HTML markup can be used inside a Marko template. This is not the case with React. The following quote is from the React documentation:

Caveat: Since JSX is closer to JavaScript than HTML, React DOM uses camelCase property naming convention instead of HTML attribute names. For example, class becomes className in JSX, and tabindex becomes tabIndex .

As a result of this caveat for React, tools for converting HTML to JSX exist.

React JSX

Marko

Syntax: conditionals

JSX is syntactic sugar on top of JavaScript, but it requires expressions, so simple things like an if/else/for statement don’t work on their own within a JSX element. As a result, you must either use a ternary expression, an immediately invoked function expression, function call expression, or the experimental do {} expression (stage 0 at the time of writing). This is not an issue for Marko, and directives such as if() and for() can be used anywhere as shown below:

React JSX

Marko

Marko also allows directives to be used as attributes for a more condensed template:

Syntax: looping

React JSX

Marko

Syntax: HTML shorthand

Marko supports a shorthand based on CSS selectors for less code.

React does not support these helpful shorthands.

Syntax: concise

Marko supports a concise syntax that drops angled brackets and ending tags in favor of indentation. Here’s how the Marko syntax options compare:

Marko HTML syntax

Marko concise syntax

Marko mixed syntax

The HTML syntax and the concise syntax can be used together:

React JSX

React does not offer a concise syntax.

Components

Marko starts with simple HTML and allows UI component logic to easily be layered on top.

React JSX

A React UI component is typically implemented as a class that extends React.Component :

React also supports a more concise functional component:

However, if state or lifecycle events are needed then a functional UI component must be converted to a class component:

Marko

Here is the same component in Marko:

Behavior can easily be added to any Marko UI component:

Marko also allows JavaScript behavior, CSS styling and HTML markup to be embedded in the Marko template as a single file UI component:

API

Marko compiles component to JavaScript modules that export an API for rendering the component as shown below:

The same UI component can be rendered to a stream such as a writable HTTP response stream:

The user’s of a Marko UI component do not need to know that the component was implemented using Marko.

Contrast this with React as an example:

On top of that, React requires that a different module be imported to render the exact same UI component on the server:

Custom tags

React JSX

With React, all custom tags for UI components must be explicitly imported:

Marko

Marko supports a mechanism for automatically discovering custom tags for UI components based on the project directory structure. Marko walks up the directory tree to discover all components/ directories and it will also automatically discover custom tags exported by installed packages. This approach negates the need for explicitly importing a custom tag to reduce the amount of code needed in a Marko template. For example given the following directory structure:

.

├── components/

│ ├── hello.marko

│ └── good-bye.marko

└── index.marko

The <hello> tag and the <good-bye> tag nested below the components/ directory will automatically be made available to the index.marko at the root:

This approach also allows editors and IDEs to offer autocompletion for custom tags.

Async

Even after rendering has started, Marko allows parts of the view to be rendered asynchronously using the <await> tag as shown in the following Marko template:

Compiler

Marko compiles a template differently based on whether or not it will be used on the server or in the browser. For example, given the following template:

Compiled for the server:

Compiled for the browser:

Compile-time code transforms

The Marko compiler was built to support compile-time code generators for custom tags and it also provides support for compile-time transforms. While Babel allows code transformations of JavaScript, the Marko compiler provides support for resolving custom tags declaratively and the Marko AST provides for very powerful and simple transformations as shown in the following code for rendering Markdown to HTML at compile-time:

components/markdown/code-generator.js:

The <markdown> tag can then be used as shown below:

In this example, after the template is compiled, the marked library is no longer needed at render-time.

Tools

Marko and React offer a variety of developer tools. The Marko developer tools are constantly evolving, but Marko currently provides tools for unit testing UI components, precompiling .marko files and generating configuration-less apps (similar to create-react-app). Currently, there are no Marko developer tools that integrate with the browser, but this is something we would like to see in the future. We will go into more detail on the Marko developer tools in a future post.

IDE and editor support

Marko offers syntax highlighting across all major IDEs and editors, as well as on GitHub. Marko provides first-class support for the Atom editor with syntax highlighting, Autocomplete for both HTML and custom tags, Hyperclick to quickly jump to referenced files and methods, and Pretty printing to keep your code readable.