What is jsc-android?
The jsc-android package provides an optimized version of the JavaScriptCore engine for Android. This allows developers to leverage the latest JavaScript features and improvements in performance within their React Native applications or any other Android project that requires an embedded JavaScript engine.
What are jsc-android's main functionalities?
Using modern JavaScript features in Android apps
This code demonstrates how to use jsc-android to run JavaScript code, utilizing modern JavaScript features, directly within an Android application. It creates a new JavaScript context and evaluates a simple script.
"import org.liquidplayer.javascript.JSContext;\n\npublic class MainActivity extends AppCompatActivity {\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.activity_main);\n\n JSContext context = new JSContext();\n context.evaluateScript(\"'Hello, World!'.toUpperCase();\");\n }\n}"
Improving React Native performance
By including jsc-android in a React Native project's dependencies, developers can improve the performance of their applications. This is particularly beneficial for complex applications that require a lot of JavaScript execution.
"dependencies {\n implementation 'org.webkit:android-jsc:r250230'\n}\n"
Other packages similar to jsc-android
v8-android
Similar to jsc-android, v8-android provides the V8 JavaScript engine for Android applications. While jsc-android uses the JavaScriptCore engine, v8-android uses Google's V8 engine. This difference in the underlying engine can lead to variations in performance and compatibility with JavaScript features.
hermes-engine
Hermes is a JavaScript engine optimized for running React Native on Android. It aims to improve startup time, decrease memory usage, and increase overall performance. Unlike jsc-android, Hermes is built specifically for React Native and may offer better optimizations for React Native apps.
JSC build scripts for Android
The aim of this project is to provide maintainable build scripts for the JavaScriptCore JavaScript engine and allow the React Native project to incorporate up-to-date releases of JSC into the framework on Android.
This project is based on facebook/android-jsc but instead of rewriting JSC's build scripts into BUCK files, it relies on CMake build scripts maintained in a GTK branch of WebKit maintained by the WebKitGTK team (great work btw!). Thanks to that, with just a small amount of work we should be able to build not only current but also future releases of JSC. An obvious benefit for everyone using React Native is that this will allow us to update JSC for React Native on Android much more often than before (note that facebook/android-jsc uses JSC version from Nov 2014), which is especially helpful since React Native on iOS uses the built-in copy of JSC that is updated with each major iOS release (see this as a reference).
Requirements
- Homebrew (https://brew.sh/)
- GNU coreutils
brew install coreutils
- Node
brew install node
- Java 8:
brew tap caskroom/versions && brew cask install java8
- Android SDK:
brew cask install android-sdk
- Run
sdkmanager --list
and install all platforms, tools, cmake, ndk (android images are not needed) - Set
$ANDROID_HOME
to the correct path (in ~/.bashrc or similar) - Set
export ANDROID_NDK=$ANDROID_HOME/ndk-bundle
- Set
export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools/bin
- Make sure you have Ruby (>2.3), Python (>2.7), Git, SVN, gperf
Build instructions
- Clone this repo
npm run clean
will clean everything (artifacts, downloaded sources)- Update the version in package.json. The version will be printed by JSC lib as soon as it loads.
- Update the config section under
package.json
to the desired build configuration - Update patches if needed (don't forget to update the
printVersion
patch in jsc.patch) npm run download
: downloads all needed sourcesnpm run start
: builds jsc (this might take some time...)
The zipfile containing the android-jsc AAR will be available at /dist
.
The library is packaged as a local Maven repository containing AAR files that include the binaries.
Distribution
JSC library built using this project is distributed over npm: npm/jsc-android.
The library is packaged as a local Maven repository containing AAR files that include the binaries.
Please refer to the section below in order to learn how your app can consume this format.
On load, JSC prints the version out to logcat, under "JavaScriptCore.Version" tag.
How to use it with my React Native app
Follow steps below in order for your React Native app to use new version of JSC VM on android:
- Add
jsc-android
to the "dependencies" section in your package.json
:
dependencies {
+ "jsc-android": "236355.x.x",
then run npm install
or yarn
(depending which npm client you use) in order for the new dependency to be installed in node_modules
- Modify
android/build.gradle
file to add new local maven repository packaged in the jsc-android
package to the search path:
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
+ maven {
+ // Local Maven repo containing AARs with JSC library built for Android
+ url "$rootDir/../node_modules/jsc-android/dist"
+ }
}
}
- Update your app's
build.gradle
file located in android/app/build.gradle
to force app builds to use new version of the JSC library as opposed to the version specified in react-native gradle module as a dependency:
}
+configurations.all {
+ resolutionStrategy {
+ force 'org.webkit:android-jsc:r236355'
+ }
+}
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
- Make sure your app's
build.gradle
uses a minimum sdk version of 21
defaultConfig {
applicationId "com.myApp"
- minSdkVersion 16
+ minSdkVersion 21
targetSdkVersion 22
versionCode 1
- You're done, rebuild your app and enjoy updated version of JSC on android!
International variant
International variant includes ICU i18n library and necessary data allowing to use e.g. Date.toLocaleString and String.localeCompare that give correct results when using with locales other than en-US. Note that this variant is about 6MiB larger per architecture than default.
To use this variant instead replace the third installation step with:
+configurations.all {
+ resolutionStrategy {
+ eachDependency { DependencyResolveDetails details ->
+ if (details.requested.name == 'android-jsc') {
+ details.useTarget group: details.requested.group, name: 'android-jsc-intl', version: 'r236355'
+ }
+ }
+ }
+}
Testing
See Measurements page that contains synthetic perf test results for the most notable versions of JSC we have tried.
Troubleshooting
Compile errors of the sort:
More than one file was found with OS independent path 'lib/armeabi-v7a/libgnustl_shared.so'
Add the following to your app/build.gradle
, under android
:
packagingOptions {
pickFirst '**/libgnustl_shared.so'
}
Resources
Credits
Check the list of contributors here. This project is supported by:
Expo.io
Software Mansion
Wix