{"id":12203,"library":"tuf-js","title":"TUF JavaScript Client","description":"tuf-js is a robust JavaScript and TypeScript implementation of The Update Framework (TUF), providing secure software update mechanisms against various supply chain attacks, including rollback, mix-and-match, and freeze attacks. The package is currently at version 5.0.1 and is actively maintained, demonstrating a consistent release cadence with patches and minor updates, and major versions released to align with Node.js LTS cycles and critical dependency upgrades. It adheres directly to the TUF specification, offering a client-side library for cryptographic signature verification, secure metadata fetching, and managing trust anchors. Key differentiators include its strong focus on security, TypeScript support, and its role as a reference implementation for TUF within the JavaScript ecosystem, ensuring resilient and verifiable software distribution. It is designed for use in environments requiring robust integrity checks for updates, operating on Node.js versions 20.17.0 or higher, or 22.9.0 or higher.","status":"active","version":"5.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/theupdateframework/tuf-js","tags":["javascript","tuf","security","update","typescript"],"install":[{"cmd":"npm install tuf-js","lang":"bash","label":"npm"},{"cmd":"yarn add tuf-js","lang":"bash","label":"yarn"},{"cmd":"pnpm add tuf-js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary class for interacting with a TUF repository. tuf-js has been ESM-first since v4; CommonJS `require()` is not supported.","wrong":"const { TufClient } = require('tuf-js')","symbol":"TufClient","correct":"import { TufClient } from 'tuf-js'"},{"note":"A concrete implementation of the Fetcher interface, suitable for HTTP(S) network requests. Requires global `fetch` to be available (present in Node.js 18+).","wrong":"import { Fetcher } from 'tuf-js' // Incorrect class name","symbol":"RemoteFetcher","correct":"import { RemoteFetcher } from 'tuf-js'"},{"note":"The Root metadata model, essential for bootstrapping the TUF client with its initial trust anchor. This type is provided by the `@tufjs/models` package, which is a peer dependency.","wrong":"import { Root } from 'tuf-js' // Root model is in @tufjs/models","symbol":"Root","correct":"import { Root } from '@tufjs/models'"},{"note":"A simple in-memory implementation of ClientStorage and TargetStorage, typically used for testing or simplified quickstarts. Available from the `@tufjs/client` package, which provides common client utilities.","wrong":"import { InMemoryStorage } from 'tuf-js' // Not exported directly by tuf-js","symbol":"InMemoryStorage","correct":"import { InMemoryStorage } from '@tufjs/client'"}],"quickstart":{"code":"import { TufClient, RemoteFetcher } from 'tuf-js';\nimport { Root } from '@tufjs/models';\nimport { InMemoryStorage } from '@tufjs/client'; // Provides simple in-memory storage\n\nasync function initializeAndDownloadTarget() {\n  const repoURL = 'https://example.com/tuf-repo/'; // Replace with your TUF repository base URL\n\n  // In a real application, you would bundle a trusted initial root.json.\n  // This is a minimal placeholder for demonstration purposes.\n  const initialRootJSON = JSON.stringify({\n    \"_type\": \"root\",\n    \"spec_version\": \"1.0.0\",\n    \"version\": 1,\n    \"expires\": \"2030-01-01T00:00:00Z\",\n    \"keys\": {},\n    \"roles\": {\n      \"root\": {\"keyids\": [], \"threshold\": 1},\n      \"targets\": {\"keyids\": [], \"threshold\": 1},\n      \"snapshot\": {\"keyids\": [], \"threshold\": 1},\n      \"timestamp\": {\"keyids\": [], \"threshold\": 1}\n    }\n  });\n\n  // Parse the initial root metadata\n  const initialRoot = Root.fromJSON(JSON.parse(initialRootJSON));\n\n  // Use in-memory storage for this example. In production, use persistent storage.\n  const client = new TufClient({\n    repoURL: repoURL,\n    root: initialRoot,\n    clientStorage: new InMemoryStorage(),\n    targetStorage: new InMemoryStorage(),\n    fetcher: new RemoteFetcher()\n  });\n\n  try {\n    console.log('Attempting to update TUF metadata...');\n    await client.update(); // Fetches and verifies the latest metadata\n    console.log('TUF metadata updated successfully.');\n\n    const targetName = 'path/to/my-app-binary-v1.0.0.zip'; // Replace with an actual target path\n    console.log(`Getting target info for: ${targetName}`);\n    const targetInfo = await client.getTargetInfo(targetName);\n\n    if (targetInfo) {\n      console.log(`Target '${targetName}' found. Downloading...`);\n      const targetContent = await client.downloadTarget(targetInfo);\n      console.log(`Downloaded ${targetContent.length} bytes for '${targetName}'.`);\n      // Here, targetContent (Uint8Array) can be saved to disk or processed.\n    } else {\n      console.log(`Target '${targetName}' not found in the repository.`);\n    }\n  } catch (error) {\n    console.error('TUF client operation failed:', error);\n  }\n}\n\n// To run this, ensure you have a global `fetch` (Node.js 18+ or polyfill)\n// and install `@tufjs/client` and `@tufjs/models` alongside `tuf-js`.\ninitializeAndDownloadTarget();\n","lang":"typescript","description":"This quickstart demonstrates how to initialize a `TufClient`, perform a metadata update, and then download a specific target file from a remote TUF repository using in-memory storage for simplicity."},"warnings":[{"fix":"Upgrade your Node.js runtime environment to a supported version (e.g., `nvm install 20` or `nvm install 22`).","message":"tuf-js v4.0.0 dropped support for Node.js 18. Applications must upgrade to Node.js 20.17.0, 22.9.0, or newer to continue using tuf-js v4 and above.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Review your application's network configuration and error handling, especially if relying on specific `make-fetch-happen` behaviors. Test thoroughly after upgrading.","message":"Starting with v4.0.0, the internal `make-fetch-happen` dependency was bumped from 14.x to 15.x. While generally backward compatible, this might introduce subtle behavioral changes or new requirements for network operations.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure your project is configured for ESM. Use `import ... from 'tuf-js'` syntax and verify your `package.json` includes `\"type\": \"module\"` or uses `.mjs` file extensions for client-side code.","message":"tuf-js is an ESM-first package. Attempting to import it using CommonJS `require()` syntax will result in errors.","severity":"gotcha","affected_versions":">=4.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Migrate your project to use ES Modules (ESM) syntax (`import ... from 'tuf-js'`) and ensure your Node.js environment or bundler correctly handles ESM.","cause":"Attempting to import tuf-js (an ESM-first package) using CommonJS `require()` syntax.","error":"ERR_REQUIRE_ESM"},{"fix":"Upgrade your Node.js runtime environment to version 20.17.0, 22.9.0, or newer. Check the `engines` field in `package.json` for exact requirements.","cause":"Running tuf-js v4.x or later on an unsupported Node.js version (e.g., Node.js 18 or older).","error":"Error: The client is configured for Node.js version X.Y.Z, which is not supported."},{"fix":"Verify the `initialRoot` metadata provided to the `TufClient` constructor. Ensure it is the correct, cryptographically valid root metadata for your TUF repository.","cause":"The initial `root.json` provided to the `TufClient` is invalid, corrupted, or does not match the repository's actual root metadata, leading to a failure in establishing the initial trust anchor.","error":"Error: Signature verification failed for role 'root'"},{"fix":"Confirm the exact `targetName` by inspecting your TUF repository's `targets.json` or related delegated role metadata. Ensure the target has been published and its metadata is signed and updated in the repository.","cause":"The specified target file name (`targetName`) does not exist in the latest verified `targets.json` metadata from the TUF repository, or the path is incorrect.","error":"Error: Target 'your-target-name' not found in repository metadata."}],"ecosystem":"npm"}