Español

Descubriendo JUX 3.0 (Parte I)

28 / 03 / 2026

Una masterclass de “ingeniería de guerrilla” en su módulo Install

Llevo años peleándome con pipelines de integración continua, el peso muerto de la carpeta node_modules y las eternas actualizaciones del composer.lock. Cuando llevas el suficiente tiempo en la industria, dejas de ser un fanático de la tecnología de moda y empiezas a valorar una sola cosa: el pragmatismo absoluto. Y entonces, me topé con JUX Framework 3.0.

JUX no es un framework cualquiera. Sus credenciales rezan que es un "Web OS" o un motor táctico sin dependencias. Al principio, como buen escéptico asqueado del hype, no me lo creí. "Claro, sin dependencias hasta que tengas que minificar un JS o hacer un backup remoto", pensé.

Entonces me aventuré en su código fuente, abrí el archivo _classes_/install.class.php (unas modestas 600 líneas) y el módulo _modules_/install. Lo que leí me dejó completamente de piedra. El nivel de autosuficiencia y de "ingeniería de guerrilla" que encierra este script es fenomenal.

Aquí desgrano tres virguerías arquitectónicas que me han volado la cabeza en mi primera expedición por el núcleo de JUX.


1. El Transpilador SQL de Trinchera

El santo grial de cualquier ORM moderno (tipo Doctrine o Eloquent) es ser agnóstico a la base de datos. Para lograrlo, estos mamuts te obligan a aprender sus pseudo-lenguajes abstractos y generan miles de archivos cacheados.

JUX abofetea esta idea con su método Install::runsql(). El framework permite escribir el esquema estructural o las consultas en puro dialecto MySQL (con sus INT(11), UNSIGNED, `AUTO_INCREMENT`, y ENGINE=MyISAM). Pero cuando llega el momento de la ejecución, el instalador evalúa el entorno de la aplicación.

Si descubre que estás corriendo una base de datos ligera SQLite, en lugar de importar una librería de traducción abstracta, aplica una brutal y elegante cadena de reemplazos de strings en tiempo real:


if (str_starts_with(trim($sql),'CREATE')){
    if (CFG::$vars['db']['type']=='sqlite') {
        $sql = str_replace( array(
            'UNSIGNED', 'INT(11)',
            'ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci',
            'NOT NULL AUTO_INCREMENT'
        ), array(
            ', 'INTEGER',
            ',
            'PRIMARY KEY AUTOINCREMENT'
        ), $sql);
    }
}
    

¿Es elegante bajo los dogmas puristas universitarios? Probablemente no. ¿Funciona al milisegundo, es inmune a fallos de dependencias y traduce sentencias complejas al instante? Hell yes. Escribes el esquema de tu módulo una sola vez, y JUX lo transmuta mágicamente. Pragmatismo al 100%.

2. Minificación y Ofuscación sin Node.js

Este es el momento en el que el ecosistema JUX se revela como un repositorio auto-contenido. Si configuras una instalación de JUX como nodo maestro, éste puede compilar módulos y empujarlos en un archivo .zip para su Marketplace.

Pero ¿qué pasa con los assets? En Laravel o Symfony, necesitaríamos levantar un proceso de Webpack o Vite. En JUX, el método recursivo addToZip() tiene un simple booleano $compress. Cuando está activo:

  • Captura los archivos .css y .js e intenta correr un proceso de minificado puro nativo.
  • La genialidad: Si el archivo interceptado es un .php, invoca implacablemente a la función interna php_strip_whitespace().

Literalmente abstrae, ofusca y comprime el código backend, además de inyectar por expresión regular una cabecera de copyright /* (c) JUX 3.0.1 */, justo antes de pasárselo a la librería nativa ZipArchive. Tienes un "Build System" inyectado en un bucle rudimentario. No hay fallos de compilación, no hay scripts npm run build olvidados. El código es su propio empaquetador.

3. Backups Nativos Fragmentados

Pregúntale a diez desarrolladores cómo hacen un volcado de base de datos desde PHP, y nueve te dirán que ejecutan llamadas bloqueantes vía exec('mysqldump ...') dependientes de los binarios del alojamiento.

JUX no asume que tengas terminal de comandos ni permisos SSH instalados. Los métodos backup_sqlite() y backup_mysql() operan un lector de esquemas pasivo. Extraen las descripciones de las tablas y, sin utilizar memoria excesiva, construyen enormes archivos array backup.php con una secuencia de asignaciones estáticas $sqls[] = "INSERT INTO...".

Lo más fascinante es cómo gestionan la memoria. Cortan literalmente las consultas INSERT agrupándolas en secuencias ("chunks") calculando de manera precaria pero matemática la longitud del string $n = $n + strlen($tmp_str).


if ($n >= $max && $i < $row_count){
    // Cerramos el chunk sintáctico e iniciamos la siguiente inyección para vaciar búfer
    $tmp_str .=  '";' . "
" . '$sqls[] =  "INSERT INTO '.$table." (".$str_fields.") VALUES ";  
    $n = 0;
}
    

Una vez completado el volcado, lo inyectan al vuelo en un archivo ZIP, te dan el link de descarga protegido y borran el rastro físico temporal de backup.php mediante un rápido unlink(). Restaura la base de datos con un clic, arrastrando el ZIP ciegamente. Pura ingeniería de resistencia.


Conclusión

Cuando observas proyectos enormes saturarse por su propia escala dogmática de Arquitecturas Hexagonales y Microservicios, examinar JUX Framework supone un alivio balsámico. Sus creadores han entendido perfectamente un axioma ignorado por muchos: el mejor código no es el que respeta todas las normas de la programación orientada a objetos moderna; es aquel que sobrevive independiente, resuelve el problema rápido y no te obliga a compilar 30 gigas de módulos de node.

Y esto es solo indagando en un archivo de seisientas líneas para despliegues. En la próxima entrega de esta serie, analizaré las coléricas entrañas de su proxy SQL (MyCache) y cómo intercepta el Lexer SQL para aniquilar Stale Data en Redis. Spoiler: es tan transgresor como te estás imaginando.

Nos leemos en la siguiente sesión de código.