Saltar al contenido principal
← ~/projects
cat ~/projects/snapcompress/CASE.md

SnapCompress

Herramientas de imagen que se ejecutan en tu navegador: comprimir, convertir, redimensionar y recortar sin subir nada

// 01

Caso práctico

## El problema

Los compresores y convertidores online suelen pedirte que subas la imagen a su servidor. Para una foto del móvil, un escaneo o una captura con datos personales, es mucho pedir a cambio de reducir un archivo.

Quería hacer lo mismo sin que la imagen saliera del dispositivo y sin cuenta. Si ningún servidor procesa la imagen, tampoco hay nada que guardar ni que filtrar.

## Decisiones clave

  1. Todo ocurre en el navegador

    La compresión usa browser-image-compression; la conversión a WebP y PNG, códecs WebAssembly (jSquash); el HEIC del iPhone se decodifica con heic-to; el redimensionado y el recorte, la API Canvas. La web dice que las imágenes no salen del dispositivo, y la arquitectura lo hace cierto.

  2. Next.js 16 con React Compiler, en Vercel

    El servidor solo atiende el boletín opcional y el formulario de contacto; ninguno recibe imágenes. Las rutas del boletín tienen límite de peticiones. Hotjar, Clarity y Umami se cargan solo después de aceptar las cookies; Google Analytics arranca en modo de consentimiento denegado.

  3. El decodificador RAW, solo como reserva

    La mayoría de los DNG, incluidos los ProRAW del iPhone, se abren con la vista previa JPEG incrustada. El decodificador RAW completo queda para los que no la traen, que son poco frecuentes.

## Qué salió mal

  1. 641 pruebas en verde y fallos reales (revisión del 5 de junio de 2026)

    La revisión de calidad encontró que la tarea programada del boletín no comprobaba la autenticación si faltaba la variable CRON_SECRET, que las rutas del boletín no tenían límite de peticiones y que el recorte deformaba las imágenes no cuadradas al girarlas 90° o 270°. El propio documento de la revisión marca los tres como corregidos.

  2. Mi documentación decía algo que el código no hacía

    Un documento afirmaba que las tres herramientas usaban Web Workers. Era falso: a 5 de junio de 2026 solo la compresión y la conversión a JPEG corrían en un worker; el redimensionado y la conversión a WebP y PNG iban en el hilo principal. Lo corregí en el documento, no en el comportamiento.

  3. Turbopack se colgó con el decodificador RAW (23 de septiembre de 2026)

    La compilación de producción con Turbopack se quedaba colgada con libraw-wasm, el decodificador RAW. El comentario turbopackIgnore no lo arregló. Lanza workers de sí mismo para su pool de hilos. El 23 de septiembre de 2026 decidí compilar una versión de un solo hilo de la librería, y al día siguiente la compilación de producción pasó a Turbopack.

## Qué haría distinto

  • Decidiría desde el principio qué corre en un worker y lo mediría, en vez de dejar que lo decida la librería que toque.
  • Probaría la compilación de producción con el empaquetador real antes de adoptar una librería WebAssembly que lanza sus propios workers.
  • Pondría límite de peticiones y la comprobación de secretos ausentes al crear cada ruta de servidor, no en una revisión posterior.
  • Documentaría lo que el código hace hoy, con fecha, y no lo que pretendo que haga.

## Cifras, solo medidas y con fecha

641
pruebas unitarias en verde al hacer la revisión de calidad, junto con el tipado, el lint y la compilación de producción · 5 de junio de 2026

No publico porcentajes de compresión: el ahorro depende de cada imagen y no lo he medido. Tampoco tengo cifras de uso.

// 02

Tecnologías y enlaces