Skip to content

feat: implement user-defined apps#638

Closed
ngxson wants to merge 1 commit intocrosspoint-reader:masterfrom
ngxson:xsn/apps
Closed

feat: implement user-defined apps#638
ngxson wants to merge 1 commit intocrosspoint-reader:masterfrom
ngxson:xsn/apps

Conversation

@ngxson
Copy link
Contributor

@ngxson ngxson commented Jan 31, 2026

Summary

Important

This work is moved to my fork: ngxson/pluspoint-reader#2

This PR introduces the ability to load user-defined app at runtime, in form of a file saved in SD card. This opens the opportunity to add certain functionalities without having to compile it into the firmware.

image

Example of a simple app that updates a counter every second:

View the code
var count = 0;
var last_ms = 0;

var pageWidth = CP.getScreenWidth();
var pageHeight = CP.getScreenHeight();

while (true) {
  var now_ms = CP.millis();
  if (now_ms - last_ms >= 1000) {
    last_ms = now_ms;
    count += 1;
    CP.clearScreen(255); // white background
    CP.drawCenteredText(CP.FONT_UI_12, pageHeight / 2, "Hello World!", true, CP.TEXT_BOLD);
    CP.drawCenteredText(CP.FONT_UI_12, pageHeight / 2 + 20, "count = " + count, true, CP.TEXT_REGULAR);
    CP.displayBuffer(CP.FAST_REFRESH);
  }

  if (CP.btnIsPressed(CP.BTN_BACK)) {
    break; // exit the program
  }
}
image

Right now, I'm still testing this implementation on my emulator, things may not work as expected in real device. I'll try to finish this PR soon, just pushing this to share and keep track of the progress.

TODO:

  • More built-in functions (e.g., file system operations)
  • More documentation
  • More examples
  • More details on how to compile app to byte code
  • Handle exceptions better

Design consideration

Why JS?

When starting with this idea, I had some candidates to be considered: ELF loader (native binary), Java/wasm (byte code), JS/python (interpreted)

  • ELF loader: while this seems to be the most efficient implementation. However, ELF relocation for ESP32C3 (RISC-V) is almost non-existent
  • Java (FlintESPJVM): Given most old school Nokia phones run J2ME, this seems to be a reasonable choice. However, it may not be very intuitive for developers how to get started
  • Wasm (wasm3): same problem with java, the compiled app is also big
  • Python (micropython): seems to be promising, but it doesn't seem to be able to integrate micropython into existing projects

So, I was left with the last choice is to use JS. I initially experimented with elk which works well, but not performant enough. I ended up moving to mquickjs

Why mquickjs?

Compare to other JS runtime implementation on ESP32, mquickjs is quite interesting because it supports 2 modes:

  • Interpreter: run JS code as-is
  • Byte code: JS file can be compiled into a more space-efficient byte code format on host machine

This is quite important because program code must be loaded into heap to be executed. Being able to compile code into byte code make it possible to write more complicated apps without taking too much space.

While this implementation uses ~120KB from flash usage, which is quite a lot, it does make sense because:

  • It contains both the interpreter and runtime, but we can consider to maybe only include the runtime to save flash space
  • Future apps can be delivered via this infrastructure, avoid adding too many built-in apps to the firmware
PR:
RAM:   [===       ]  32.5% (used 106540 bytes from 327680 bytes)
Flash: [==========]  96.8% (used 6344126 bytes from 6553600 bytes)

master:
RAM:   [===       ]  32.5% (used 106508 bytes from 327680 bytes)
Flash: [========= ]  94.9% (used 6217222 bytes from 6553600 bytes)

Limitations

Please note that I don't plan to include any networking functionalities in the initial version. They will be added the next iteration.

  • Apps cannot run on the background, similar to old nokia phones or the flipper zero
  • Max app size is currently set to 32KB and max memory is set to 64KB. This is to allow having some spare memory to handle networking in the future

AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code?

Except for some comments being auto-completed by the IDE, all of the code here is written by human

@ngxson
Copy link
Contributor Author

ngxson commented Feb 1, 2026

Per discussion from #640, I'm closing this PR and moving it to my fork

@ngxson ngxson closed this Feb 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant