OpenTTY brings a full Unix-like environment to J2ME feature phones. Execute RISC-V binaries, Lua scripts, manage processes, and experience modern CLI on old devices.
$ uname -a Nokia 6233 (OpenTTY 1.18.1) main/mod 2026-1.18.1-03x27 - CLDC-1.1 MIDP-2.0 $ ./hello.elf Hello from RISC-V ELF on J2ME! $ lua -e 'print(os.date())' Tue Apr 30 16:20:01 2026 $ ps PID PROCESS 1 init 1420 lua script.lua status: running
OpenTTY provides an unprecedented experience on J2ME phones: ELF loader, dynamic linking, POSIX syscalls, and full Lua environment.
Full RV32IM ELF interpreter. Support for PT_LOAD, dynamic sections, GOT/PLT relocation, and syscall translation layer.
Complete Lua interpreter with coroutines, tables, metatables, and custom modules: `os`, `io`, `socket`, `graphics`, `audio`, `push` API.
In-memory filesystem, persistent RMS storage, `/bin`, `/etc`, `/home`, and real FileConnection for memory cards. Full Unix-like paths.
TCP/UDP socket support, HTTP client, socket server API. Connect, bind, send/receive syscalls mapped to J2ME GCF.
Interactive UI via `graphics` module: Forms, Lists, TextFields, Images, Commands with callback handlers, LCDUI integration.
Multi-process model with UIDs, signalling, priority handling, and kernel IPC via request() mechanism. Sandboxed execution.
The core of OpenTTY includes a lightweight RISC-V RV32IM interpreter that reads ELF binaries, relocates symbols, resolves dynamic libraries, and traps syscalls. Combined with the Lua runtime, it offers both compiled C applications and scripting.
// ELF relocation handling (Java) switch(type) { case R_RISCV_JUMP_SLOT: writeIntLE(memory, offset, resolveSymbol(symName)); break; case R_RISCV_GLOB_DAT: symAddr = resolveSymbol(symName); writeIntLE(memory, offset, symAddr); break; } // RISC-V system instruction 0x00000073 : ecall
"OpenTTY brings the Unix philosophy to feature phones. It's more than a terminal — it's a full development and runtime environment for RISC-V binaries and Lua, all running inside the JVM."
ELF loader – independent bytecode interpreter – posix file abstraction – Lua FFI – graphics toolkit. Everything structured for extensions and lightweight memory usage (dynamic heap, 1MB base memory).
Compile with sdkcli.jar on a computer or directly on your mobile device using the on-device SDK
Download sdkcli.jar, open a terminal in the OpenTTY repository folder, and run the SDK CLI to build the project.
Open the OpenTTY source folder in the on-device SDK. Ensure all Java files are present.
Press the Build button (🛠️ hammer icon) and wait for compilation to finish.
After success, check the dist/ folder:
Method 1: Open OpenTTY.jar directly → install → launch.
Method 2: Use OpenTTY.jad for devices that prefer JAD installers.
Get the latest release, browse the repository, or test the web proxy. All resources are open-source and community-driven.
# download sdkcli.jar from http://opentty.fun/sdkcli.jar # then run it from the OpenTTY repository folder $ java -jar sdkcli.jar # or compile on-device $ open the OpenTTY folder in the on-device SDK $ click Build (🛠️) # output: dist/OpenTTY.jar + OpenTTY.jad # install on any MIDP 2.0 device