# What changed in imapflow

> 148 changes in imapflow 1 to 2 from its official release notes, upgrade guides and advisories: 14 breaking, 13 security, 15 new APIs and options. Each one cited. Sources checked 2026-10-18. HTML: https://unstale.sh/npm/imapflow/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## imapflow 2

### Breaking changes

- A tagged BYE no longer passes as success. (2.5.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.5.1)
- ImapSocket is now an alias of ImapTransportSocket rather than net.Socket; TypeScript code using net.Socket-only members needs a cast. (2.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.5.0)
- Commands now fail on a NO or BAD status line without a tag. (2.4.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.4.3)
- Drops flags and keywords that are not atoms rather than sending them quoted. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Unknown search keys are refused instead of being accepted. (2.2.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.7)
- A NUL in a non-ASCII search value is rejected instead of being sent as a literal. (2.2.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.3)
- Search refuses empty operands. (2.1.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.1)
- Throttle, truncation and listener failures are surfaced instead of hidden, so callers can detect them. (2.0.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.8)
- The declarations no longer expose ImapFlow's internal members. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)
- The export map provides a supported path for accessing library modules now that the lib/ directory is no longer published. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)
- The lib/ directory is no longer published; use the package root or the imapflow/lib/* export map instead. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)
- Node.js 20 or newer is now required to use imapflow. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)

### Security

- Limits what a hostile server can make the client buffer or wait for. (2.5.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.5.1)
- Response parsing and command compilation were hardened after issues were found by fuzzing. (2.2.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.6)

### New APIs and options

- Added createSocketsTransport() for celld. (2.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.5.0)
- Added createStreamsTransport() for socket APIs built on web streams. (2.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.5.0)
- A transport option was added for celld. (2.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.5.0)
- Unexpected parser exceptions are re-raised as coded ParserErrorInternal errors. (2.4.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.4.0)
- An alert event is emitted for ALERT response codes, allowing applications to handle these server alerts. (2.3.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.3.0)
- The client can choose the hash used behind the fallback message id. (2.2.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.0)
- Exports ImapFlowErrorCode with the error codes set by the library. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Supports await using through Symbol.asyncDispose. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Bun and Cloudflare Workers are now supported runtimes. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)
- The package now provides ES module and CommonJS builds. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)

### Behavior and default changes

- A warning is issued when STARTTLS falls back to cleartext, making the fallback visible to developers. (2.2.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.7)

### Fixes and other changes

- The ID command is sent after STARTTLS instead of before it. (2.4.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.4.3)
- Download decoding handles padded base64 parts in linear memory. (2.4.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.4.1)
- Append literals are kept in sync with their data. (2.4.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.4.0)
- Downloads fail cleanly. (2.4.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.4.0)
- The first chunk of a download is requested again when the answer comes back empty. (2.3.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.3.0)
- A throttled login is no longer treated as a rejected credential. (2.3.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.3.0)
- An empty response for a download chunk causes the chunk to be requested again instead of failing the download. (2.2.11) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.11)
- Reads NAMESPACE prefixes, QUOTAROOT names, and ID values when the server sends them as literals. (2.2.11) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.11)
- fetchOne() takes the requested message when a FETCH answer also carries unsolicited rows. (2.2.10) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.10)
- Socket errors after a failed STARTTLS upgrade are logged instead of thrown on Bun. (2.2.10) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.10)
- Declares DownloadOptions.binary so TypeScript users can use the option with its type recognized. (2.2.9) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.9)
- Declares the QRESYNC mailboxOpen options in the type definitions. (2.2.9) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.9)
- Refetches body sections that Apache James drops. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Enables CONDSTORE with QRESYNC. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Checks that FETCH answers belong to the download. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Expands FETCH ALL, FAST, and FULL macros instead of sending them in a list. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Encodes and decodes non-ASCII Gmail labels as modified UTF-7, like mailbox names. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Decrements mailbox.exists when the server sends an untagged VANISHED response, keeping the mailbox count consistent. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Sends the OAuth token after the continuation request when SASL-IR is not advertised. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Does not send sequence sets when the mailbox is empty. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Sends the UNCHANGEDSINCE modifier before the flags. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- Leaves servername out of tls.connect() for IP literal hosts, which Bun rejects. (2.2.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.8)
- downloadMany now enforces maxBytes, preventing downloads from exceeding the configured byte limit. (2.2.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.7)
- A lost login is reported only once. (2.2.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.7)
- The transport is closed when a connection attempt fails. (2.2.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.7)
- Digit-led atoms such as "2024:Q1" are read instead of causing the response line to be dropped. (2.2.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.6)
- Non-ASCII search values are sent as literals, addressing issue #417. (2.2.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.3)
- Append flags are kept when the destination is not an open read-write mailbox. (2.2.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.2)
- A flag update that reduces to nothing no longer clears every flag. (2.2.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.2)
- IMAP4rev2 is no longer enabled on Strato RZimapd, avoiding the issue with that server. (2.2.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.2.1)
- Closing settles every pending connect operation. (2.1.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.1)
- NIL envelope rows are kept. (2.1.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.1)
- Top-level special-use folders are preferred. (2.1.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.1)
- Reads the last extension field of a BODYSTRUCTURE part. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Rejects connect() immediately when the server sends a BYE greeting. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Processes a chunk that arrives while the input loop is winding down. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Parses a chunk containing many literals in a loop instead of recursing. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Preserves a bracketed IPv6 host in a REFERRAL URL. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- When the best special-use candidate is taken, its next candidate is given a special-use type. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- QRESYNC accepts uidValidity as either a number or a string. (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- Keeps auto-IDLE disabled on a socket handed over by unbind(). (2.1.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.1.0)
- The quota response type now describes the value returned by getQuota(). (2.0.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.8)
- The source is no longer expunged when the fallback COPY fails, preventing message loss. (2.0.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.8)
- Body sections sent by the server as quoted strings are now kept as quoted strings. (2.0.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.7)
- The parser now splits flags when a server writes them without the separating space. (2.0.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.6)
- The chunked download loop is bounded by the reported message size. (2.0.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.3)
- Chunked downloads stop when the server ignores the partial spec. (2.0.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.3)
- Skip LSUB after a server rejects ENABLE over the IMAP4rev2 it advertises. (2.0.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.2)
- Imapflow stops acting on an IMAP4rev2 advertisement after the server rejects ENABLE over it. (2.0.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.1)
- AuthenticationFailure.response is now typed as a string, matching its actual value. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)
- Auto-IDLE is re-armed after an IDLE or poll session ends on its own. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)
- Events are typed without relying on the generic EventEmitter from @types/node. (2.0.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v2.0.0)

## imapflow 1

### Breaking changes

- Non-secure connections now default to IMAP port 143 instead of POP3 port 110. (1.4.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.4.8)
- close() now rejects synchronously instead of using setImmediate. (1.2.15) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.15)

### Security

- Credential frames are masked in the raw log while error detail is preserved. (1.7.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.1)
- Parsing of untrusted server response values was hardened. (1.6.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.6)
- Blocks IMAP command injection. (1.6.4) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.4)
- Hardens rev2 protocol handling. (1.6.4) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.4)
- Response parsing, tag correlation, IDLE polling, and proxy connection setup are hardened. (1.6.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.0)
- The FLAGS guard was hardened; the notes do not specify the affected behavior. (1.3.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.7)
- Connection error paths were hardened. (1.3.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.6)
- Literal bounds handling was hardened. (1.3.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.6)
- The STARTTLS upgrade path was hardened. (1.3.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.6)
- Hardens the parser. (1.3.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.5)
- Hardened mailbox-lock and error-propagation paths. (1.3.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.2)

### New APIs and options

- The auto-IDLE delay is configurable through autoIdleDelay. (1.7.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.0)
- Adds rev2 BINARY fetch support. (1.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.5.0)
- Adds support for STATUS SIZE/DELETED. (1.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.5.0)
- The search compiler supports a Gmail label search term. (1.4.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.4.0)
- Adds ESEARCH (RFC 4731) and PARTIAL (RFC 9394) support. (1.3.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.0)

### Behavior and default changes

- Special-use folder names are expanded from client localization catalogs, allowing localized names to be recognized. (1.6.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.0)

### Fixes and other changes

- Keeps the pipeline error forwarder across a backpressure wait, preventing errors from being lost. (1.7.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.8)
- A re-stamped rejection no longer carries the previous site's markers. (1.7.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.6)
- An IDLE-break waiter now has its own rejection site. (1.7.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.5)
- Search dates are normalized so invalid values cannot throw or emit NaN. (1.7.4) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.4)
- Connection errors are stamped, and the rejection guard is structural, making connection-error handling more consistent. (1.7.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.3)
- The IDLE preCheck waiter is guarded, and connection errors name the rejection site. (1.7.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.3)
- The type now accepts string[] paths. (1.7.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.2)
- The type now accepts string[] paths. (1.7.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.2)
- Envelope parsing no longer invents an address when the host field is NIL. (1.7.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.2)
- The type now accepts string[] paths. (1.7.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.2)
- The type now accepts string[] paths. (1.7.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.2)
- The type now accepts string[] paths. (1.7.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.2)
- Auto-IDLE is kept off a busy connection. (1.7.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.0)
- The socket watchdog is aligned with the auto-IDLE busy guard. (1.7.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.7.0)
- Folders are assumed to be subscribed when the server reports no subscription state. (1.6.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.3)
- IMAP4rev2 sessions no longer fall back to LSUB. (1.6.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.2)
- Authentication results are now kept on a verifyOnly connection. (1.6.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.1)
- Missing localized special-use folder names are added, and names are normalized to NFC. (1.6.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.0)
- Decorated folder names are matched, and special-use names are normalized to NFKC. (1.6.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.0)
- The types now declare specialUseHints.archive. (1.6.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.0)
- The types now declare specialUseSource. (1.6.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.6.0)
- Fixes protocol bugs found in an RFC 9051 review. (1.5.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.5.0)
- The list operation requests subscription state inline and supports IMAP4rev2. (1.4.9) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.4.9)
- Folder handling now passes the StatusObject value instead of its boolean primitive. (1.4.9) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.4.9)
- The OAUTHBEARER payload now describes the real connection. (1.4.8) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.4.8)
- Mailboxes marked \NonExistent in LIST responses are treated as \Noselect. (1.4.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.4.7)
- Corrects flag removal behavior. (1.3.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.5)
- Prevents host process crashes caused by socket errors after unbind() when COMPRESS=DEFLATE is active. (1.3.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.5)
- Corrects literal parsing. (1.3.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.5)
- Corrects path normalization. (1.3.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.5)
- Handles THREADID NIL in FETCH responses. (1.3.4) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.4)
- Handles a NIL delimiter in NAMESPACE responses, as specified by RFC 2342. (1.3.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.3)
- Handles the plain Array form for PARTIAL in the ESEARCH parser. (1.3.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.0)
- Corrects the return type of ESEARCH search(). (1.3.0) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.3.0)
- Compound OR/NOT search conditions are parenthesized according to RFC 3501. (1.2.16) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.16)
- Corrects handling of red at index 0, which was treated as falsy. (1.2.14) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.14)
- Matches euc-jp in decoder selection. (1.2.14) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.14)
- Uses nullish coalescing when resolving flag colors. (1.2.14) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.14)
- Uses nullish coalescing in charset resolution. (1.2.14) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.14)
- Handles BigInt(0) in uidValidity checks. (1.2.14) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.14)
- Prevents unhandled promise rejections when close() encounters race conditions. (1.2.13) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.13)
- Prevents an unhandled NoConnection rejection during IDLE recovery. (1.2.12) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.12)
- The fetch() generator releases backpressure when iteration ends early through break or throw. (1.2.11) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.11)
- Null guards in compress() prevent a crash during TLS teardown. (1.2.10) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.10)
- Transform streams now implement _destroy() methods for proper cleanup. (1.2.7) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.7)
- Restores the isClosed check and error logging in initialPREAUTH. (1.2.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.6)
- Prevents memory leaks in socket and event handling. (1.2.6) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.6)
- Adds the missing text search property to the TypeScript definitions so developers can use it with type support. (1.2.5) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.5)
- Improves resource cleanup when a connection closes. (1.2.4) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.4)
- Adds logging for download errors that were silently swallowed, making them visible to developers. (1.2.3) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.3)
- Pending mailbox locks are rejected when the connection closes. (1.2.2) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.2)
- Promise rejections are deferred when a connection closes to prevent unhandled rejections. (1.2.1) — [release notes](https://github.com/postalsys/imapflow/releases/tag/v1.2.1)
