# 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. - Published: 2026-05-31 - Updated: 2026-06-06 - Author: SharpSkill - Tags: node.js, node.js 24, urlpattern, permissions, interview, v8, javascript - Reading time: 10 min --- 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. > **Node.js 24 LTS de un vistazo** > > 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. ```bash # 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.js ``` El 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. ```javascript // permission-check.js // 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](https://nodejs.org/en/blog/vulnerability/march-2026-security-releases) 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](https://developer.mozilla.org/en-US/docs/Web/API/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. ```javascript // router.js // 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. ```javascript // url-validation.js // 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](https://github.com/delvedor/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. ## 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](https://github.com/tc39/proposal-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. ```javascript // resource-management.js // 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. ```javascript // disposable-stack.js // 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](/technologies/node-nestjs). **RegExp.escape** sanea cadenas para incrustarlas de forma segura en expresiones regulares: ```javascript // regexp-escape.js // 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: ```javascript // float16.js // 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 Float32Array ``` **Error.isError** ofrece una verificación de tipo fiable que funciona entre realms (iframes, contextos vm, worker threads): ```javascript // error-check.js // Cross-realm error detection const err = new TypeError('invalid input'); Error.isError(err); // true Error.isError({ message: 'fake' }); // false ``` ## Mejora 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](https://opentelemetry.io/) y los frameworks de logging que dependen de `AsyncLocalStorage` para el contexto por solicitud obtienen mejoras de rendimiento medibles sin cambios de código. ```javascript // async-context.js // 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](https://github.com/delvedor/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. ## 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 `--permission` no 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 using`** reemplazan a `try/finally` para 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](/technologies/node-nestjs/interview-questions/authentication-jwt) --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/es/blog/node-nestjs/nodejs-24-urlpattern-permissions-interview-questions