Inicio / Artículos

Cree herramientas para desarrolladores centradas en el cliente que no requieran una confianza ciega.

KitDev Space mantiene los hashes, JWT y archivos en el navegador; utiliza Bun únicamente cuando se requiere funcionalidad nativa o entre hosts diferentes, y marca el lugar de ejecución de cada herramienta.

Editor: REACTAPP.TOP6 min de lectura1438 palabras

Fuentes: How I built KitDev Space, an open source hub of developer tools that never has to ask you to trust it

Pegar un JWT de producción en el primer decodificador que sugiere un motor de búsqueda es una costumbre común. El objetivo es únicamente leer los datos del token, pero este sigue saliendo de la máquina. El mismo patrón se observa con los archivos .env en los convertidores y las fotos en los herramientas para extraer información EXIF: la política de privacidad afirma que el servidor no almacena nada, y esa afirmación se acepta sin cuestionamientos.

KitDev Space existe para reducir esa confianza ciega. Las herramientas diarias para desarrolladores no deberían requerir que se confíe en un operador, ni siquiera en aquel que creó el sitio. La estructura del producto sigue una regla inicial que se estableció por escrito y luego se consideró innegociable.

La regla

Preferir la ejecución en el lado del cliente. Involucrar al backend solo cuando el entorno de la página sea realmente incapaz de completar la tarea.

La primera mitad no es controvertida. La segunda mitad requiere una definición clara, de lo contrario todas las soluciones prácticas se trasladarían al lado del servidor. Las situaciones que realmente cumplen los requisitos fueron pocas:

  1. La tarea necesita una biblioteca nativa. La codificación de AVIF o la rasterización de SVG requieren un códec real. Abrir una conexión TLS necesita un socket.
  2. La tarea debe comunicarse con otro host. DNS, encabezados de respuesta, RDAP y vistas previas de OpenGraph fallan o deberían fallar desde una página debido a CORS.
  3. La tarea necesita una API en tiempo de ejecución sin su equivalente en el navegador, como Bun.dns o Bun.Archive.
  4. La entrada es demasiado grande para que una pestaña la contenga cómodamente.

Si una herramienta no cumple ninguno de estos requisitos, permanece en el lado del cliente. La conveniencia ha llevado a hacer excepciones cuando una ruta en el servidor tendría veinte líneas mientras que la ruta en el navegador tendría doscientas. Esas excepciones no se han implementado.

El navegador hace más de lo esperado

