Skip to content
s edited this page Aug 3, 2026 · 7 revisions

Supernote Module Generator

Supernote Module Generator (better name pending) is an easy-to-use CLI tool designed to help leverage the strengths of native code without the hassle and frustration of having to deal with all the boilerplate and code registration that is usually required for using native code in React Native.

This tool is intended for use with an existing Supernote plugin.
If you do not yet have a plugin project, please refer to the official documentation first:

https://docs.supernote.com

The rest of this wiki assumes that you have already made a Supernote plugin, understand its project structure, and have read the official plugin documentation.

Why native code?

Most Supernote plugins can and should be written entirely in JavaScript or TypeScript.

Native code becomes useful when your plugin reaches a point where JavaScript is no longer enough. This normally happens because your plugin needs access to Android APIs, has reached a performance bottleneck, needs to use an existing native library, or some combination of the three.

For Supernote plugins, native code generally means Kotlin or Java running on Android, or C and C++ compiled directly for the device.

Native code can let your plugin:

  • Access Android APIs that are not exposed to JavaScript.
  • Use existing Kotlin, Java, C, or C++ libraries.
  • Move expensive processing out of JavaScript.
  • Avoid repeatedly sending large amounts of data through the normal React Native module system.
  • Expose a small synchronous API when JavaScript needs an immediate result.

Native code is not automatically faster. A badly designed native module can still be slow, especially if it constantly sends small values back and forth between JavaScript and the native implementation. The module type you choose and the way you divide the work both matter.

What does this tool do?

Adding native code to a React Native project normally requires a surprising amount of setup before you can write the code you actually care about.

Depending on the module type, you may need to create and connect Kotlin or Java classes, React Native registration, Gradle configuration, JNI bindings, CMake configuration, C or C++ source files, JSI installation code, and TypeScript declarations.

Supernote Module Generator creates and registers that boilerplate for you.

You choose the type of module you need, answer a few questions, and the generator adds a local package to your existing plugin. Once the module has been generated, you can open the implementation files and start working on the feature that required native code in the first place.

The goal is not to hide how native code works. You still need to understand the language, API, library, and performance decisions involved in your implementation. The goal is to remove the repetitive integration work and the many small registration mistakes that can prevent otherwise correct native code from working.

Modules

When using Supernote Module Generator, there are three types of native modules, each with its own use cases.

In the CLI, these are called Native Module, Native JNI Module, and JSI Module.

Native Module

Choose a Native Module if your plugin needs access to Android APIs or existing Kotlin and Java libraries, or if you prefer implementing the native part of your plugin in Kotlin or Java rather than JavaScript, TypeScript, C, or C++.

Native Modules are also a good choice for performance-sensitive operations that can be grouped into a small number of larger calls. Communication between JavaScript and Kotlin or Java has some overhead, but when requests and updates are batched rather than sent individually, the bridge is often not the limiting factor.

Learn how to implement Native Modules.

Native JNI Module

Choose a Native JNI Module if you need the performance, control, or library support of C or C++, but also want that code to work as part of a normal Android module with Kotlin, Java, Android APIs, and an asynchronous JavaScript interface.

A Native JNI Module is the middle ground between a regular Native Module and a JSI Module. JavaScript still uses the same Promise-based interface as a regular Native Module, while generated Kotlin and JNI code connect React Native and Android to your C or C++ implementation.

This is usually the best choice when a feature needs C or C++ processing but does not specifically need JavaScript to call it synchronously.

Learn how to implement Native JNI Modules.

JSI Module

Choose a JSI Module if you specifically need JavaScript to call C++ directly through a synchronous, low-overhead API.

JSI is most useful for short operations that need to be called frequently or return a result immediately. Because JSI functions run on the JavaScript thread, long-running work can freeze the plugin until it finishes.

JSI modules are implemented in C++. Other native languages with a C-compatible interface, such as Rust or Zig, can potentially be connected through a C or C++ wrapper, but the additional build configuration is not handled automatically by the generator.

Use JSI because your feature needs a direct synchronous API, not simply because you prefer writing C or C++. If you only need C or C++ processing and can return the result asynchronously, a Native JNI Module will usually be easier and safer.

You must also verify that the PluginHost version and firmware you are targeting allow the generated native library to load and execute.

Learn how to implement JSI Modules.

Documentation

Install the generator, run Doctor, choose a module type, and generate your first module.

Everything needed to create, use, validate, update, and troubleshoot a Native Module written in Kotlin or Java.

Everything needed to connect your plugin to C or C++ through JNI while keeping a Promise-based JavaScript interface.

Everything needed to expose synchronous C++ functions directly to JavaScript, including the important runtime limitations on Supernote.