JavaScript Runtime

JavaScript Runtime

One of biggest features of Lynx is Dual-Thread Architecture(read Thinking in ReactLynx for more information), JavaScript code runs on two threads: the main thread and the background thread. The two threads use different JavaScript engines as their runtime.

Main Thread

The Lynx main thread is responsible for handling tasks that directly affect the screen pixel-pipeline, including executing main thread scripts, handling layout, and rendering graphics.

The main thread uses PrimJS, maintained by the Lynx team, as its runtime. PrimJS is a lightweight, high-performance JavaScript engine based on QuickJS, providing excellent runtime performance for the main thread.

Background Thread

As opposed to the main thread, Lynx's background threads handle tasks that do not directly affect the display of screen pixels. This includes scripts and tasks that run in the background, separate from the main thread. This allows the main thread to focus on handling user interaction and rendering, which improves overall performance.

  • Android: for a combination of package size and performance considerations, we use PrimJS by default
  • iOS: we use JavaScriptCore by default, unless you need to use the PrimJS for debugging

While these environments are very similar, you may end up hitting some inconsistencies. It is best to avoid relying on specifics of any runtime.

JavaScript Syntax Transformers

The Lynx dual-thread runtime supports the following maximum ECMAScript versions:

Of course, you can use new JavaScript syntax to write your code. During the build process, SWC will be used as Syntax Transformer to transform your code, so you don't have to wait for JavaScript runtime support.

JavaScript Polyfills

INFO

Only injects polyfills on iOS.

A full list of Lynx's polyfills can be found in Lynx repository

Besides syntax transformers, many built-in objects and standard functions are also available. Including:

Built-in Objects

Array

ArrayBuffer

Date

Number

Object

Promise

Reflect

RegExp

String

Symbol

Module

You can use JavaScript module when developing Lynx project.

Lynx currently supports ESModule and CommonJS. The usage of ESModule and CommonJS can be mixed.

It is recommended to use ESModule, which allows for better Tree Shaking.

Module Names

Both ESModule and CommonJS, a module name needs to be specified. It can be one of:

  • Relative path: ./common.js
  • Name of a npm package: lodash (C++ addon and NodeJS builtin packages are not supported)
  • Path with alias: @common/foo.js

CommonJS

CommonJS uses require(path) to import a module. Uses module.exports or exports to export a module.

common.js
ReactLynx
common.js
1const lodash = require('lodash'); // can require npm packages
2function hello(name) {
3  console.log(`Hello ${lodash.capitalize(name)} !`);
4}
5
6function goodbye(name) {
7  console.log(`Goodbye ${name} !`);
8}
9
10module.exports.hello = hello;
11exports.goodbye = goodbye;
TIP
  • require can be anywhere in your code, not required to be at top.

  • require will synchronously execute the target module.

  • require will cache the returned object. Multiple require to the same path will return the same value. e.g:

require('foo') === require('foo'); // true

ESModule

ESModule uses import to import a module. Uses export to export a module. import and export must be placed at the top level of source file.

ESModule can also use import() to dynamically import a module.

utils.js
ReactLynx
utils.js
export function getAge() {
  return 11;
}

export default function (add1, add2) {
  return add1 + add2;
}
Except as otherwise noted, this work is licensed under a Creative Commons Attribution 4.0 International License, and code samples are licensed under the Apache License 2.0.