@irithell-js/canvas-termux
v1.0.7
Published
Canvas wrapper for Termux
Maintainers
Readme
@irithell-js/canvas-termux
Wrapper for the canvas module, specifically designed to resolve compilation and execution failures of native graphic dependencies on Termux (Android). The package acts as a Drop-in Replacement, providing full compatibility with existing code and supporting both CommonJS and ESM.
Architecture and Solution
Android-based systems use emulated partitions (FUSE/FAT) on /sdcard/ that do not have native support for creating symbolic links (symlinks). Since the generic canvas module depends on node-gyp to compile C++ code using symlinks and strict execution permissions, the traditional installation fails on the phone's internal storage.
The @irithell-js/canvas-termux resolves this bottleneck through an isolation architecture:
- Analytical Detection: Reads environment variables (
process.env.PREFIX) to identify if the current runtime is Termux or a standard Linux server. - System Dependency Injection: Triggers the system package manager (
pkg) to install repositories (x11-repo, tur-repo) and native graphic C libraries (build-essential, pango, libcairo, libpng, giflib, etc). - Hash Isolation: Calculates a unique MD5 identifier based on your project directory to create an aseptic build environment.
- Runtime & Background Compilation: Runs the native rebuild of the Canvas engine and injects the correct paths via a
.jsonstate file.
Installation
npm install @irithell-js/canvas-termuxHow to Use
Usage is identical to the original package. No refactoring is required in your current code; simply replace the import or require source.
CommonJS
const { createCanvas, loadImage } = require("@irithell-js/canvas-termux");
const config = { dimensions: [800, 600] };
const canvas = createCanvas(config.dimensions[0], config.dimensions[1]);
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 800, 600);ESM
import {
createCanvas,
loadImage,
registerFont,
} from "@irithell-js/canvas-termux";
const sizes = [1024, 768];
const canvas = createCanvas(sizes[0], sizes[1]);
const ctx = canvas.getContext("2d");
// Normal graphic processing...Version Control (Update & Downgrade)
By default, the proxy automatically fetches and compiles the latest version of the original canvas package. If you need to pin a specific version, downgrade, or update, you can do so seamlessly without cluttering your project with broken binaries.
There are two methods to specify the target version:
Method 1: Via package.json (Recommended)
You can define the desired version using a custom irithell block in your project's root package.json:
{
"name": "your-project",
"dependencies": {
"@irithell-js/canvas-termux": "^1.0.7"
},
"irithell": {
"canvasVersion": "3.2.3"
}
}Method 2: Via Environment Variable
You can force a specific version directly from the terminal, either at runtime execution or during installation:
# At runtime execution
CANVAS_VERSION=3.2.3 node app.js
# Or during installation
CANVAS_VERSION=3.2.3 npm install @irithell-js/canvas-termuxForcing the Rebuild Engine
If you wish to manually force a rebuild of the isolated engine at any time, simply run the installation script directly:
node ./node_modules/@irithell-js/canvas-termux/dist/install.cjsInternal Technical Features
Automatic Runtime Setup & Recovery
When package managers (such as npm, yarn, or pnpm) block postinstall scripts via --ignore-scripts, @irithell-js/canvas-termux intercepts the missing binary state during application initialization (require / import). It dynamically compiles and configures the engine on the fly before exporting the Canvas API, preventing application crashes.
Environment Migration (Cross-Environment Auto-Recovery)
When developing on Termux and later moving the entire project folder (including node_modules) to a Linux VPS or Docker container, binary architectures conflict.
The proxy registers metadata containing the source architecture at the time of installation. During execution on the new platform, the module intercepts the discrepancy in the C++ binary, cleans the outdated engine, and initiates a native rebuild focused on the new kernel.
Engine Management API
You can programmatically manage compiled Canvas engines directly from your code:
const {
listEngines,
getCurrentEngine,
deleteEngine,
clearAllEngines,
engineManager,
} = require("@irithell-js/canvas-termux");
// List all compiled engines in ~/.canvas_engines/
console.log(listEngines());
// Get info about the current project's engine
console.log(getCurrentEngine());
// Delete a specific engine by projectId (or current project's engine if omitted)
deleteEngine(); // or deleteEngine("92bddb13")
// Delete all compiled engines
clearAllEngines();
// Alternatively, use the helper object:
engineManager.list();
engineManager.current();
engineManager.delete("92bddb13");
engineManager.clearAll();Cleanup
If it is necessary to delete the compiled instances in Termux memory, the isolation directory is located at:
~/.canvas_engines/Changelog
[1.0.7]
- ESM Dynamic Require Fix: Resolved
Dynamic require is not supportederrors in ESM runtime and.mjs/.jsinstaller scripts by utilizing nativecreateRequire(import.meta.url)directly.
[1.0.6]
- Smart Package Pre-check: Added
dpkg-queryvalidation to skip runningpkg installif required system dependencies are already installed on Termux. - APT Sandbox Permission Fix: Added
-o APT::Sandbox::User=root --allow-unauthenticatedflags to prevent APT privilege drop crashes (fstaterrors) on Android devices. - Manual Resolution Help: Formatted clear error banners with Termux manual installation options.
[1.0.5]
- Fixed Termux Installation Abort: Removed
pkg upgrade -yfrom automatic installation commands to prevent Android file descriptor sanitizer (fdsan) crashes (apt full-upgradeaborts) and unnecessary system package upgrades. - Engine Management API: Added programmatic helper methods (
listEngines,getCurrentEngine,deleteEngine,clearAllEngines,engineManager) to inspect and manage compiled engine instances. - Graceful Repo Setup: Wrapped
pkg updateand repo installations in resilient execution handlers.
[1.0.3]
- Runtime Installation Integration: Moved engine verification and setup logic directly into runtime execution (
src/index.ts). Ifpostinstallis blocked or skipped, installation is triggered automatically upon module import. - Fixed
CANVAS_VERSIONEnvironment Variable:CANVAS_VERSIONis now dynamically evaluated both at runtime execution (CANVAS_VERSION=x.y.z node app.js) and during manual setup. - Removed
package.jsonAuto-Mutation: The installer no longer forcibly writes to the consumer'spackage.jsonfile, preventing unintended git modifications. - English Logs Standard: Standardized all system output, warning banners, and error messages to English.
- Direct Install Script: Maintained
dist/install.cjsas an optional direct CLI entrypoint.
[1.0.2]
- Cross-Environment Migration: Added automatic platform detection (
termuxvs standard environment) and auto-recovery upon environment switches. - Isolated Engine Architecture: Implemented isolated build directories in
~/.canvas_engines/.
[1.0.1]
- Version Pinning Support: Added support for custom
irithell.canvasVersionconfiguration block in consumerpackage.json.
[1.0.0]
- Initial Release: Canvas wrapper for Termux providing a drop-in replacement architecture.
