Skip to content

Support user apps#2

Merged
ngxson merged 11 commits intomasterfrom
xsn/mqjs
Feb 2, 2026
Merged

Support user apps#2
ngxson merged 11 commits intomasterfrom
xsn/mqjs

Conversation

@ngxson
Copy link
Owner

@ngxson ngxson commented Feb 1, 2026

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 considerations

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

@ngxson ngxson changed the title Xsn/mqjs Support user apps Feb 1, 2026
@ngxson ngxson merged commit eb4f749 into master Feb 2, 2026
1 check passed
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