Las estimaciones iniciales suponían un código de servidor complejo. La mayor parte del trabajo relacionado con herramientas para desarrolladores ya se adapta a las API de la plataforma o a una pequeña dependencia que funciona sin salir de la página.

  • Helpers para el procesamiento de hashes desde SHA-1 hasta SHA-512 mediante crypto.subtle.digest
  • Entropía e identificadores a través de crypto.getRandomValues
  • Técnicas criptográficas simétricas —AES-256-GCM, PBKDF2, HMAC— en crypto.subtle
  • Ediciones geométricas (cambio de tamaño, rotación, recorte) con OffscreenCanvas junto a createImageBitmap
  • Exportación de imágenes estáticas en formato JPEG, PNG o WebP usando OffscreenCanvas.convertToBlob
  • Lectura de datos EXIF y GPS mediante el análisis de los bytes del archivo con DataView
  • Compresión y archivado (gzip, deflate, tar) a través de fflate
  • Formatos de configuración como YAML, TOML, JSONC y JSON5 a través de confbox
  • SQL en memoria con sql.js ejecutándose como WebAssembly
  • El panel JWT verifica las firmas HS256 con Web Crypto y omite por completo el uso de HTTP. La pantalla AES deriva los materiales necesarios con PBKDF2 dentro de la pestaña. El navegador de archivos abre archivos tar sin necesidad de subirlos. El estudio SQLite mantiene una base de datos en memoria. El patrón es sencillo: primero se examina la plataforma y luego se agrega una ruta solo si falta algo.

    Web Crypto todavía tiene limitaciones: no cuenta con MD5, ni CRC32, ni xxHash. Una biblioteca de MD5 en pura JavaScript podría realizar el hashing completamente localmente, pero la herramienta de hash también ofrece xxhash64 y wyhash, y enviar esos algoritmos poco utilizados a cada visitante parecía incorrecto. Esas opciones requieren una ruta en el servidor, y la interfaz de usuario indica claramente esa elección cuando se selecciona. Nombrar el modo que deja la operación en la máquina es mejor que fingir que nada se procesa.

    Un módulo, dos rutas

    Mantener versiones separadas del navegador y del servidor de una misma herramienta conduce a divergencias silenciosas. Dos convertidores pueden desviarse, y una misma entrada deja de funcionar correctamente según el entorno de ejecución. Un convertidor de formatos antiguo sufrió exactamente ese tipo de fallo.

    La estructura óptima consiste en un módulo compartido que exporta tanto al proceso de trabajo como a una pequeña sonda de capacidades. La interfaz de usuario consulta a dicha sonda, mientras que la ruta API importa ese mismo módulo. Por lo tanto, la lógica de hash se encuentra en un único lugar.

    // shared/utils/crypto/hash.ts
    const SUBTLE_NAMES = {
     sha1: 'SHA-1',
     sha256: 'SHA-256',
     sha384: 'SHA-384',
     sha512: 'SHA-512'
    }
    
    export function canHashInBrowser(algorithm: HashAlgorithm): boolean {
     return algorithm in SUBTLE_NAMES
    }
    
    // simplified page logic
    const result = canHashInBrowser(algorithm)
     ? await hashInBrowser(input, algorithm)
     : await $fetch('/api/hash', { method: 'POST', body: { input, algorithm } })
    

    El hash, la conversión de formatos, el formato del código y semver siguen todos esa estructura. Las nuevas herramientas con doble ruta heredan la misma organización en lugar de crear otra división.

    Para qué sirve realmente el servidor

    Las utilidades respaldadas por el backend se ejecutan en Bun. Cada una existe debido a una excepción específica:

    • La inspección de certificados abre un socket real para leer cadenas, SAN y cifrados acordados.
  • Las herramientas de salud de nombres y correos solicitan A/MX/TXT además de SPF, DKIM y DMARC.
  • La inspección de encabezados, las vistas previas de OpenGraph y RDAP requieren consultas a terceros.
  • Image Studio y el empaquetado de iconos favicon llaman a Bun.Image cuando es necesario generar archivos AVIF o ICO.
  • La transpilación de TS/JSX y los entornos de pruebas AST dependen de la implementación nativa de OXC.
  • Las rutas del servidor se consideran pasivos y comparten una misma lista de verificación previa al envío. Las URL deben ser válidas y solo pueden utilizar http o https. Se rechazan localhost, rangos privados, direcciones link-local, puntos finales de metadatos en la nube y formas de transición a IPv6 que ocultan el IPv4 (NAT64 y Teredo, que aparecen al crear esa lista de denegación). Los puertos de destino tienen un límite para que la inspección TLS no pueda escanear la red. Se verifica el contenido, los cuerpos de los datos se transmiten en flujo continuo y las lecturas se detienen al alcanzar un límite estricto en lugar de almacenarse en búfer indefinidamente. Los límites de velocidad utilizan una clave del cliente no relacionada con x-forwarded-for, lo cual es fácil de falsificar. Las subidas permanecen en memoria, nunca en disco. Ni las entradas ni las salidas se conservan.

    La analítica sigue la misma disciplina. Los eventos incluyen únicamente un id de herramienta y nada más. Se puede ver el uso del visualizador cron, pero no la expresión escrita.

    Hacer visible la regla

    Una regla que nadie puede ver es el marketing, no un control de privacidad. Por lo tanto, la navegación indica el lugar donde se ejecuta la acción.

    Cada entrada lleva una insignia. “Client” significa que la página nunca hace llamadas al servidor central. “Bun” indica que cada acción llega al backend. Las herramientas con ambos tipos de rutas omiten la insignia y especifican qué acción hace que se cierre la pestaña. Esas marcas se generan a partir de dos indicadores del registro, el mismo que gestiona los títulos y las búsquedas; así, la documentación no puede contradecir la implementación.

    El código tiene licencia MIT y está enlazado en el pie de página. La etiqueta “Client” puede ser verificada abriendo el módulo y comprobando que nunca llama a una ruta específica. La verificación, no la confianza, es el último elemento del diseño.

    ¿Qué hay dentro?

    El tamaño del catálogo cambia casi cada semana, por lo que cualquier conteo estaría desactualizado al día siguiente. Las utilidades más utilizadas, agrupadas por función:

    Trabajo con datos: formato atractivo para JSON que también acepta JSON5/JSONC, generación de tipos TypeScript a partir de JSON, movimiento libre entre YAML, TOML, XML y CSV (además de conversiones de filas CSV a inserciones SQL), navegación por tablas CSV extensas y ejecución del estudio SQLite en el navegador.

    Ayudas para desarrolladores: una pizarra de regex que narra cada token, un calendario cron de las próximas ejecuciones, conversores de cURL a fetch, Axios, Python o Go, convertidores de HTML/SVG para JSX o Vue, un entorno de pruebas glob y el navegador local de tar.

    Verificaciones de red: inspección de la cadena de certificados, consultas DNS, verificación del estado de autenticación de buzones, revisión de encabezados HTTP en bruto, cálculos CIDR, decodificación de cookies y búsquedas RDAP.

    Herramientas criptográficas: digestos, HMAC, inspección de JWT, códigos TOTP, encriptación/desencriptación AES, además de generadores de UUID y contraseñas.

    Herramientas de color: conversión a OKLCH, evaluación de contraste según WCAG, gradientes Tailwind, composición de gradientes CSS y extracción de paletas a partir de imágenes.

    Herramientas de imagen: recorte, redimensionado, rotación y conversión combinados, inspección o eliminación de datos EXIF, rasterización de SVG a PNG/WebP en resoluciones 1x/2x/4x, y un generador de iconos favicon que devuelve un archivo ZIP.

    No existen cuentas ni barreras de pago. El tema sigue las preferencias del sistema operativo, por lo que no hay un control separado para modo claro/oscuro.

    Detalles técnicos

    La pila de implementación se mantiene intencionadamente sencilla: Nuxt 4 con Nuxt UI 4 en el navegador, composables VueUse, editores CodeMirror, rutas gestionadas por Bun, pruebas con Vitest y Playwright, y despliegue en Vercel.

    Necesito tu ayuda

    Al probar https://kitdev.space, dos informes son de gran ayuda: cuál herramienta faltaba y si alguna herramienta envió datos al servidor cuando debería haberse quedado local. El segundo informe indica que existe un fallo en la regla.

    El repositorio está a un clic desde el pie de página. Se aceptan problemas y solicitudes de pull request para nuevas herramientas, correcciones o ajustes en las insignias. Un centro como este mejora con más participación; esa es la razón principal por la que el código fuente está abierto.

    Al crear utilidades similares en otro lugar, mantenga la misma lista corta de casos en los que el navegador realmente no puede completar la tarea. Todo lo demás debe ejecutarse en la máquina del usuario.

    Lecturas relacionadas

  • Cinco sugerencias rel de enlace que aceleran el primer dibujo contenido — Utilice preconnect, preload, dns-prefetch, prefetch y modulepreload en la sección head del documento para preparar las conexiones y reducir el consumo de recursos sin tener que reescribir la aplicación.
  • Cuando JavaScript deja de ser sintaxis y pasa a ser una herramienta — Los principiantes suelen buscar más código JavaScript cuando en realidad necesitan proyectos, retroalimentación y hábitos de resolución de problemas. Puntos de control prácticos y pruebas autónomas que convierten la sintaxis en una herramienta útil.