@capawesome/capacitor-nodejs

中文文档
0.2.0发布于 2026/10/15MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 2898

Capacitor plugin for running Node.js in mobile apps on Android and iOS.

原始使用文档
文档目录36 节
  1. Features
  2. Use Cases
  3. Compatibility
  4. Demo
  5. Installation
  6. Android
  7. iOS
  8. Configuration
  9. Examples
  10. Usage
  11. Set up the Node.js project
  12. Communicate with the Capacitor app from Node.js
  13. Start the Node.js runtime manually
  14. Wait for the Node.js runtime to be ready
  15. Exchange messages with the Node.js runtime
  16. Use npm packages
  17. API
  18. isReady()
  19. send(...)
  20. start(...)
  21. addListener('message', ...)
  22. addListener('ready', ...)
  23. removeAllListeners()
  24. Interfaces
  25. Type Aliases
  26. Limitations
  27. FAQ
  28. Which Node.js version is supported?
  29. Why is there no stop() method?
  30. Where should I store persistent data in the Node.js project?
  31. Why is JavaScript execution slower on iOS than on Android?
  32. Can I use this plugin with Ionic, React, Vue or Angular?
  33. Related Plugins
  34. Newsletter
  35. Changelog
  36. License

Capacitor Node.js Plugin

Capacitor plugin for running Node.js in mobile apps.[^1][^2]

Features

The Capacitor Node.js plugin is one of the most complete solutions for running Node.js in Capacitor apps. Here are some of the key features:

  • 🖥️ Cross-platform: Supports Android and iOS.
  • 🚀 Node.js runtime: Embeds a complete Node.js runtime based on Node.js for Mobile Apps.
  • 🧵 Background thread: Runs the Node.js engine on a dedicated background thread to avoid blocking the UI.
  • 🔁 Bidirectional communication: Event-based message passing between the Capacitor app and the Node.js runtime.
  • 📦 npm ecosystem: Use npm packages that are not browser-compatible and rely on Node.js core modules.
  • 🛠️ Configurable: Start the Node.js runtime automatically or manually with custom arguments, environment variables and script.
  • 🤝 Compatibility: Works alongside the Background Task, SQLite and Zip plugins.
  • 🔁 Up-to-date: Always supports the latest Capacitor version.

Missing a feature? Just open an issue and we'll take a look!

Use Cases

The Node.js plugin is typically used whenever an app needs functionality that only the Node.js ecosystem provides, for example:

  • Node.js-only libraries: Use npm packages that are not browser-compatible because they rely on Node.js core modules.
  • Code reuse: Reuse existing Node.js code in your mobile app instead of rewriting it for the browser.
  • Background processing: Offload heavy work to the Node.js engine, which runs on a dedicated background thread and does not block the UI.
  • Local data processing: Process and persist data on the device using the writable directory provided by the Node.js runtime.

Compatibility

Plugin VersionCapacitor VersionStatus
0.0.x>=8.x.xActive support

Demo

A working example can be found here.

Installation

You can use our AI-Assisted Setup to install the plugin. Add the Capawesome Skills to your AI tool using the following command:

npx skills add capawesome-team/skills --skill capacitor-plugins

