{"id":15529,"library":"aws4fetch","title":"Compact AWS Client for Modern JS","description":"aws4fetch is a JavaScript library designed for signing AWS requests using the AWS Signature Version 4 process. It provides a compact client (6.4kb minified, 2.5kb gzipped) tailored for modern JavaScript environments that natively support the Web `fetch` API and `SubtleCrypto`. This makes it particularly well-suited for serverless edge computing platforms like Cloudflare Workers, as well as modern web browsers. The library is currently at version `1.0.20` and maintains an active release cadence, frequently adding support for new AWS features and refining existing functionality. A key differentiator is its built-in exponential backoff with full jitter retry strategy, enhancing the reliability of AWS interactions. Unlike traditional Node.js-centric AWS SDKs, `aws4fetch` leverages browser-native APIs, prioritizing minimalism and performance in environments where those APIs are readily available.","status":"active","version":"1.0.20","language":"javascript","source_language":"en","source_url":"https://github.com/mhart/aws4fetch","tags":["javascript","typescript"],"install":[{"cmd":"npm install aws4fetch","lang":"bash","label":"npm"},{"cmd":"yarn add aws4fetch","lang":"bash","label":"yarn"},{"cmd":"pnpm add aws4fetch","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Primary class for signing and fetching requests. `require` syntax is not officially supported and may lead to issues due to the package's ESM-first design since v1.0.16.","wrong":"const AwsClient = require('aws4fetch').AwsClient","symbol":"AwsClient","correct":"import { AwsClient } from 'aws4fetch'"},{"note":"Class for low-level V4 signing operations. It is a named export, not a default export.","wrong":"import AwsV4Signer from 'aws4fetch'","symbol":"AwsV4Signer","correct":"import { AwsV4Signer } from 'aws4fetch'"},{"note":"The library ships with TypeScript types. Specific type imports follow standard named import patterns.","symbol":"TypeScript Types","correct":"import type { AwsClientOptions } from 'aws4fetch'"}],"quickstart":{"code":"import { AwsClient } from 'aws4fetch';\n\n// In a real application, retrieve these from secure environment variables or a secrets manager.\n// For demonstration, use placeholders or process.env.\nconst MY_ACCESS_KEY = process.env.AWS_ACCESS_KEY_ID ?? 'YOUR_AWS_ACCESS_KEY_ID';\nconst MY_SECRET_KEY = process.env.AWS_SECRET_ACCESS_KEY ?? 'YOUR_AWS_SECRET_ACCESS_KEY';\nconst MY_SESSION_TOKEN = process.env.AWS_SESSION_TOKEN ?? undefined; // Optional for temporary credentials\n\nasync function setupAndInvokeLambda() {\n  if (!MY_ACCESS_KEY || !MY_SECRET_KEY) {\n    console.error(\"AWS credentials are not set. Please provide MY_ACCESS_KEY and MY_SECRET_KEY.\");\n    return;\n  }\n\n  const aws = new AwsClient({\n    accessKeyId: MY_ACCESS_KEY,\n    secretAccessKey: MY_SECRET_KEY,\n    sessionToken: MY_SESSION_TOKEN,\n    region: 'us-east-1' // Explicitly set a region if known, or let aws4fetch parse it\n  });\n\n  // Example: Invoking an AWS Lambda function\n  // Replace 'my-lambda' with your actual Lambda function name.\n  // The API endpoint structure is standard for Lambda Invoke API.\n  const LAMBDA_FN_API_BASE = 'https://lambda.us-east-1.amazonaws.com/2015-03-31/functions';\n  const functionName = 'my-test-lambda'; // Replace with your Lambda function name\n  const url = `${LAMBDA_FN_API_BASE}/${functionName}/invocations`;\n\n  const eventPayload = {\n    message: 'Hello from aws4fetch!',\n    timestamp: new Date().toISOString()\n  };\n\n  try {\n    console.log(`Invoking Lambda function: ${functionName} with payload:`, eventPayload);\n    const res = await aws.fetch(url, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify(eventPayload)\n    });\n\n    if (res.ok) {\n      const jsonResponse = await res.json();\n      console.log('Lambda invocation successful:', jsonResponse);\n      return jsonResponse;\n    } else {\n      const errorText = await res.text();\n      console.error(`Lambda invocation failed with status ${res.status}:`, errorText);\n      throw new Error(`Lambda invocation failed: ${res.status} ${errorText}`);\n    }\n  } catch (error) {\n    console.error('Error during Lambda invocation:', error);\n    throw error;\n  }\n}\n\n// Call the async function\nsetupAndInvokeLambda().catch(err => console.error(\"Unhandled error:\", err));\n","lang":"typescript","description":"This quickstart demonstrates how to instantiate `AwsClient` with credentials and use it to invoke an AWS Lambda function via the `fetch` API, handling potential errors."},"warnings":[{"fix":"For Node.js environments, ensure `fetch` and `SubtleCrypto` are available, either by using a recent Node.js version (v18+ for global fetch) or by installing and importing polyfills like `node-fetch` and a Web Crypto API implementation.","message":"The library relies on the global `fetch` API and `SubtleCrypto`. It is primarily designed for environments like modern web browsers and Cloudflare Workers. Running in Node.js without polyfills for these APIs will result in errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade your bundler or Node.js version to one that supports `package.json#exports`. Ensure you are using ESM `import` statements for `aws4fetch`. If stuck on an older setup, consider using a bundler configuration to resolve the package correctly or stay on an older `aws4fetch` version if possible.","message":"Version 1.0.16 introduced an `exports` field to `package.json`. This change can break module resolution for older bundlers (e.g., Webpack 4) or Node.js environments that do not correctly interpret the `exports` map, particularly when using CommonJS `require()`.","severity":"breaking","affected_versions":">=1.0.16"},{"fix":"Verify your Node.js project is configured to handle ESM correctly (e.g., `\"type\": \"module\"` in `package.json` or `.mjs` file extensions) and that your bundler is configured for ESM output where appropriate.","message":"Version 1.0.17 added a `.mjs` version for Node.js. While intended to improve ESM compatibility, this, coupled with the `exports` field, can introduce module resolution complexities if your project configuration is not aligned with modern Node.js ESM practices.","severity":"gotcha","affected_versions":">=1.0.17"},{"fix":"Update your project's TypeScript version to a recent stable release that is compatible with the latest `aws4fetch` types. Review any custom type declarations or workarounds you might have had for `aws4fetch`.","message":"Version 1.0.18 included fixes for TypeScript types for newer TypeScript versions. This could potentially introduce type-related compilation errors or incompatibilities for projects using older TypeScript versions that relied on previous type definitions or workarounds.","severity":"breaking","affected_versions":">=1.0.18"},{"fix":"Ensure that any dynamically generated hostnames comply with the 63-character label limit. Review hostname generation logic for AWS services, particularly S3, R2, and Backblaze, which have specific hostname conventions.","message":"Version 1.0.20 enforced a maximum of 63 characters for hostname labels, aligning with DNS standards. While a fix, if your application generates very long or non-standard hostnames (e.g., for S3 buckets or custom endpoints), these requests might now fail validation.","severity":"gotcha","affected_versions":">=1.0.20"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"For Node.js v18+, `fetch` is global. For older Node.js versions, install a `fetch` polyfill (e.g., `npm install node-fetch`) and ensure it's loaded before `aws4fetch` is used: `import fetch from 'node-fetch'; global.fetch = fetch;`.","cause":"`aws4fetch` was executed in a JavaScript environment (e.g., Node.js older than v18) that does not natively provide the `fetch` global API.","error":"ReferenceError: fetch is not defined"},{"fix":"In Node.js, you might need a Web Crypto API polyfill. Consider libraries like `@peculiar/webcrypto` if your Node.js version doesn't provide it globally or if you're in a specific environment that omits it.","cause":"`aws4fetch` was executed in an environment lacking the `SubtleCrypto` global API, which is essential for cryptographic operations like signing.","error":"ReferenceError: SubtleCrypto is not defined"},{"fix":"Ensure your bundler (e.g., Webpack, Rollup, esbuild) is up-to-date and configured to handle ESM and `package.json#exports` correctly. Always use `import { AwsClient } from 'aws4fetch'` and avoid `require()` where possible.","cause":"This error typically occurs when a bundler or runtime environment fails to correctly resolve the `AwsClient` export, often due to misinterpretation of `package.json#exports` or using `require()` with an ESM-only package.","error":"TypeError: (0 , aws4fetch__WEBPACK_IMPORTED_MODULE_0__.AwsClient) is not a constructor"},{"fix":"Verify `aws4fetch` is correctly installed. Ensure your `tsconfig.json` has `\"moduleResolution\": \"bundler\"` or `\"node16\"` (or appropriate for modern ESM) and that your TypeScript version is compatible (v1.0.18 fixed type issues for newer TS). Reinstall `@types/aws4fetch` if it exists, though `aws4fetch` ships its own types.","cause":"TypeScript cannot locate the type definitions for the `aws4fetch` package, or there's a mismatch between the installed package version and TypeScript compiler settings.","error":"TS2307: Cannot find module 'aws4fetch' or its corresponding type declarations."}],"ecosystem":"npm"}