Node.js 24 en 2026: URLPattern, Permission Model y preguntas de entrevista
Node.js 24 LTS trae un Permission Model estable, URLPattern global, gestión explícita de recursos con using/await using y V8 13.6. Un análisis a fondo de las funciones que importan en producción y en entrevistas.

Node.js 24, con nombre clave Krypton, alcanzó el estado LTS en octubre de 2025 y sigue siendo la versión de producción recomendada en 2026. Esta versión estabiliza el Permission Model, promueve URLPattern a API global, incorpora la gestión explícita de recursos mediante V8 13.6 y actualiza npm a la versión 11. Estos cambios afectan directamente la forma en que las aplicaciones backend gestionan la seguridad, el enrutamiento y el ciclo de vida de los recursos.
V8 13.6 con using/await using, el flag estable --permission que reemplaza a --experimental-permission, URLPattern global para enrutamiento sin frameworks, npm 11 y Undici 7 como cliente HTTP por defecto. El último parche es la 24.16.0 (mayo de 2026).
El Permission Model: de experimental a listo para producción
Node.js 20 introdujo el Permission Model detrás de --experimental-permission. Node.js 24 elimina el prefijo experimental. El flag ahora es simplemente --permission, y el runtime restringe el acceso al sistema de archivos, la red, los procesos hijo, los addons nativos y las variables de entorno salvo que se permita de forma explícita.
Esto importa para la seguridad de la cadena de suministro. Una dependencia comprometida no puede exfiltrar datos a través de la red ni leer archivos arbitrarios si el proceso se ejecuta bajo --permission con permisos acotados de forma estricta.
# launch-secure.sh
# Run an API server with minimal permissions
node --permission \
--allow-fs-read=/app/src,/app/config \
--allow-fs-write=/app/uploads \
--allow-net=0.0.0.0:3000 \
server.jsEl proceso anterior solo puede leer los directorios de código fuente y configuración, escribir en la carpeta de uploads y escuchar en el puerto 3000. Cualquier intento de lanzar un proceso hijo, cargar un addon nativo o acceder a variables de entorno fuera del alcance permitido lanza un error ERR_ACCESS_DENIED.
Verificaciones de permisos en tiempo de ejecución con process.permission
El método process.permission.has() habilita la introspección en tiempo de ejecución. El código de la aplicación puede verificar sus propias capacidades antes de intentar una operación restringida.
// Verify permissions before performing restricted operations
function ensureWriteAccess(directory) {
if (!process.permission.has('fs.write', directory)) {
throw new Error(`No write permission for ${directory}`);
}
}
function canSpawnProcesses() {
return process.permission.has('child');
}
// Gracefully degrade when network access is restricted
function fetchWithFallback(url, cachedData) {
if (!process.permission.has('net')) {
console.warn('Network access denied, using cached data');
return cachedData;
}
return fetch(url);
}Este patrón resulta especialmente útil para bibliotecas que deben funcionar tanto en entornos con sandbox como sin restricciones. El parche de seguridad de marzo de 2026 para Node.js 24.14.1 también corrigió una evasión en FileHandle.chmod() y FileHandle.chown() que omitía las verificaciones de permisos, lo que recalca la importancia de mantener el runtime actualizado.
URLPattern global: coincidencia de rutas nativa sin dependencias
Node.js 24 expone URLPattern en el ámbito global. Este estándar de la WHATWG ofrece una coincidencia de patrones similar a las expresiones regulares, diseñada específicamente para URLs, con grupos nombrados, segmentos opcionales y restricciones de validación.
No se necesita ningún import ni require. La API se comporta de forma idéntica en navegadores, en Cloudflare Workers y en Deno, lo que la convierte en una primitiva de enrutamiento genuinamente portable.
// Framework-free HTTP router using global URLPattern
const routes = [
{
pattern: new URLPattern({ pathname: '/api/users/:userId' }),
handler: handleGetUser
},
{
pattern: new URLPattern({ pathname: '/api/users/:userId/posts/:postId' }),
handler: handleGetPost
},
{
// Optional segment: matches /api/products and /api/products/:category
pattern: new URLPattern({ pathname: '/api/products{/:category}?' }),
handler: handleProducts
}
];
function matchRoute(url) {
for (const route of routes) {
const result = route.pattern.exec(url);
if (result) {
return { handler: route.handler, params: result.pathname.groups };
}
}
return null;
}
// Usage with Node.js HTTP server
import { createServer } from 'node:http';
const server = createServer((req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
const match = matchRoute(url.href);
if (match) {
match.handler(req, res, match.params);
} else {
res.writeHead(404).end('Not Found');
}
});
server.listen(3000);Validación de patrones y coincidencia avanzada
URLPattern admite restricciones regex en línea sobre los grupos nombrados, coincidencia por protocolo y filtrado por nombre de host. El método test() devuelve un booleano para verificaciones rápidas, sin asignar un objeto de resultado.
// Validate URL segments with inline regex constraints
const numericUser = new URLPattern({ pathname: '/users/:id([0-9]+)' });
numericUser.test('https://app.com/users/42'); // true
numericUser.test('https://app.com/users/alice'); // false
// Match by protocol and hostname
const secureApi = new URLPattern({
protocol: 'https',
hostname: 'api.example.com',
pathname: '/v2/*'
});
// Service worker-style routing for static assets vs API calls
const staticAssets = new URLPattern({ pathname: '/static/*' });
const apiCalls = new URLPattern({ pathname: '/api/*' });En cuanto al rendimiento, URLPattern no está pensado para competir en rendimiento bruto con routers optimizados como find-my-way. Su valor reside en la portabilidad entre runtimes y en una API estandarizada que elimina los errores de análisis de rutas.
¿Listo para aprobar tus entrevistas de Node.js / NestJS?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
Gestión explícita de recursos: using y await using
V8 13.6 en Node.js 24 incorpora la propuesta de TC39 Explicit Resource Management. Las declaraciones using y await using reemplazan los bloques try/finally para la limpieza determinista de descriptores de archivos, conexiones de base de datos, locks y cualquier objeto que implemente Symbol.dispose o Symbol.asyncDispose.
A partir de Node.js 24.2.0, Symbol.dispose y Symbol.asyncDispose dejan de ser experimentales.
// Automatic cleanup with using and await using
import { open } from 'node:fs/promises';
async function processCSV(path) {
// File handle is automatically closed when scope exits
await using file = await open(path, 'r');
const content = await file.readFile({ encoding: 'utf8' });
return content.split('\n').length;
// file[Symbol.asyncDispose]() called here automatically
}
// Custom disposable resource
function createDatabasePool(connectionString) {
const pool = new Pool(connectionString);
return {
pool,
query: (sql, params) => pool.query(sql, params),
[Symbol.asyncDispose]: async () => {
await pool.end();
console.log('Pool connections released');
}
};
}
async function runMigrations() {
await using db = createDatabasePool(process.env.DB_URL);
await db.query('CREATE TABLE IF NOT EXISTS migrations ...');
// Pool automatically closed, no try/finally needed
}DisposableStack para múltiples recursos
DisposableStack y AsyncDisposableStack agrupan varios recursos descartables. Cuando la pila se libera, los recursos se liberan en orden inverso, lo que gestiona correctamente las cadenas de dependencias.
// Manage multiple resources with AsyncDisposableStack
async function processTransaction() {
await using stack = new AsyncDisposableStack();
const connection = stack.use(await getConnection());
const transaction = stack.use(await connection.beginTransaction());
const tempFile = stack.use(await createTempFile());
await transaction.execute('INSERT INTO orders ...');
await tempFile.write('backup data');
// On scope exit: tempFile closed, transaction committed/rolled back,
// connection returned to pool (reverse order)
}Este patrón elimina toda una categoría de errores por fugas de recursos. El tipo SuppressedError maneja el caso límite en el que la propia liberación lanza una excepción, preservando tanto el error original como el error de liberación.
V8 13.6: características del motor JavaScript que conviene conocer
Más allá de la gestión explícita de recursos, V8 13.6 introduce varias características que aparecen en las entrevistas técnicas de Node.js.
RegExp.escape sanea cadenas para incrustarlas de forma segura en expresiones regulares:
// Safely embed user input in regular expressions
const userInput = 'price: $9.99 (USD)';
const escaped = RegExp.escape(userInput);
// escaped: 'price\:\ \$9\.99\ \(USD\)'
const pattern = new RegExp(escaped);Float16Array agrega un array tipado de punto flotante de 16 bits, que reduce a la mitad el uso de memoria frente a Float32Array en cargas como la inferencia de ML o la preparación de buffers de WebGL:
// Half-precision floating point for memory-sensitive workloads
const weights = new Float16Array([0.5, -1.25, 3.14]);
console.log(weights.byteLength); // 6 bytes instead of 12 with Float32ArrayError.isError ofrece una verificación de tipo fiable que funciona entre realms (iframes, contextos vm, worker threads):
// Cross-realm error detection
const err = new TypeError('invalid input');
Error.isError(err); // true
Error.isError({ message: 'fake' }); // falseMejora de rendimiento de AsyncLocalStorage
Node.js 24 cambia AsyncLocalStorage a la implementación AsyncContextFrame por defecto. Las versiones anteriores usaban un enfoque basado en hooks que añadía sobrecarga a cada operación asíncrona. La nueva implementación se integra directamente con la cola de microtareas de V8, reduciendo el costo de propagación de contexto en aplicaciones de alta concurrencia.
Este cambio es transparente para el código existente. Bibliotecas como OpenTelemetry y los frameworks de logging que dependen de AsyncLocalStorage para el contexto por solicitud obtienen mejoras de rendimiento medibles sin cambios de código.
// Request-scoped context with improved AsyncLocalStorage
import { AsyncLocalStorage } from 'node:async_hooks';
const requestContext = new AsyncLocalStorage();
function handleRequest(req, res) {
const context = {
requestId: crypto.randomUUID(),
startTime: performance.now()
};
requestContext.run(context, async () => {
// Context automatically propagated through all async operations
const data = await fetchUserData(req.userId);
const elapsed = performance.now() - requestContext.getStore().startTime;
logger.info(`Request ${requestContext.getStore().requestId} completed in ${elapsed}ms`);
res.json(data);
});
}Preguntas de entrevista: edición Node.js 24
Estas preguntas reflejan las características y los patrones que los entrevistadores apuntan en 2026. Cada respuesta demuestra una comprensión a nivel de producción, no un conocimiento superficial.
Q1: ¿En qué se diferencia el Permission Model de Node.js del sandboxing a nivel de sistema operativo?
El Permission Model opera a nivel del runtime de Node.js, no del kernel del sistema operativo. Restringe el acceso a las API integradas de Node.js (fs, net, child_process) según los flags de la línea de comandos. El sandboxing a nivel de sistema operativo (contenedores, seccomp, AppArmor) opera por debajo del runtime y restringe las llamadas al sistema. El Permission Model complementa el sandboxing del sistema operativo al aportar granularidad a nivel de aplicación. Una limitación clave: no se aplica a los addons nativos que evitan las API de Node.js, y los descriptores de archivo abiertos antes de la verificación de permisos siguen siendo utilizables.
Q2: ¿Cuándo sería URLPattern una mala elección frente a un router dedicado?
URLPattern carece de soporte para middleware, enrutamiento por método (GET vs POST) y garantías de orden de rutas. Realiza una coincidencia lineal al recorrer un array de patrones, mientras que routers como find-my-way usan árboles radix para búsquedas en O(log n). URLPattern es apropiado para la lógica de validación compartida entre cliente y servidor, los manejadores de fetch de los service workers y los prototipos. Las API HTTP de producción con cientos de rutas se benefician de un router dedicado.
Q3: Explicar la diferencia entre using y await using. ¿Cuándo conviene cada uno?
using llama a [Symbol.dispose]() de forma síncrona al salir del bloque. Sirve para recursos como mutex, descriptores de archivo gestionados por addons C++ síncronos o cachés en memoria. await using llama a [Symbol.asyncDispose]() y espera el resultado, lo que lo hace necesario para conexiones de base de datos, sesiones HTTP o cualquier limpieza que implique E/S asíncrona. Usar un using síncrono para un recurso asíncrono omite la limpieza de forma silenciosa.
Q4: ¿Cómo mejora AsyncContextFrame el rendimiento de AsyncLocalStorage?
Las implementaciones anteriores usaban async hooks (init, before, after, destroy) para propagar el contexto, añadiendo sobrecarga a cada resolución de Promise y a cada callback de timer. AsyncContextFrame almacena el contexto directamente en la cadena interna de promesas de V8, eliminando la sobrecarga de los hooks. La mejora es más notable en cargas con alta rotación de Promise, como los servidores HTTP que manejan miles de solicitudes concurrentes con trazado por solicitud.
Q5: ¿Qué limitaciones de seguridad existen en el Permission Model?
Cinco limitaciones críticas: (1) los enlaces simbólicos pueden salir de las rutas permitidas; (2) los addons nativos evitan por completo las verificaciones de permisos; (3) los descriptores de archivo heredados de un proceso padre o abiertos antes de la inicialización de --permission no están restringidos; (4) los flags --env-file y --openssl-config leen archivos antes de que se inicialice el Permission Model; (5) los permisos de los worker threads son independientes y deben configurarse por separado. La corrección de CVE de marzo de 2026 para FileHandle.chmod()/FileHandle.chown() demostró que las nuevas API deben auditarse de forma continua para asegurar la aplicación de permisos.
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Conclusión
- Ruta de actualización: Node.js 24 LTS (Krypton) es la versión de producción recomendada hasta abril de 2028. El flag
--permissionno exige cambios de código, solo configuración de despliegue - URLPattern elimina las dependencias ligeras de enrutamiento para código multi-runtime. Reservar los routers dedicados para las API HTTP de alto rendimiento con cadenas de middleware complejas
using/await usingreemplazan atry/finallypara la gestión del ciclo de vida de los recursos. Conviene empezar por añadir[Symbol.asyncDispose]a los wrappers de pools de base de datos y a las utilidades de descriptores de archivo- AsyncLocalStorage aplica sus mejoras de rendimiento de forma automática. Verificarlas midiendo el logging y el trazado por solicitud bajo carga
- La preparación de entrevistas debe cubrir las limitaciones del Permission Model (enlaces simbólicos, addons nativos, descriptores de archivo heredados), las concesiones de URLPattern frente a los routers de árbol radix y la distinción entre liberación síncrona y asíncrona
- Practicar la implementación de recursos descartables personalizados y de verificaciones de permisos en tiempo de ejecución permite demostrar familiaridad práctica con las características de Node.js 24 durante las sesiones de entrevista backend
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Etiquetas
Compartir
Artículos relacionados

Preguntas de entrevista Node.js Backend: Guia completa 2026
Las 25 preguntas mas frecuentes en entrevistas de backend Node.js. Event loop, async/await, streams, clustering y rendimiento explicados con respuestas detalladas.

Entrevista NestJS: Guards, Interceptors y arquitectura modular
Preguntas frecuentes en entrevistas técnicas de NestJS sobre Guards, Interceptors y arquitectura modular, con ejemplos concretos en TypeScript y explicaciones técnicas.

Rendimiento en Node.js: Event Loop, Clustering y Optimización en 2026
Optimización del rendimiento en Node.js mediante la gestión del event loop, estrategias de clustering y worker threads. Patrones prácticos para aplicaciones Node.js de alto rendimiento en 2026.