Then use the following prompt:

 Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-nodejs` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

npm install @capawesome/capacitor-nodejs
npx cap sync

Attention: This plugin embeds the Node.js for Mobile Apps runtime binaries. The binaries are not included in the npm package but downloaded on demand: the Android binaries are downloaded by the Gradle build and the iOS binaries are downloaded during npm install (only on macOS). Set the CAPACITOR_NODEJS_SKIP_DOWNLOAD environment variable to 1 to skip the iOS download.

Android

Variables

If needed, you can define the following project variables in your app's variables.gradle file to use different runtime binaries:

  • $nodejsMobileAndroidUrl download URL of the Android runtime binaries (default: GitHub release of 18.20.4-capawesome.3, a 16 KB page size compatible build)
  • $nodejsMobileAndroidSha256 SHA-256 checksum of the Android runtime binaries download (default: checksum of the default download)

iOS

This plugin currently only supports Swift Package Manager. CocoaPods is not supported.

If you install dependencies with disabled lifecycle scripts (e.g. npm install --ignore-scripts), the iOS runtime binaries are not downloaded automatically. In this case, run the download script manually before building your app:

node node_modules/@capawesome/capacitor-nodejs/scripts/postinstall.js

Configuration

PropTypeDescriptionDefaultSince
nodeDirstringThe directory of the Node.js project, relative to the Capacitor webDir. Only available on Android and iOS.'nodejs'0.0.1
startMode'manual' | 'auto'The start mode of the Node.js runtime. If set to auto, the Node.js runtime starts automatically when the app is launched. If set to manual, the Node.js runtime must be started manually using the start(...) method. Only available on Android and iOS.'auto'0.0.1

Examples

In capacitor.config.json:

{
  "plugins": {
    "Nodejs": {
      "nodeDir": 'custom-nodejs',
      "startMode": 'manual'
    }
  }
}

In capacitor.config.ts:

/// <reference types="@capawesome/capacitor-nodejs" />

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    Nodejs: {
      nodeDir: 'custom-nodejs',
      startMode: 'manual',
    },
  },
};

export default config;

Usage

The following examples show how to set up the Node.js project, communicate between Node.js and the Capacitor app, start the runtime manually, wait for it to be ready, and exchange messages with it.

Set up the Node.js project

The plugin runs the Node.js project located in the nodejs directory (see the nodeDir configuration option) inside your Capacitor webDir. Make sure your web build outputs the Node.js project to this directory, for example by placing it in the public directory of your web project:

my-app
├── capacitor.config.json   // webDir: 'dist'
└── src
    └── public
        └── nodejs
            ├── package.json
            └── index.js

The package.json file of the Node.js project defines the script file to run in the main field:

{
  "name": "nodejs-project",
  "version": "1.0.0",
  "main": "index.js"
}

Communicate with the Capacitor app from Node.js

Inside the script file (index.js in this example), the built-in bridge module provides the communication channel to the Capacitor app:

const { app, channel } = require('bridge');

// Receive messages from the Capacitor app.
channel.on('my-event', (...args) => {
  // Send messages to the Capacitor app.
  channel.post('my-response', 'Hello from Node.js!');
});

// Get a writable directory for persistent file storage.
const dataDir = app.datadir();

// Listen for app lifecycle events.
app.on('pause', pauseLock => {
  pauseLock.release();
});
app.on('resume', () => {});

Attention: The Node.js project directory may be overwritten during app updates. Store persistent data in the directory returned by app.datadir().

Start the Node.js runtime manually

By default, the Node.js runtime starts automatically when the app is launched. If the startMode configuration option is set to manual, start it yourself with custom arguments, environment variables and script:

import { Nodejs } from '@capawesome/capacitor-nodejs';

const start = async () => {
  // Only available if the `startMode` configuration option is set to `manual`.
  await Nodejs.start({
    args: ['--option', 'value'],
    env: { MY_ENV_VAR: 'value' },
    script: 'custom-main.js',
  });
};

Wait for the Node.js runtime to be ready

The Node.js runtime is considered ready as soon as the Node.js project has required the bridge module. Check the current state with isReady() or listen for the ready event:

import { Nodejs } from '@capawesome/capacitor-nodejs';

const isReady = async () => {
  const { ready } = await Nodejs.isReady();
  return ready;
};

const addReadyListener = async () => {
  await Nodejs.addListener('ready', () => {
    console.log('The Node.js runtime is ready.');
  });
};

Exchange messages with the Node.js runtime

Once the Node.js runtime is ready, send messages to it and listen for messages received from it:

import { Nodejs } from '@capawesome/capacitor-nodejs';

const send = async () => {
  await Nodejs.send({
    eventName: 'my-event',
    args: ['Hello from Capacitor!'],
  });
};

const addMessageListener = async () => {
  await Nodejs.addListener('message', event => {
    console.log('Received message:', event.eventName, event.args);
  });
};

Use npm packages

To use npm packages, run npm install --omit=dev inside the Node.js project directory before building your web project. It's recommended to bundle the Node.js project into a single file (e.g. with esbuild) to improve the startup time.

API

isReady()

isReady() => Promise<IsReadyResult>

Check if the Node.js runtime is ready to receive messages.

The Node.js runtime is considered ready as soon as the Node.js project has required the bridge module.

Only available on Android and iOS.

Returns: Promise<IsReadyResult>

Since: 0.0.1


send(...)

send(options: SendOptions) => Promise<void>

Send a message to the Node.js runtime.

This method is only available when the Node.js runtime is ready. Use the isReady() method or the ready event to check if the Node.js runtime is ready.

Only available on Android and iOS.

ParamType
optionsSendOptions

Since: 0.0.1


start(...)

start(options?: StartOptions | undefined) => Promise<void>

Start the Node.js runtime manually.

This method is only available if the startMode configuration option is set to manual.

Attention: The Node.js runtime can only be started once per app launch. Stopping and restarting the Node.js runtime is not supported.

Only available on Android and iOS.

ParamType
optionsStartOptions

Since: 0.0.1


addListener('message', ...)

addListener(eventName: 'message', listenerFunc: (event: MessageEvent) => void) => Promise<PluginListenerHandle>

Called when a message is received from the Node.js runtime.

Only available on Android and iOS.

ParamType
eventName'message'
listenerFunc(event: MessageEvent) => void

Returns: Promise<PluginListenerHandle>

Since: 0.0.1


addListener('ready', ...)

addListener(eventName: 'ready', listenerFunc: () => void) => Promise<PluginListenerHandle>

Called when the Node.js runtime is ready to receive messages.

Only available on Android and iOS.

ParamType
eventName'ready'
listenerFunc() => void

Returns: Promise<PluginListenerHandle>

Since: 0.0.1


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all listeners for this plugin.

Since: 0.0.1


Interfaces

IsReadyResult

PropTypeDescriptionSince
readybooleanWhether or not the Node.js runtime is ready to receive messages.0.0.1

SendOptions

PropTypeDescriptionSince
argsMessageArg[]The arguments to send to the Node.js runtime.0.0.1
eventNamestringThe name of the event to send to the Node.js runtime.0.0.1

StartOptions

PropTypeDescriptionDefaultSince
argsstring[]The arguments to pass to the Node.js process.0.0.1
env{ [key: string]: string; }The environment variables to set for the Node.js process.0.0.1
scriptstringThe path of the script file to run, relative to the Node.js project directory.The main field of the package.json file of the Node.js project.0.0.1

PluginListenerHandle

PropType
remove() => Promise<void>

MessageEvent

PropTypeDescriptionSince
argsMessageArg[]The arguments received from the Node.js runtime.0.0.1
eventNamestringThe name of the event received from the Node.js runtime.0.0.1

Type Aliases

MessageArg

A single argument of a message that is exchanged with the Node.js runtime.

The value must be JSON-serializable.

string | number | boolean | null | MessageArg[] | { [key: string]: MessageArg }

Limitations

The underlying Node.js for Mobile Apps runtime has some limitations that you should be aware of:

  • Single instance: The Node.js runtime can only be started once per app launch. Stopping and restarting the runtime is not supported.
  • No child processes: The child_process module is not supported on mobile platforms.
  • No JIT on iOS: On iOS, the JavaScript engine runs in interpreter-only mode (no JIT compilation), which results in slower JavaScript execution compared to Android.
  • App size: Embedding the Node.js runtime increases the app size by several tens of megabytes per CPU architecture.
  • Native addons: Node.js native addons are only supported on Android if they are provided as prebuilds (see node-gyp-build) for the target architectures.
  • process.exit(): Calling process.exit() is not allowed by the Apple App Store guidelines.

FAQ

Which Node.js version is supported?

The plugin currently runs Node.js 18.20.4, the latest version available from Node.js for Mobile Apps. Support for newer Node.js versions requires self-built runtime binaries for mobile platforms, which we are evaluating.

Why is there no stop() method?

The underlying runtime only supports a single Node.js instance per app launch and provides no API to stop or restart it. A stop() method would therefore leave the app in a state where Node.js could never be started again until the app is restarted. If you need to stop work in the Node.js runtime, send a message (e.g. a shutdown event) and let your Node.js code stop its servers and timers. The idle runtime consumes negligible resources.

Where should I store persistent data in the Node.js project?

Store persistent data in the directory returned by app.datadir() of the built-in bridge module. The Node.js project directory itself may be overwritten during app updates, so any files written there can be lost.

Why is JavaScript execution slower on iOS than on Android?

On iOS, the JavaScript engine runs in interpreter-only mode without JIT compilation, which results in slower JavaScript execution compared to Android. This is a limitation of the underlying Node.js for Mobile Apps runtime. See the Limitations section for more details.

Can I use this plugin with Ionic, React, Vue or Angular?

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

  • Background Task: Run background tasks in your Capacitor app.
  • SQLite: Access SQLite databases with support for encryption, transactions, and schema migrations.
  • Zip: Zip and unzip files and directories.

Newsletter

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our Capawesome Newsletter.

Changelog

See CHANGELOG.md.

License

See LICENSE.

The embedded Node.js runtime and its bundled dependencies (V8, OpenSSL, ICU, libuv, and others) are distributed under their own licenses. See the Node.js license.

[^1]: This project is not affiliated with, endorsed by, sponsored by, or approved by the OpenJS Foundation or any of their affiliates or subsidiaries. [^2]: Node.js is a registered trademark of the OpenJS Foundation.

版本与发布记录

@capawesome/capacitor-nodejs 共发布 4 个版本,首次发布于 2026/07/06;过去 12 个月发布了 4 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.0latest2026/10/1524 天前
0.1.12026/09/022 个月前
0.1.02026/07/064 个月前
0.0.12026/07/064 个月前

关于 @capawesome/capacitor-nodejs 的常见问题

@capawesome/capacitor-nodejs 是什么?

Capacitor plugin for running Node.js in mobile apps on Android and iOS.

如何安装 @capawesome/capacitor-nodejs?

在项目目录运行 npm install @capawesome/capacitor-nodejs,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@capacitor/core(>=8.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@capawesome/capacitor-nodejs 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@capawesome/capacitor-nodejs 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@capawesome/capacitor-nodejs 可以商用吗?

@capawesome/capacitor-nodejs 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@capawesome/capacitor-nodejs 的下载量有多少?

根据 npm 官方下载统计,@capawesome/capacitor-nodejs 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,898 次,日均约 97 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@capawesome/capacitor-nodejs 还在维护吗?

最新版本 0.2.0 发布于 2026/10/15(24 天前);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/07/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。