Runtime
Tabris.js apps are executed in a JavaScript engine hosted by a native iOS or Android App. The code may be packaged with the app (using the Tabris build service or CLI), or side-loaded via HTTP and Tabris CLI. Side loading is usually only done with debug builds or the Tabris Developer App.
The JavaScript Engine
The different platforms use different JavaScript engines.
Android uses V8 (via J2V8), which is bundled with the native part of the app. As a result the version of the JavaScript engine that an Tabris app runs in is bound to the Tabris.js version the app is built on.
On iOS the JavaScriptCore engine is used, which is part of the operating system. Therefore the version of iOS that a Tabris app is installed on determines which version of the JavaScript engine it runs on.
Application Programming Language
Tabris.js apps can be developed in JavaScript or TypeScript. In both cases you also have the option to embed JSX (an HTML-like language extension) in your JavaScript/TypeScript code.
Which language features are available to you depends on the exact JavaScript engine the code runs in (as explained above), and which compiler - if any - is used to pre-process your code.
Vanilla JavaScript Projects
You get this “vanilla” JS kind of project setup if you choose the Template “Hello World (JavaScript)” when running the tabris init
command, or by just typing npm init && npm i tabris
in an empty directory.
Important: Many examples in the official Tabris.js documentation make use of the ES6 module syntax and JSX. These features do not work with vanilla JS projects. The details are explained below and in this article.
In vanilla JS projects your code will be executed exactly as written, and which language features are available depends entirely on the JavaScript engine. In general both platforms (iOS/Android) support most of the ECMAScript 2017 standard, but not the ES6 Module syntax.
Notable supported features:
Feature | Example |
---|---|
Arrow functions | (a, b) => a + b |
Classes | class { … } |
const | const a = 1; |
Default parameters | function(a = 1) { … } |
Destructuring assignment | [a, b] = [1, 2] |
Exponentiation operator | a ** b |
for…of | for (let a of b) { … } |
Generators | function*() { … } |
let | let a = 1; |
Map | new Map(iterable) |
Methods | { a() { … } } |
Object property shorthands | {a, b} |
Promise | new Promise(cb) |
Reflect | Reflect.setPrototypeOf(a, proto) |
Rest parameters | function(...args) { … } |
Proxy | new Proxy(a, handler) |
set | { set a(value) { … } } |
get | { get a() { … } } |
Set | new Set(iterable) |
Spread operator | foo(...arr) |
Symbol | Symbol(str) |
Template literals | \`foo ${value} bar\` |
Typed Arrays and ArrayBuffer | new Uint8Array(buffer) |
WeakMap | new WeakMap(iterable) |
WeakSet | new WeakSet(iterable) |
Notable feature NOT supported:
Feature | Example | Alternative |
---|---|---|
import/export | import {foo} from 'foo'; |
const {foo} = require('foo'); |
JSX | <TextView text='foo'/> |
TextView({text: 'foo'}) |
Types/Interfaces | const foo: string; |
/** @type {string} */ const foo; |
async/await* | await fn(); |
fn().then(...); |
- “async” functions are parsed, but can not update the UI. This can currently not be fixed. It’s recommended to either use promises directly or a compiler that transforms async functions to promises.
Compiled JavaScript Projects
There are many tools (e.g. TypeScript, Babel, WebPack) that provide some kind of JavaScript pre-processing. In Tabris.js this can enable the use of syntax (see above) that would otherwise not be supported at runtime.
The Tabris.js project templates provided by the tabris init
command use the TypeScript compiler (tsc
) to provide ES6 Module syntax and JSX support in JavaScript code. We generally recommend tsc
over Babel, even for non-TypeScript projects. This is because it requires less dependencies and configuration, provides better auto completion in your IDE, and eases migration to TypeScript should this be desired later on.
TypeScript Projects
Since tabris init
creates a JavaScript/TypeScript hybrid projects, everything from the previous section still applies here. You simply create .ts
and .tsx
files instead of .js
and .jsx
files. Further notes on TypeScript support can be found here.