¿Qué es SELF y por qué debería importarte?
Farid Zakaria, un ingeniero conocido por experimentar con formatos de archivo poco convencionales, publicó SELF, un formato donde el ejecutable de un programa es literalmente una base de datos SQLite. La idea de fondo suena a broma, pero la demo funciona: su servidor web de prueba (self-httpd) es un único archivo que es, al mismo tiempo, el programa compilado, el contenido del sitio, las rutas y el log de visitantes. Todo se lee y se escribe contra el propio binario.
Zakaria no parte de cero. Como él mismo reconoce, el trabajo previo de Justine Tunney con redbean — un servidor web que cabe en un único archivo portable entre Linux, macOS, Windows y los BSD — fue la inspiración. Según Hackaday, redbean corre "en seis sistemas operativos diferentes" gracias al formato APE (Actually Portable Executable), que embebe un ZIP dentro del binario (hackaday.com). SELF toma un camino distinto: en lugar de meter un archivo dentro de otro, hace que el archivo ya sea una base de datos.
Para un founder que despliega microservicios, side projects o herramientas internas, lo atractivo es obvio: un solo archivo = deploy terminado. Pero hay implicaciones más profundas cuando el estado de tu aplicación vive dentro del propio binario.
👥 ¿Quieres ir más allá de la noticia?
En nuestra comunidad discutimos las tendencias, compartimos oportunidades y nos ayudamos entre emprendedores. Sin humo, solo acción.
👥 Unirme a la comunidad¿Cómo funciona SELF por dentro?
El truco está en un detalle del formato SQLite que casi nadie usa: los 4 bytes de application ID, ubicados 68 bytes después del inicio del archivo. Zakaria los rellena con el texto "SELF" ("Structured Executable & Linkable Format"), y a partir de ahí organiza las distintas secciones del ejecutable ELF en tablas de SQLite. El esquema que usa está disponible en el repositorio fzakaria/selfdb (github.com/fzakaria/selfdb).
Para que el kernel de Linux ejecute ese archivo automáticamente, SELF se registra con binfmt_misc, un mecanismo del kernel que asocia un magic number con un intérprete. Zakaria usa NixOS para registrarlo de forma declarativa; sin NixOS, el equivalente en bash sería algo como:
printf '%s\n' ':self:M:68:SELF::/usr/local/bin/self-exec:' \
> /proc/sys/fs/binfmt_misc/register
Cuando lanzas ./server, el kernel no hace execve sobre el archivo: invoca self-exec y le pasa la ruta como argumento. El intérprete libera su propia conexión a SQLite y salta al punto de entrada del programa, que a su vez abre su propio archivo:
int main(int argc, char **argv) {
sqlite3 *db;
sqlite3_open(argv[0], &db); // el archivo que acaba de ejecutar el kernel
...
}
El argv[0] apunta a la ruta del ejecutable, así que el proceso puede leerse y escribirse a sí mismo de forma transaccional. Las escrituras persisten entre invocaciones. Simon Willison resumió el efecto en una línea: "Si redbean es un Actually Portable Executable, SELF es un Actually Queryable Executable. Uno corre en cualquier sitio; el otro, le puedes hacer SELECT" (simonwillison.net).
¿Qué cambia cuando tu estado vive dentro del binario?
La demo de Zakaria, self-httpd, lo muestra con claridad. Tres tablas, declaradas con SQL ordinario:
routes(path, mime, body): el contenido HTML y los tipos MIME.visits(id, at, ua, path): cada visita al servidor.presses(id, at, button): cada pulsación del botón de la página.
El pipeline de build es revelador:
$ cc -O2 server.c -o server.elf $(pkg-config --libs sqlite3)
$ elf2self server.elf server
$ sqlite3 server < site/schema.sql
$ sqlite3 server "INSERT INTO routes VALUES ('/index.html', 'text/html', readfile('site/index.html'))"
Compilas, conviertes el ELF en SELF, y luego alimentas la base de datos con SQL normal. El servidor arranca, sirve los archivos desde su propia tabla routes y registra visitas y presses en tablas que viven dentro del mismo archivo que está corriendo.
Lo más potente aparece cuando lo combinas con la maquinaria que ya tiene SQLite. Editar el sitio en caliente, por ejemplo, es un UPDATE:
$ sqlite3 server "UPDATE routes SET body = readfile('new.html') WHERE path = '/index.html'"
$ curl -s localhost:8080
<!doctype html><h1>edited in place</h1>
Sin reinicio, sin reload, sin deploy. Como las modificaciones son transacciones ACID, un ROLLBACK deshace el cambio. Y sqldiff te dice exactamente qué cambió entre dos builds:
routes: 1 changes, 0 inserts, 0 deletes, 2 unchanged
segments: 0 changes, 0 inserts, 0 deletes, 13 unchanged
Añadir búsqueda full-text al sitio en vivo es literalmente un CREATE VIRTUAL TABLE:
$ sqlite3 server "CREATE VIRTUAL TABLE search USING fts5(path, body); \
INSERT INTO search SELECT path, body FROM routes \
WHERE mime LIKE 'text/%'"
El servidor "sabe" buscar en sus propias páginas porque SQLite ya sabe hacerlo. No escribiste código de indexación.
¿Qué significa esto para tu startup?
Para founders que iteran rápido, SELF propone algo radical: el deploy vuelve a ser scp archivo. Zakaria lo compara con productos como exe.dev, que están popularizando esa simplicidad. SELF lleva la idea al extremo: cuando el código y el estado son el mismo archivo, un redeploy se convierte en una migración de datos, no en una orquestación de infraestructura.
Escenarios concretos donde esta idea es relevante:
- Side projects y prototipos: un solo archivo versionable en Git que ya contiene datos seed, rutas y assets. Sin árbol de directorios exótico, sin archivos sueltos en
/var/o/tmp/. - Herramientas internas para equipos pequeños: el "binario" es a la vez la base de conocimiento y el ejecutable. Cualquier auditor o desarrollador puede abrirlo con
sqlite3y entender qué está pasando. - Distribución de software con estado embebido: juegos单机, herramientas CLI que recuerdan preferencias, utilidades que mantienen su propio índice. Todo cabe en un archivo.
Tres acciones concretas que puedes tomar hoy:
- Clona
fzakaria/selfdby compilaself-httpd(github.com/fzakaria/selfdb). Aunque no adoptes SELF, el ejercicio mental de meter el estado dentro del binario te obliga a pensar qué dependencias tiene realmente tu aplicación. - Visita la demo en vivo en selfdb.exe.xyz y presiona el botón. Cada pulsación es un
INSERTen el ejecutable que te está sirviendo la página. Esa simpleza es el argumento de venta. - Audita tus propios binarios con
sqlite3. La próxima vez que un.bin,.dato archivo propietario te dé problemas, recuerda quehead -c 16 archivo | xxdpuede revelar que ya es una SQLite. Si lo es, puedes abrirlo y hacer consultas.
¿Dónde están los límites?
SELF es Linux-only hoy. Zakaria lo reconoce: depende de binfmt_misc, que no existe en macOS o Windows. La idea es portable a otros kernels (FreeBSD tiene un mecanismo similar), pero no esperes un ejecutable universal tipo redbean mañana.
Además, mezclar código y datos en el mismo archivo trae trade-offs reales: el versionado se vuelve más complejo (¿el cambio en visits cuenta como commit?), y los backups ahora requieren entender qué tablas son efímeras y cuáles son parte del binario. Para una startup en escala, probablemente prefieras seguir separando aplicación y base de datos. Pero como ejercicio de diseño, SELF te obliga a cuestionar qué partes de tu stack realmente necesitan existir como capas separadas.
Fuentes
- Actually Queryable Executables — Farid Zakaria
- Your executable is a SQLite database — Simon Willison
- Color Us Impressed: Redbean Runs A Web Server On Six Operating Systems — Hackaday
- fzakaria/selfdb — GitHub
👥 ¿Quieres ir más allá de la noticia?
En nuestra comunidad discutimos las tendencias, compartimos oportunidades y nos ayudamos entre emprendedores. Sin humo, solo acción.
👥 Unirme a la comunidad














