Skip to content

Getting Started

s edited this page Aug 1, 2026 · 3 revisions

Getting Started

This tutorial starts with an existing Supernote React Native plugin and ends with a Kotlin add(left, right) function running on a device. JNI and JSI use the same example in their focused pages.

1. Install the generator

Python 3.9 or newer is required:

python3 -m pip install supernote-module-generator

Confirm the installed version:

supernote-module --version

See Compatibility before installing Android or C/C++ tools.

2. Open the existing plugin root

Run the generator from the exact directory containing all of these markers:

PluginConfig.json
package.json
android/
android/settings.gradle       # or settings.gradle.kts

The generator does not search parent directories. The official Supernote template creates PluginConfig.json during its first packaging run. If a new plugin does not have it, package the unmodified plugin once before continuing.

Check the plugin and Native toolchain without changing files:

supernote-module doctor --type native

3. Generate local-math

From the plugin root, start the guided interface:

supernote-module

Choose Add module, then Native Module, and answer:

Prompt Answer What it controls
Package name local-math Folder, npm/Yarn dependency, and TypeScript import string
Description leave empty Optional local package metadata
JavaScript name accept Math Object registered with React Native
Android namespace accept com.example.math Kotlin/Java package and source path
Package version accept 0.1.0 Local module version, not the plugin version
Install the local dependency now? Yes Runs npm or Yarn so autolinking can find the package

The three identities—package name, JavaScript name, and Android namespace—must be unique among managed modules. Update cannot rename them or change the module type.

4. Implement add

Edit this user-owned starter file:

local_modules/local-math/android/src/main/java/com/example/math/Example.kt

Replace its contents with:

package com.example.math

import com.example.math.nativemodule.annotation.SupernoteExport

class Example {
  @SupernoteExport
  fun add(left: Double, right: Double): Double = left + right
}

The annotation tells the generator's Android build step to expose the method to JavaScript. Do not edit generated bridge or registration files.

5. Call it from TypeScript

Native value-returning exports are asynchronous from JavaScript, so use the package's default import and await:

import React, {useState} from 'react';
import {Button, Text, View} from 'react-native';
import Math from 'local-math';

export default function App(): React.JSX.Element {
  const [result, setResult] = useState('Not run');

  async function runAdd() {
    try {
      const value = await Math.add(20, 22);
      console.log('Math.add result:', value);
      setResult(String(value));
    } catch (error) {
      console.error('Math.add failed:', error);
      setResult(String(error));
    }
  }

  return (
    <View>
      <Button title="Run native add" onPress={runAdd} />
      <Text testID="math-result">{result}</Text>
    </View>
  );
}

6. Build the plugin package

If generation used --skip-install, first link the local dependency with the parent plugin's package manager:

npm install

or:

yarn install

Package on macOS or Linux:

./buildPlugin.sh

Package in Windows PowerShell:

.\buildPlugin.ps1

For the official template's default name, the result is:

build/outputs/plugin.snplg

If PluginConfig.json uses another plugin name, use the filename actually written to build/outputs/. The generator's --build option only runs the parent Gradle :app:assembleDebug task; it does not replace the packaging script or prove that a .snplg was produced.

7. Transfer and install

Copy the package with Android Debug Bridge (ADB):

adb push "build/outputs/plugin.snplg" /storage/emulated/0/MyStyle/

This transfers the file; it does not install it. On the Supernote, open Settings > Apps > Plugins > Add Plugin, select the package, and install it. The official parent-plugin workflow is also documented in Supernote's Your First Plugin guide.

8. Verify the call

Open the plugin and press Run native add. The UI should show 42.

Inspect JavaScript logs when it does not:

adb logcat -d -s ReactNativeJS:V '*:S'

For generated Native bridge errors, include the module tag:

adb logcat -d -s SupernoteNativeMath:V ReactNativeJS:V '*:S'

9. Protect your source

Kotlin/Java implementation under the module's android/src/main/java/ tree is user-owned, except generated packages. Update replaces metadata, wrappers, declarations, Gradle wiring, generated bridge code, and the generated README. Remove deletes the entire package, including implementation source.

Commit before Update or Remove, then read Managing Modules.

Continue by module type

Clone this wiki locally