Cuando nos propusimos crear EditoraPDF, teníamos un objetivo claro: crear un editor de PDF completamente gratuito y de código abierto que respete la privacidad del usuario y funcione enteramente en el navegador. Sin servidores, sin subidas, sin rastreo: solo procesamiento puro del lado del cliente.
Esta es la historia de cómo lo creamos, los desafíos técnicos a los que nos enfrentamos y las decisiones que tomamos por el camino. Tanto si eres un desarrollador que quiere crear algo similar como si simplemente sientes curiosidad por el desarrollo de código abierto, esta publicación te ofrecerá una visión interna completa.
La visión: edición de PDF con la privacidad por delante
La mayoría de los editores de PDF de hoy en día te exigen subir tus documentos a sus servidores. Para documentos sensibles como contratos, historiales médicos o extractos financieros, esto es una pesadilla para la privacidad.
Queríamos crear algo diferente:
- Procesamiento 100 % del lado del cliente — los archivos nunca salen de tu navegador
- Sin necesidad de instalación — funciona directamente en los navegadores web
- Sin registro ni rastreo — uso completamente anónimo
- Código abierto — código transparente que cualquiera puede auditar
- Gratis para siempre — sin muros de pago ni suscripciones
Con estos principios en mente, empezamos a evaluar las tecnologías que podrían hacer realidad esta visión.
Cómo elegimos la pila tecnológica
Framework de frontend: Next.js 14
Elegimos Next.js 14 con el nuevo App Router por varias razones:
- Excelentes capacidades de SEO — renderizado del lado del servidor y gestión de metadatos de serie
- Soporte para exportación estática — despliega donde sea (Vercel, Netlify, GitHub Pages)
- Integración con TypeScript — seguridad de tipos y una mejor experiencia de desarrollo
- Optimización del rendimiento — división automática del código, optimización de imágenes
- Experiencia de desarrollo — recarga en caliente, excelente documentación, un enorme ecosistema
Renderizado de PDF: PDF.js
PDF.js de Mozilla es el estándar de oro para renderizar PDF en el navegador. Es lo que impulsa el visor de PDF integrado de Firefox.
Ventajas clave:
- Probado a fondo en millones de navegadores
- Excelente calidad de renderizado
- Capacidades de extracción de texto
- Renderizado basado en canvas para un mejor rendimiento
- Mantenimiento activo por parte de Mozilla
Manipulación de PDF: pdf-lib
Para crear y modificar PDF, usamos pdf-lib — una biblioteca de JavaScript puro que se ejecuta enteramente en el navegador.
Capacidades clave:
- Crear PDF desde cero
- Modificar PDF existentes (añadir páginas, rotar, eliminar)
- Incrustar texto, imágenes y formas
- Copiar páginas entre documentos
- Cero dependencias de Node.js
Gestión del estado: Zustand
En lugar de Redux, elegimos Zustand — una biblioteca de gestión del estado mínima y rápida.
- API sencilla — sin código repetitivo
- Diseño centrado en TypeScript
- Tamaño de paquete reducido (~1KB)
- No requiere proveedores de contexto
Estilos: Tailwind CSS
Tailwind CSS nos ofrece estilos utility-first con una excelente experiencia de desarrollo y paquetes de producción reducidos gracias a la depuración automática.
Arquitectura y decisiones de diseño
1. Procesamiento exclusivamente del lado del cliente
Todo ocurre en el navegador:
User uploads PDF ↓ PDF.js parses and renders to canvas ↓ User makes edits (text, images, shapes) ↓ pdf-lib creates new PDF with changes ↓ Download to user's device
En ningún momento el archivo sale del dispositivo del usuario. Esto es privacidad real por diseño.
2. Sistema de coordenadas normalizado
Un desafío importante: los PDF tienen diferentes tamaños de página y los usuarios pueden acercar y alejar el zoom. ¿Cómo hacemos para rastrear las posiciones de las superposiciones?
Solución: Normalizar todas las coordenadas al rango [0, 1].
// Instead of absolute pixels:
{ x: 150, y: 200 }
// We store normalized coordinates:
{ x: 0.25, y: 0.33 }
// Then scale to current viewport:
actualX = normalizedX * pageWidth * zoom
actualY = normalizedY * pageHeight * zoomEsto hace que las superposiciones sean independientes del zoom y portables entre diferentes tamaños de página.
3. Arquitectura de componentes
Estructuramos la aplicación en componentes específicos:
PdfViewer— renderizado del canvas principalThumbnails— barra lateral de navegación de páginasToolbar— controles de zoom, rotación y eliminaciónEditToolbar— selección de herramientas (texto, imagen, forma)AdvancedOverlayLayer— renderizado de texto, imágenes y formasExportButton— lógica de exportación de PDF
4. Patrón de gestión del estado
Nuestro store de Zustand mantiene:
{
originalFile: File,
pages: [
{
id: string,
originalIndex: number,
rotation: 0 | 90 | 180 | 270,
deleted: boolean,
textOverlays: [],
imageOverlays: [],
shapeOverlays: []
}
],
selectedPageId: string,
zoom: number,
editMode: 'select' | 'text' | 'image' | 'shape'
}Desafíos técnicos a los que nos enfrentamos
Desafío 1: precisión en la extracción de texto
PDF.js puede extraer texto, pero el posicionamiento no siempre es perfecto al píxel debido a cómo los PDF codifican el texto (a veces como caracteres individuales, a veces como palabras).
Solución: Extraemos los elementos de texto con sus matrices de transformación y los convertimos a coordenadas normalizadas con cuadros delimitadores generosos.
Desafío 2: rendimiento con PDF grandes
Renderizar PDF de más de 100 páginas puede bloquear el navegador.
Solución:
- Carga diferida de páginas (renderizar solo las páginas visibles)
- Usar requestAnimationFrame para un renderizado fluido
- Recomendar un límite de 25MB / 50 páginas
- Canvas fuera de pantalla para las miniaturas
Desafío 3: calidad de exportación
Incrustar texto e imágenes en pdf-lib requiere una transformación cuidadosa de coordenadas desde el espacio del navegador hasta el espacio del PDF.
Solución: Construir una canalización de transformación integral que gestione:
- Rotaciones de página
- Diferencias en el sistema de coordenadas (el eje Y está invertido en el PDF)
- Incrustación y tamaño de fuentes
- Conversión de formato de imagen
Desafío 4: compatibilidad entre navegadores
Los distintos navegadores tienen implementaciones de canvas ligeramente diferentes y peculiaridades en el renderizado de PDF.
Solución: Pruebas exhaustivas en Chrome, Firefox, Safari y Edge. Usar detección de funcionalidades en lugar de detección de navegador.
Por qué lo hicimos de código abierto
Desde el primer día supimos que esto tenía que ser de código abierto:
1. Transparencia = confianza
Al tratar con documentos sensibles, los usuarios necesitan verificar que los archivos realmente permanecen en local. El código abierto permite que cualquiera audite el código.
2. Contribuciones de la comunidad
El código abierto permite que desarrolladores de todo el mundo contribuyan con funcionalidades, corrijan errores y mejoren la herramienta.
3. Recurso de aprendizaje
Aprendimos muchísimo de los proyectos de código abierto. Ahora podemos devolver el favor y ayudar a otros a aprender Next.js, procesamiento de PDF y desarrollo web.
4. Longevidad
Aunque dejemos de mantenerlo, la comunidad puede hacer un fork y continuar el desarrollo. La herramienta sigue viva.
Los resultados
Tras meses de desarrollo, lanzamos EditoraPDF con:
El código base está disponible en github.com/affsquadDevs/editorapdf bajo la licencia MIT.
Conclusiones clave para desarrolladores
- ✓El procesamiento del lado del cliente es poderoso — Los navegadores modernos pueden manejar tareas complejas que antes requerían servidores
- ✓Elige las bibliotecas adecuadas — PDF.js y pdf-lib nos ahorraron meses de desarrollo
- ✓La normalización de coordenadas es fundamental — Hace que las superposiciones sean portables e independientes del zoom
- ✓El rendimiento importa — La carga diferida y la optimización son cruciales para los archivos grandes
- ✓El código abierto beneficia a todos — Transparencia, comunidad y aprendizaje salen todos ganando
Participa
EditoraPDF es un proyecto de código abierto, y damos la bienvenida a las contribuciones de desarrolladores de todos los niveles.
Preguntas frecuentes
¿Con qué pila tecnológica está construido EditoraPDF?
EditoraPDF está construido con Next.js 14, TypeScript, React 18, PDF.js para el renderizado, pdf-lib para la manipulación, Zustand para la gestión del estado y Tailwind CSS para los estilos. Es completamente de código abierto bajo licencia MIT.
¿Por qué elegisteis Next.js para un editor de PDF?
Next.js ofrece un rendimiento excelente, capacidades de SEO, soporte para exportación estática y una gran experiencia de desarrollo. El App Router facilita la creación de aplicaciones rápidas y optimizadas para SEO que se pueden desplegar en cualquier lugar.
¿EditoraPDF es realmente de código abierto?
Sí, EditoraPDF es 100 % de código abierto bajo la licencia MIT. El código fuente completo está disponible en GitHub en github.com/affsquadDevs/editorapdf
¿Cómo funciona el procesamiento de PDF del lado del cliente?
PDF.js renderiza los PDF en un canvas HTML dentro del navegador, mientras que pdf-lib manipula la estructura del PDF. Todo el procesamiento ocurre localmente en el navegador del usuario usando JavaScript, lo que garantiza total privacidad y seguridad sin ninguna subida a servidores.
¿Puedo usar el código de EditoraPDF en mi propio proyecto?
¡Por supuesto! EditoraPDF está licenciado bajo MIT, lo que significa que puedes usar, modificar y distribuir el código libremente, incluso en proyectos comerciales. Solo tienes que incluir el aviso de licencia original.
¿Cómo puedo contribuir al proyecto?
Consulta nuestra guía de contribución en GitHub. Puedes contribuir con código, reportar errores, sugerir funcionalidades, mejorar la documentación o ayudar con las pruebas.
Reflexiones finales
Crear EditoraPDF fue un recorrido desafiante pero gratificante. Aprendimos muchísimo sobre el procesamiento de PDF, las capacidades de los navegadores y el desarrollo de código abierto.
¿La mejor parte? Cualquiera puede ahora tomar este código, aprender de él, modificarlo o crear algo aún mejor. Ese es el poder del código abierto.
Si estás trabajando en un proyecto similar o simplemente sientes curiosidad por el código, echa un vistazo al repositorio de GitHub. Nos encantaría conocer tu opinión, responder a tus preguntas o revisar tus pull requests.