atril

Experimental JS rendering library

Ideas from ReactJS, Polymer, Angular 2, Aurelia, made simple

Note: this documentation shows features from EcmaScript 6/7, but they're completely optional. You can use atril with plain ES5 and any module system. The docs include some ES5 examples as well.

Custom Elements and Attributes

The library has three types of building blocks.

<my-custom-element></my-custom-element>
<input bind.disabled="isDisabled">
<template if.="allowed">
  <button>submit</button>
</template>
<button if.="allowed">submit</button>

Example Component

A custom element (usually called component) is a combination of a view model (data and logic) with a view (a template). atril renders the view and automatically updates it whenever the data changes.

// Viewmodel.

import {Component} from 'atril';

@Component({
  tagName: 'hello-world'
})
class ViewModel {
  name = 'world';
  static viewUrl = 'hello-world/hello-world.html';
}
<!-- Template. -->

<!-- Updates automatically -->
<h1>Hello, {{name}}!</h1>

<!-- Two-way databinding -->
<input twoway.value="name">

<!-- One-way databinding with manual feedback -->
<input bind.value="name" on.input="name = this.value">

<!-- One-way databinding with no feedback;
     on.input is needed to detect user activity -->
<input bind.value="name" on.input>
<!-- Usage in HTML -->

<hello-world></hello-world>
var Component = require('atril').Component;

Component({
  tagName: 'hello-world'
})(ViewModel);

function ViewModel() {
  this.name = 'world';
}

ViewModel.viewUrl = 'hello-world/hello-world.html';
<!-- Updates automatically -->
<h1>Hello, {{name}}!</h1>

<!-- Two-way databinding -->
<input twoway.value="name">

<!-- One-way databinding with manual feedback -->
<input bind.value="name" on.input="name = this.value">

<!-- One-way databinding with no feedback;
     on.input is needed to detect user activity -->
<input bind.value="name" on.input>

Automatic Change Detection

Much like Angular 2, atril uses zone.js to automatically detect relevant events. When something happens, the library reflows the virtual DOM, updating it with the new data, and carefully updates the view.

Forget about event subscriptions, manual re-renders (ReactJS), digest cycles (Angular) or observables (Polymer, Aurelia). In atril, it just works.

As a side benefit, this architecture allows you to bind to expressions rather than just properties. See databinding for details.

Databinding

The library has one-way and two-way databinding. It lets you automatically sync values to the view and vice versa. This includes properties of native DOM elements, and other custom elements in the view.

See Databinding for details.

Virtual DOM

atril maintains a virtual representation of each component's node tree. Updates to the viewmodel cause changes in the virtual tree. The library diffs them with the live DOM and carefully updates the view.

This is primarily an implementation detail, and is done for internal consistency. However, this architecture should enable optimisations for high rendering performance, similar to ReactJS.

Multi-page Application Friendly

This library is targeting websites over web applications. It's aimed at multi-page, document-oriented sites with server-side routing and large amounts of static content — in other words, the majority of the web.

It's designed to be as light, fast, and non-intrusive as possible. The library clocks at 47KB, starts up quickly, and you can use custom components just by including new tags on the page — without any effect on the rest of the content, routing, or page rendering.

Big-name next generation frameworks like Angular 2 and Aurelia are targeting a wider range of applications, with the primary focus on single-page apps. You can certainly use them for any website, but at the moment of writing, they incur a significant performance and mental overhead for an MPA.

Make a comparison and pick the right tool for the given use case.

Lightweight

Despite its power, atril is simple at its core. The entire library is 47KB minified with dependencies. This includes 14KB of zone.js, which comes with a Promise polyfill. The library has no other ES6 dependencies.

Browser support: standards-compliant browsers; IE10 and above.

Overview Quickstart Component Attribute Mold Databinding Bootstrapping if for let on class ref demo