# Source: https://docs.zapier.com/platform/news/2025/v17.0.0.md

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt
> Use this file to discover all available pages before exploring further.

# What's changed in v17.0.0

> ES module support, more complete typing, no more `{{curlies}}` in shorthand requests.

*Released: 2025-05-12*

Version 17.0.0 is a **BREAKING CHANGE** release that contains several important upgrades and changes. Here is a brief breakdown of the main breaking changes (**❗ denotes a breaking change**):

## ES Module Support

You can now build integrations using modern ES Module syntax. This means you can use `import ... from ...` instead of `require(...)`, and use newer npm packages that support only ESM.

To start using ESM for your integration project:

* Set `"type": "module"` in your `package.json`
* Replace `main` with `exports` in your `package.json`

For a complete example, check out [minimal-esm](https://github.com/zapier/zapier-platform/tree/82b11aef29a4e7cb576431dba24cba0066c5057b/example-apps/minimal-esm) or [typescript-esm](https://github.com/zapier/zapier-platform/tree/82b11aef29a4e7cb576431dba24cba0066c5057b/example-apps/typescript-esm) (both can be initialized using [`zapier init`](https://github.com/zapier/zapier-platform/blob/82b11aef29a4e7cb576431dba24cba0066c5057b/packages/cli/docs/cli.md#init) with the `-m esm` flag).

Additionally, this update means it's no longer required for every integration's entry point to be `index.js` at the root directory. Instead, the entry point can be defined in `package.json`.

* For example, see the Typescript ESM example integration [at this link](https://github.com/zapier/zapier-platform/tree/main/example-apps/typescript-esm) - it no longer contains an `index.js` file at the root directory, rather the entry point is defined via `"exports": "./dist/index.js"` in the integration's [package.json](https://github.com/zapier/zapier-platform/blob/main/example-apps/typescript-esm/package.json#L20)

## Typing Improvements

We've improved the typing system, making the TypeScript dev experience more enjoyable. The new typing system includes:

* Bundle `inputData` types is now inferred from input fields.
* New helper functions to help with typing:
  * `defineApp`, `defineTrigger`, `defineCreate`, `defineSearch`, `defineInputFields`
  * These are now recommended over the equivalent `satisfies Xyz` statements
  * `satisfies` is still used for `perform` functions, with `InferInputData`, and for other features without `define` helpers. For example, `export default { ... } satisfies Authentication` is still expected.

Check out the [typescript-esm](https://github.com/zapier/zapier-platform/tree/82b11aef29a4e7cb576431dba24cba0066c5057b/example-apps/typescript-esm) example project for a full example.

## ❗ No More `{{curly brackets}}` Outside of Shorthand Requests

Calling `z.request()` with `{{bundle.*}}` or `{{process.env.*}}` will now result in an error. For example:

```js  theme={null}
const perform = async (z, bundle) => {
  const response = await z.request({
    url: "https://{{bundle.authData.subdomain}}.example.com",
  });
  return response.data;
};
```

This will result in an error in v17. Instead, you must use [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) i.e. `${var}`:

```js  theme={null}
const perform = async (z, bundle) => {
  const response = await z.request({
    url: `https://${bundle.authData.subdomain}.example.com`,
  });
  return response.data;
};
```

However, `{{curly backets}}` are still (and have to be) allowed in other places, including `operation.lock.key`. They are also allowed (actually required) in usage of shorthand requests:

```js  theme={null}
{
  operation: {
    perform: {
      url: 'https://{{bundle.authData.subdomain}}.example.com',
      method: 'GET',
    }
  }
}
```

### ❗ Schema Changes

We have split authentication fields, input fields, and output fields into their own respective schemas, to allow for stricter schema checks and to prepare for future platform updates. Along with this, we have removed irrelevant or incompatible field types and properties from certain schemas.

Note that a descriptive error will be thrown on `zapier validate` if your integration attempts to use an unsupported type or property to prompt you to change it; no need to manually check these. The updated schema are as follows:

* `AuthenticationSchema.fields`:
  * The following **types** are no longer supported: `code`, `file`, `integer`, `text`
  * The following **properties** are no longer supported: `altersDynamicFields`, `dynamic`, `meta`, `primary`, `search`, `steadyState`
* `BasicActionOperationSchema.inputFields`:
  * All **types** remain the same.
  * The following **properties** are no longer supported: `primary`, `steadyState`
* `BasicActionOperationSchema.outputFields`:
  * The following **types** are no longer supported: `text`, `copy`, `code`
  * The following **properties** are no longer supported: `altersDynamicFields`, `choices`, `computed`, `dynamic`, `helpText`, `inputFormat`, `meta`, `placeholder`, `search`

***

Apart from these major changes, here are the detailed release notes for this release (**note that ❗ denotes a breaking change**):

## cli

* 🎉 ESM support added to `zapier init` command via the `--module` flag - supports Minimal and Typescript templates ([#976](https://github.com/zapier/zapier-platform/pull/976))
* 🔨 `zapier build` now uses `esbuild` instead of `browserify` to detect dependencies, for a faster experience building, and to better support ESM ([#946](https://github.com/zapier/zapier-platform/pull/946))
* 🔨 Update `gulp-prettier` dependency from 4.0.0 to 5.0.0

## core

* ❗ Stop replacing `{{curlies}}` unless it's a shorthand request ([#1001](https://github.com/zapier/zapier-platform/pull/1001))
* 🎉 ESM Support: Two versions of `zapierwrapper.js`, one CJS and one ESM, loaded dynamically depending on the app type ([#965](https://github.com/zapier/zapier-platform/pull/965))
* 🐛 Not every `{{curlies}}` in the request object need to be recursively replaced ([#1001](https://github.com/zapier/zapier-platform/pull/1001))
* 🐛 HTTP 500 along with status codes >500 are caught in RPC client ([#974](https://github.com/zapier/zapier-platform/pull/974))
* 🔨 Remove Bluebird library, replace with native promises ([#980](https://github.com/zapier/zapier-platform/pull/980))
* 🔨 Refactor middleware and lambda handler logic to use async/await instead of Promise chaining ([#980](https://github.com/zapier/zapier-platform/pull/980))
* 🔨 Trim newline and whitespaces from request headers ([#1000](https://github.com/zapier/zapier-platform/pull/1000))

## schema

* ❗ Remove deprecated shouldLock property in the schema ([#988](https://github.com/zapier/zapier-platform/pull/988))
* 🔨 FieldSchema has been split into separate schemas and renamed for clarity ([#957](https://github.com/zapier/zapier-platform/pull/957), [#998](https://github.com/zapier/zapier-platform/pull/998)). Changes include:
  * Input Fields (`PlainInputFieldSchema` and `InputFieldsSchema`)
  * Output Fields (`PlainOutputFieldSchema` and `OutputFieldsSchema`)
  * Authentication Fields (`AuthFieldSchema` and `AuthFieldsSchema`)
* 🔨 A dedicated `BasicSearchOperationSchema` has been added ([#998](https://github.com/zapier/zapier-platform/pull/998))

## misc

* 🔨 Dependency updates - full list in the PR ([#1010](https://github.com/zapier/zapier-platform/pull/1010))