Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
L

LiquidCore

> 编程语言
Open source

Node.js virtual machine for Android and iOS

1.0K stars0 likes1 views
WebsiteGitHub

About

Node.js virtual machine for Android and iOS

The LiquidCore Project

LiquidCore enables Node.js virtual machines to run inside Android and iOS apps. It provides a complete runtime environment, including a virtual file system.

LiquidCore also provides a convenient way for Android developers to execute raw JavaScript inside of their apps, as iOS developers can already do natively with JavaScriptCore.

Installation

Step 1: Make sure your project is configured for use with npm

In the root directory of your project, you must have a package.json file. If you do not already have one, you can create it by running:

bash
$ npm init

and following the steps in the wizard.

Step 2: Install LiquidCore and configure package.json

bash
$ npm i liquidcore
$ npx liquidcore init

The init step will add some utility scripts and the liquidcore object to your package.json file. It will also create an example service called example.js, which will get packaged into your app. You can change / add files to be packaged by editing the liquidcore.entry property in your package.json.

Step 3: Configure your mobile app project

Android

iOS

bash
$ npx liquidcore gradle-config --module=

where `` is the name of your application module (the default in Android Studio is 'app').

bash
$ npx liquidcore pod-config --target= --podfile=
$ npx liquidcore bundler --platform=ios
$ pod install

where is your XCode project target, and is the path of your application's Podfile

Notes on iOS

LiquidCore requires the use of Cocoapods, so make sure you've set up your project to use a Podfile first. Important: Your Podfile must contain the use_frameworks! directive. If you are not yet using Cocoapods, you can create a simple one like this:

ruby
platform :ios, '11.0'
use_frameworks!

target '' do
end

where `` is the name of your xcodeproj (without the .xcodeproj extension).

Also, any time you add a new liquidcore.entry point in package.json, you must first run the bundler and then run pod install again. This is a quirk of how Cocoapods works with finding files. Those files must exist at installation time, or they will not be available in the pod, even if they are created later. So after adding a new entry, just do this part again:

bash
$ npx liquidcore bundler --platform=ios
$ pod install

Automatic Bundling

One of the newest features in 0.7.0+ is the ability to automatically bundle JavaScript files in the application build process. This is configured in the gradle-config and/or pod-config steps above. The bundling options are stored in the local package.json file in the liquidcore property. A typical file liquidcore object may look something like this:

json
  "liquidcore": {
    "entry": [
      "example.js",
      "index.js"
    ],
    "gradle_options": {
      "module": "app"
    },
    "bundler_output": {
      "android": "app/src/main/res/raw",
      "ios": ".liquidcore/ios_bundle"
    },
    "bundler_options": {
      "minify": false
    },
    "pod_options": {
      "dev": true,
      "target": "TestApp"
    }
  }

To include a new bundle, simply put the entry point JavaScript file in the entry array property. LiquidCore will generate one bundle for each entry during the build process.

If you have a non-standard configuration for your app, you may have to change some of these values. For example, bundler_output for Android assumes that your resources directory is at /src/main/res. This is the Android Studio default. If you have changed this to something else, you will need to update this property.

Bundling is a convenient way to test and package your JavaScript projects. The bundler uses Metro to package up all of your required node modules into a single file that can be packaged as a resource in your app. If you are running on the Android Emulator or iOS Simulator, you can run a local server on your development machine and hot-edit your JavaScript code by npx liquidcore server in your project root. If you are using the Bundle API (described below), and your app is built in debug mode, it will first attempt to get the bundles from the server. If the server is not available, it will use the automated bundle packaged at build time. In release mode, it will always use the packaged bundle.

Usage

The MicroService API

A micro service is nothing more than an independent Node.js instance whose startup code is referenced by a URI. For example:

Android Kotlin

iOS Swift

kotlin
val uri = MicroService.Bundle(androidContext, "example")
val service = MicroService(androidContext, uri)
service.start()
swift
import LiquidCore
...
let url = LCMicroService.bundle("example")
let service = LCMicroService(url: url)
service?.start()

The service URI can either refer to a server URL or a local resource. For services that are automatically bundled with your app by LiquidCore, you can use the MicroService.Bundle() or LCMicroService.bundle() methods to generate the correct URI. Any javascript entry files referenced in your package.json in liquidcore.entry will get bundled automatically with each build. By default, the initialization script creates and packages example.js, but you can easily change this.

A micro service can communicate with the host app once the Node.js environment is set up. This can be determined by adding a start listener in the constructor:

Android Kotlin

iOS Swift

kotlin
val uri = MicroService.Bundle(androidContext, "example")
val startListener = MicroService.ServiceStartListener {
    // .. The environment is live, but the startup
    // JS code (from the URI) has not been executed yet.
}
val service = MicroService(androidContext, uri,
    startListener)
service.start()

Conform to LCMicroServiceDelegate

swift
let service = LCMicroService(url:url,
                        delegate:self)
service?.start()
...
func onStart(_ service: LCMicroService) {
    // .. The environment is live, but the
    // startup JS code (from the URI) has
    // not been executed yet.
}

A micro service communicates with the host through a simple EventEmitter interface, eponymously called LiquidCore. For example, in your JavaScript startup code:

javascript
LiquidCore.emit('my_event', {foo: "hello, world", bar: 5, l337 : ['a', 'b'] })

On the app side, the host app can listen for events:

Android Kotlin

iOS Swift

kotlin
val listener = MicroService.EventListener {
    service, event, payload ->
    android.util.Log.i("Event:" + event,
        payload.getString("foo"))
    // logs: I/Event:my_event: hello, world
}
service.addEventListener("my_event", listener)

Conform to LCMicroServiceEventListener

swift
service.addEventListener("my_event", listener:self)
...
func onEvent(_ service: LCMicroService, event: String,
               payload: Any?) {
    var p = (payload as! Dictionary)
    NSLog(format:"Event: %@: %@", args:event, p["foo"]);
    // logs: Event:my_event: hello, world
}

Similarly, the micro service can listen for events from the host:

Android Kotlin

iOS Swift

kotlin
val payload = JSONObject()
payload.put("hallo", "die Weld")
service.emit("host_event", payload)
swift
var payload = ["hallo" : "die Weld"]
service.emitObject("host_event", object:payload)

Then, in Javascript:

javascript
LiquidCore.on('host_event', function(msg) {
   console.log('Hallo, ' + msg.hallo)
})

LiquidCore creates a convenient virtual file system so that instances of micro services do not unintentionally or maliciously interfere with each other or the rest of the Android/iOS filesystem. The file system is described in detail here.

Playing with example.js

When you follow the directions above, LiquidCore will automatically bundle a file called example.js, which looks like this:

…

Below is an example of how to interact with this JavaScript code from the app. Note that hello_text on Android and textBox on iOS are UI elements whose setup is not shown here.

Android Kotlin

iOS Swift

…
…

You can use this as a guide for how to create your own services. You can use npm install to install most JS-only (non-native) modules and require them as normal. The bundler will package all of the code into a single file.

API Documentation

Android Javadocs (liquidcore-Nodejs)

Android Javadocs (liquidcore-V8)

iOS Objective-C/Swift

License

Copyright (c) 2014 - 2020 LiquidPlayer

Distributed under the MIT License. See LICENSE.md for terms and conditions.

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

C++androidandroid-libraryiosios-library

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言