{"id":10856,"library":"ews-javascript-api","title":"Exchange Web Services JavaScript API","description":"ews-javascript-api is a JavaScript/TypeScript library that provides an API for interacting with Microsoft Exchange Web Services (EWS), aiming to be a counterpart to the C# EWS Managed API. It supports Office 365 OAuth, enabling interaction with modern Exchange Online environments. The current stable version is 0.15.3, with recent releases focusing on bug fixes, security dependency updates, and improved OAuth support. While development has had periods of activity and dormancy, the project is actively maintained to address issues and enhance features like async/await integration and a modular `@ewsjs` namespace. Key differentiators include comprehensive TypeScript type definitions, support for both Node.js and browser environments (via `ews-js-api-browser`), and built-in OAuth support for Exchange Online/Office 365 through `EwsOAuthHelper`, making it suitable for modern web and server-side applications needing to access Exchange data programmatically.","status":"active","version":"0.15.3","language":"javascript","source_language":"en","source_url":"https://github.com/gautamsi/ews-javascript-api","tags":["javascript","ews","ews javascript api","ews-javascript-api","exchange web service","typescript"],"install":[{"cmd":"npm install ews-javascript-api","lang":"bash","label":"npm"},{"cmd":"yarn add ews-javascript-api","lang":"bash","label":"yarn"},{"cmd":"pnpm add ews-javascript-api","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Internal dependency for handling HTTP requests, explicitly mentioned as updated to 3.1.0 in v0.15.0.","package":"@ewsjs/xhr","optional":false}],"imports":[{"note":"Main class for EWS operations. CommonJS `require` is generally discouraged since modern Node versions and TypeScript projects primarily use ESM.","wrong":"const ExchangeService = require('ews-javascript-api').ExchangeService;","symbol":"ExchangeService","correct":"import { ExchangeService } from 'ews-javascript-api';"},{"note":"This helper class for OAuth is located in a subpath, not directly on the main package export. Importing from the root will result in undefined.","wrong":"import { EwsOAuthHelper } from 'ews-javascript-api';","symbol":"EwsOAuthHelper","correct":"import { EwsOAuthHelper } from 'ews-javascript-api/lib/EwsOAuthHelper';"},{"note":"An enumeration used to specify the target Exchange server version for operations. Direct import from the root is preferred over deep imports.","wrong":"const ExchangeVersion = require('ews-javascript-api/lib/Enumerations/ExchangeVersion');","symbol":"ExchangeVersion","correct":"import { ExchangeVersion } from 'ews-javascript-api';"}],"quickstart":{"code":"import { ExchangeService, OAuthCredentials, ExchangeVersion } from \"ews-javascript-api\";\nimport { EwsOAuthHelper } from \"ews-javascript-api/lib/EwsOAuthHelper\";\n\nconst clientId = process.env.EWS_CLIENT_ID ?? '';\nconst clientSecret = process.env.EWS_CLIENT_SECRET ?? '';\nconst tenantId = process.env.EWS_TENANT_ID ?? '';\nconst exchangeUrl = process.env.EWS_URL ?? 'https://outlook.office365.com/EWS/Exchange.asmx';\n\nasync function main() {\n  if (!clientId || !clientSecret || !tenantId) {\n    console.error('Missing EWS_CLIENT_ID, EWS_CLIENT_SECRET, or EWS_TENANT_ID environment variables.');\n    return;\n  }\n\n  try {\n    const oAuthHelper = new EwsOAuthHelper({ clientId, clientSecret, tenantId });\n    console.log('Attempting to get application access token...');\n    const token = await oAuthHelper.getAppAccessToken();\n    console.log('Successfully obtained access token. Expires in:', token.expiresIn);\n\n    const ews = new ExchangeService(ExchangeVersion.Exchange2016);\n    ews.Url = exchangeUrl; // Set your EWS endpoint URL\n    ews.Credentials = new OAuthCredentials(token.accessToken);\n\n    // Example: Find the Inbox folder\n    // You might need to refresh the token if it expires during long-running operations.\n    // A typical pattern is to wrap EWS calls in a function that checks token validity.\n    // const wellKnownFolderName = new WellKnownFolderName(WellKnownFolderName.Inbox);\n    // const findFoldersResults = await ews.FindFolders(wellKnownFolderName, new FolderView(10));\n    // console.log('Found Inbox folder:', findFoldersResults.Folders[0].DisplayName);\n\n    console.log('ExchangeService initialized with OAuth credentials. Ready for EWS operations.');\n    // Placeholder for actual EWS operations, e.g., finding items or sending emails.\n    // await ews.FindItems(WellKnownFolderName.Inbox, new ItemView(10));\n  } catch (error) {\n    console.error('Error during EWS operation:', error);\n    if (error instanceof Error) {\n      console.error('Error message:', error.message);\n    }\n  }\n}\n\nmain().catch(console.error);\n","lang":"typescript","description":"This quickstart demonstrates how to initialize the ExchangeService with Office 365 OAuth credentials using the `EwsOAuthHelper` to obtain an application-only access token, preparing it for subsequent EWS operations. It sets up environment variables for sensitive credentials and includes basic error handling, illustrating the modern authentication flow."},"warnings":[{"fix":"Upgrade your Node.js runtime environment to version 12 or newer. Use `nvm` or your package manager to manage Node.js versions.","message":"Version 0.11.0 and later require Node.js version 10 or higher, with version 12 being preferred. Earlier Node.js versions are not supported and will likely lead to runtime errors due to updated dependencies and language features.","severity":"breaking","affected_versions":">=0.11.0"},{"fix":"Ensure your import statement for `EwsOAuthHelper` is `import { EwsOAuthHelper } from 'ews-javascript-api/lib/EwsOAuthHelper';`.","message":"The `EwsOAuthHelper` class, which is crucial for modern Office 365 authentication, must be imported from its specific subpath `ews-javascript-api/lib/EwsOAuthHelper`. A direct import from the root package `ews-javascript-api` will fail to find the class, leading to runtime errors.","severity":"gotcha","affected_versions":">=0.15.0"},{"fix":"Store the token's `expiresIn` value and re-call `oAuthHelper.getAppAccessToken()` proactively before the current token expires. Consider wrapping EWS operations in a function that ensures a valid token is always present.","message":"When using OAuth, access tokens have a limited lifespan. You must implement logic to periodically refresh the access token using `oAuthHelper.getAppAccessToken()` before it expires, especially for long-running processes or frequent EWS calls. Failure to do so will result in authentication failures (401 Unauthorized errors).","severity":"gotcha","affected_versions":">=0.15.0"},{"fix":"Always use `import` statements for `ews-javascript-api` classes and functions. Ensure your project is configured for ESM, particularly in `package.json` with `\"type\": \"module\"` or when transpiling TypeScript.","message":"The library primarily uses ESM (ECMAScript Modules) syntax for imports and is designed for modern JavaScript environments. While some CommonJS `require()` might work for basic usage, mixing module systems or using outdated `require()` patterns can lead to unexpected behavior or build issues, especially with TypeScript projects.","severity":"gotcha","affected_versions":">=0.11.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Verify that `ExchangeService` and other classes are correctly imported using `import { ClassName } from 'ews-javascript-api';` and that the instance is created before use, e.g., `const ews = new ExchangeService(ExchangeVersion.Exchange2016);`.","cause":"This usually indicates that the `ExchangeService` instance was not properly initialized, or a method was called on an undefined object, often due to an incorrect import or a `this` context issue.","error":"TypeError: Cannot read properties of undefined (reading 'apply') or Cannot set properties of undefined (setting 'Credentials')"},{"fix":"For development/testing (use with caution in production due to security implications), set `process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';` before making EWS calls. For production, properly configure Node.js to trust your CA certificate (e.g., via `NODE_EXTRA_CA_CERTS` environment variable).","cause":"This error typically occurs when Node.js cannot verify the SSL certificate of the EWS endpoint, often in corporate environments with custom proxy certificates or self-signed certificates.","error":"Error: unable to get local issuer certificate (in Node.js)"},{"fix":"Implement token refresh logic. Before making EWS calls, check the token's validity and, if expired or close to expiration, call `oAuthHelper.getAppAccessToken()` again to retrieve a fresh token and update `ews.Credentials`.","cause":"The OAuth access token provided in `OAuthCredentials` has expired or is malformed/invalid, leading to authentication failure with the Exchange server.","error":"401 Unauthorized: Access token is expired or invalid"},{"fix":"Ensure the path is correct and case-sensitive. The `lib/` directory is critical for some sub-modules. Verify your `tsconfig.json` `moduleResolution` and `baseUrl` if you are having issues with non-relative imports. For `EwsOAuthHelper`, the correct import is `import { EwsOAuthHelper } from 'ews-javascript-api/lib/EwsOAuthHelper';`.","cause":"The module resolver cannot locate the specified path for `EwsOAuthHelper` or other sub-modules.","error":"Error: Cannot find module 'ews-javascript-api/lib/EwsOAuthHelper' or similar path errors"}],"ecosystem":"npm"}