Las preguntas generales (qué es AfterPack, si es gratuito, si rompe tu aplicación) se responden en las preguntas frecuentes de la página principal. Esta página entra en el detalle a nivel de build.
¿Qué diferencia hay entre Free y Pro?
Free ejecuta el pipeline completo de forma uniforme en todo el bundle. Pro añade puntería: marcas una región y solo ese código recibe el tratamiento intensivo. Niveles tiene la matriz completa y los precios.
¿Necesito el plugin del framework?
Para un framework con soporte de primera clase, sí. Instala el plugin como dependencia de desarrollo y añade una línea de configuración, y tu build habitual emitirá salida ofuscada. Dónde se ejecuta el motor depende del bundler: Vite, Rollup, webpack y Parcel ofuscan dentro del propio pipeline del bundler, Next.js ofusca desde un hook dentro de next build, y esbuild y Angular ejecutan una pasada cuando su build ha terminado de escribir.
$ npm install -D @afterpack/vitePara stacks de bundler puro o sin plugin, apunta la CLI a la salida de tu build:
$ npx afterpack@latest dist/En ambos casos, AfterPack se ejecuta estrictamente después del build, sobre la salida compilada. El directorio de build es opcional: sin él, la CLI detecta la salida de tu build. La CLI también es la vía para CI y para ejecuciones manuales puntuales en frameworks con plugin.
¿Por qué el mismo código produce una salida distinta en cada build?
Es el polimorfismo por build, y es la defensa principal. Con la semilla aleatoria por defecto, dos builds de la misma entrada salen estructuralmente distintos. Un desofuscador estático que aprende la forma del build N no obtiene nada reutilizable para el build N+1, así que recompilar producción periódicamente reinicia una y otra vez el progreso del atacante.
Cuando necesites bytes idénticos, para aciertos de caché en CI o tests con snapshots de referencia, fija la semilla con --seed:
$ npx afterpack@latest dist/ --seed=gitEl modelo de publicación: los builds de desarrollo no se ofuscan para iterar rápido; producción compila el artefacto ofuscado una sola vez y promociona los mismos bytes por qa, preprod y prod. Consulta Builds y CI.
¿Free es solo renombrado?
No. Free ejecuta el motor completo. El preset light por defecto renombra los identificadores y codifica cada literal de cadena que puede reescribir. A partir de medium, Free también aplana el flujo de control, fusiona e infla la lógica y materializa constantes, todo dentro de un archivo. Esa salida se reestructura, no solo se reetiqueta, y se queda en la clase de reversión polinómico-inyectiva: la estructura original solo puede recuperarse con un esfuerzo real que se renueva en cada build.
¿Una directiva afecta solo a una línea?
No. Una directiva abarca toda una región, no solo su propia línea. Abre un bloque con /* @afterpack preset=hard */ solo en la línea anterior a una función y ciérralo con /* @afterpack end */ después de la llave de cierre, y cubrirá la función entera, cuerpo incluido:
/* @afterpack preset=hard */
export function checkLicense(token: string) {
// the entire function body is covered
}
/* @afterpack end */Esa es la forma de bloque: una apertura sola en su línea, cerrada por el /* @afterpack end */ correspondiente. Para un único valor, un /* @afterpack preset=extreme */ en línea cubre el resto de su línea, el literal o la expresión que viene justo después. Consulta Directivas para la gramática completa.
¿Qué pasa si la nube Pro está caída?
Reintenta con espera progresiva y después falla de forma segura (fail closed): una caída de la nube rompe la CI en lugar de publicar menos protección de la que pediste.
Si no quieres ninguna dependencia de terceros en el camino del build, ejecuta Free en local: nunca hace una llamada de red. Consulta Modos de despliegue.
¿Cómo funcionan los source maps?
Los source maps de AfterPack enlazan la salida ofuscada con tu código fuente original. Son útiles para depurar en local. Nunca publiques uno en producción: un .map público le da al atacante un camino directo al código fuente que acabas de ofuscar.
AfterPack los mantiene fuera de tu bundle de producción por defecto: la emisión de source maps está desactivada en un build de producción, el comentario //# sourceMappingURL= se elimina y los source maps que escribió tu bundler se borran, incluidos los de CSS. Todo build es de producción salvo que diga que es de desarrollo, también un npx afterpack en local. Consulta Buenas prácticas.
¿Puedo usar AfterPack en CI?
Sí. En un framework con soporte de primera clase, el plugin se ejecuta como parte de tu build habitual, así que tu paso de build actual ya emite salida ofuscada. En otros stacks, añade npx afterpack@latest <path> como paso posterior al build.
Fija la semilla al identificador de tu versión para obtener artefactos reproducibles, compila la salida ofuscada una sola vez y promociona los mismos bytes por tus entornos. Audita cada versión y adjunta el Protection Map como artefacto de CI. Consulta Builds y CI para un ejemplo de pipeline completo.
¿La ofuscación ralentiza mi código?
Moderadamente. Reestructurar el flujo de control y reconstruir constantes añade trabajo en tiempo de ejecución, pero en una aplicación web típica el coste suele ser pequeño en comparación con el tiempo de red y de renderizado.
Cuanto mayor es el preset, más cuesta: cada peldaño corresponde a una complexity más alta, y el predeterminado es light. Un preset más pesado aplica más transformación; no es un aumento medido de la protección. Mantén el preset global en light salvo que uno más pesado compense su coste, y reserva extreme para las regiones que marques. La escalera y sus valores están en Presets.
¿Cómo protejo las claves de API y la lógica de licencias?
Márcalas. Usa un /* @afterpack preset=extreme */ en línea sobre un literal secreto, y envuelve la función que controla las licencias en un bloque /* @afterpack preset=hard */ … /* @afterpack end */:
const LICENSE_SECRET = /* @afterpack preset=extreme */ "YOUR_SECRET";
/* @afterpack preset=hard */
export function checkLicense(token: string) {
/* ... */
}
/* @afterpack end */preset=extreme sube esa región al objetivo de complejidad 25 con el mínimo de cadenas forzado, así que el literal se codifica en lugar de publicarse en claro. Sigue existiendo en la salida, y el programa lo reconstruye al usarlo. Para dejar fuera de la salida por completo un literal con el que tu código compara, activa transforms.comparisonHardening.enabled: la comparación se convierte en una comprobación de digest unidireccional y solo se publica el digest. En cualquier caso, un atacante que ejecute el código bajo un runtime instrumentado todavía puede llegar al valor (consulta la siguiente pregunta). Estas directivas elevan el coste de la recuperación estática en cada versión. No convierten un secreto de alto valor en algo seguro de guardar en el cliente. Consulta Buenas prácticas para el patrón completo.
¿Puede alguien que ejecuta mi código extraer un secreto?
Sí. Un atacante decidido que ejecute tu código bajo un runtime instrumentado puede llegar a cualquier secreto que use el propio código. Ningún ofuscador en tiempo de build cambia eso: si el programa en ejecución necesita el valor para hacer su trabajo, es observable para quien parchee el runtime, intercepte la llamada adecuada o haga una instantánea del heap en el momento justo.
AfterPack hace que el valor sea invisible para los ataques más baratos: el lector estático y el LLM a ciegas que explica código sin ejecutarlo. La no materialización mantiene un literal protegido completamente fuera del artefacto, el mínimo de cadenas evita que el resto aparezca en claro, y el polimorfismo por build hace que las herramientas escritas contra los patrones de un build fallen en el siguiente. Quien ejecuta el código todavía puede leer los valores que usa.
La ofuscación eleva el coste estático y el de volver a extraer un secreto del lado del cliente. La única forma de mantener un secreto de alto valor fuera del alcance de un atacante es no enviarlo nunca al cliente: mantenlo en el servidor y deja que sea el servidor quien tome la decisión. Usa preset=extreme para los secretos que de verdad no pueden trasladarse al servidor, y trátalo como algo que eleva el coste, nunca como una caja fuerte.
¿Qué frameworks son compatibles?
Estos stacks tienen un plugin publicado: Next.js, Vite, Webpack, Rollup, esbuild, Astro, Svelte, SvelteKit, Vue 3, Nuxt 3, Angular v17+, Electron y Parcel. Un plugin conoce su propio directorio de salida, así que no hay nada a lo que apuntarlo.
Remix y JS plano se ejecutan mediante la CLI después del build, donde tú indicas el directorio (npx afterpack@latest dist/; Next.js escribe en .next/ y Nuxt en .output/). Consulta Frameworks para la matriz completa y la configuración de cada stack, y el Security Scanner público si quieres ver cómo se ve la protección en un bundle real.
¿Dónde hago una pregunta, informo de un error o propongo una función?
En GitHub. Las preguntas y propuestas van a GitHub Discussions; los errores, a GitHub Issues. Un problema de seguridad va a security@afterpack.dev en lugar de a un hilo público; consulta SLA, SLO y soporte.
Siguiente
- Inicio rápido: instala, compila y publica en unos minutos
- Niveles: Free frente a Pro, función por función
- Configuración: cada opción y qué forma puede establecerla
- Directivas: la gramática de
@afterpacky qué claves se aplican - Presets: la escala de cinco peldaños
- Buenas prácticas: secretos, source maps y CI