Compatibility dates
Cloudflare regularly updates the Workers runtime. These updates apply to all Workers globally and should never cause a Worker that is already deployed to stop functioning. Sometimes, though, some changes may be backwards-incompatible. In particular, there might be bugs in the runtime API that existing Workers may inadvertently depend upon. Cloudflare implements bug fixes that new Workers can opt into while existing Workers will continue to see the buggy behavior to prevent breaking deployed Workers.
Compatibility dates (and flags) are how you, as a developer, opt into these changes. By specifying a compatibility_date
in your wrangler.toml
file, that Worker enables all changes that were made before the given date.
# (in wrangler.toml)
# Opt into backwards-incompatible changes through April 5, 2022.
compatibility_date = "2022-04-05"
When you start your project, you should always set compatibility_date
to the current date. You should occasionally update the compatibility_date
field. When updating, you should refer to this page to find out what has changed, and you should be careful to test your Worker to see if the changes affect you, updating your code as necessary. The new compatibility date takes effect when you next run the wrangler publish
command.
There is no need to update your compatibility_date
if you do not want to. The Workers runtime will support old compatibility dates forever. If, for some reason, Cloudflare finds it is necessary to make a change that will break live Workers, Cloudflare will actively contact affected developers. That said, Cloudflare aims to avoid this if at all possible.
However, even though you do not need to update the compatibility_date
field, it is a good practice to do so for two reasons:
- Sometimes, new features can only be made available to Workers that have a current
compatibility_date
. To access the latest features, you need to stay up-to-date. - Generally, other than this page, the Workers documentation may only describe the current
compatibility_date
, omitting information about historical behavior. If your Worker uses an oldcompatibility_date
, you will need to continuously refer to this page in order to check if any of the APIs you are using have changed.
Compatibility flags
In addition to setting a compatibility_date
in your wrangler.toml
file, you may also provide a list of compatibility_flags
, which enable or disable specific changes.
# (in wrangler.toml)
# Opt into backwards-incompatible changes through September 14, 2021.
compatibility_date = "2021-09-14"
# Also opt into an upcoming fix to the FormData API.
compatibility_flags = [ "formdata_parser_supports_files" ]
This example enabled the specific flag formdata_parser_supports_files
, which is described below. As of the specified date, 2021-09-14
, this particular flag was not yet enabled by default, but specifying it in this way enables it anyway. compatibility_flags
can also be used to disable changes that became the default in the past.
Most developers will not need to use compatibility_flags
; instead, Cloudflare recommends only specifying compatibility_date
. compatibility_flags
can be useful if you want to help the Workers team test upcoming changes that are not yet enabled by default, or if you need to hold back a change that your code depends on but still want to apply other compatibility changes.
Change history
Newest changes are listed first.
R2
bucket list
respects the include
option
Default as of | 2022-08-04 |
Flag to enable | r2_list_honor_include |
r2_list_honor_include
flag set, the include
argument to R2 list
options is honored. With an older compatability date and without this flag, the include
argument behaves implicitly as include: ["httpMetadata", "customMetadata"]
.Minimal subrequests
Default as of | 2022-04-05 |
Flag to enable | minimal_subrequests |
Flag to disable | no_minimal_subrequests |
With the minimal_subrequests
flag set, fetch()
subrequests sent to endpoints on the Worker’s own zone (also called same-zone subrequests) have a reduced set of features applied to them. In general, these features should not have been initially applied to same-zone subrequests, and very few user-facing behavior changes are anticipated. Specifically, Workers might observe the following behavior changes with the new flag:
- Response bodies will not be opportunistically gzipped before being transmitted to the Workers runtime. If a Worker reads the response body, it will read it in plaintext, as has always been the case, so disabling this prevents unnecessary decompression. Meanwhile, if the Worker passes the response through to the client, Cloudflare’s HTTP proxy will opportunistically gzip the response body on that side of the Workers runtime instead. The behavior change observable by a Worker script should be that some
Content-Encoding: gzip
headers will no longer appear. - Automatic Platform Optimization may previously have been applied on both the Worker’s initiating request and its subrequests in some circumstances. It will now only apply to the initiating request.
- Link prefetching will now only apply to the Worker’s response, not responses to the Worker’s subrequests.
Global navigator
Default as of | 2022-03-21 |
Flag to enable | global_navigator |
Flag to disable | no_global_navigator |
global_navigator
flag set, a new global navigator
property is available from within Workers. Currently, it exposes only a single navigator.userAgent
property whose value is set to 'Cloudflare-Workers'
. This property can be used to reliably determine whether code is running within the Workers environment.Setters/getters on API object prototypes
Default as of | 2022-01-31 |
Flag to enable | workers_api_getters_setters_on_prototype |
Flag to disable | workers_api_getters_setters_on_instance |
Originally, properties on Workers API objects were defined as instance properties as opposed to prototype properties. This broke subclassing at the JavaScript layer, preventing a subclass from correctly overriding the superclass getters/setters. This flag controls the breaking change made to set those getters/setters on the prototype template instead.
This changes applies to:
AbortSignal
AbortController
Blob
Body
DigestStream
Event
File
Request
ReadableStream
ReadableStreamDefaultReader
ReadableStreamBYOBReader
Response
TextDecoder
TextEncoder
TransformStream
URL
WebSocket
WritableStream
WritableStreamDefaultWriter
New URL parser implementation
Flag to enable | url_standard |
Flag to disable | url_original |
URL
API implementation is not fully compliant with the WHATWG URL Standard. Cloudflare has added a new implementation that is fully compliant. However, since the new implementation is not completely backwards compatible, it is disabled by default. Use the url_standard
flag to enable the new implementation.Durable Object stub.fetch()
requires a full URL
Default as of | 2021-11-10 |
Flag to enable | durable_object_fetch_requires_full_url |
Flag to disable | durable_object_fetch_allows_relative_url |
stub.fetch(url)
, a relative URL was accepted as an input. The URL would be interpreted relative to the dummy URL http://fake-host
, and the resulting absolute URL was delivered to the destination object’s fetch()
handler. This was a mistake — full URLs were meant to be required. This flag makes full URLs required.Streams BYOB reader detaches buffer
Default as of | 2021-11-10 |
Flag to enable | streams_byob_reader_detaches_buffer |
Flag to disable | streams_byob_reader_does_not_detach_buffer |
Originally, the Workers runtime did not detach the ArrayBuffer
s from user-provided TypedArrays when using the BYOB reader’s read()
method, as required by the Streams spec, meaning it was possible to inadvertently reuse the same buffer for multiple read()
calls. This change makes Workers conform to the spec.
User code should never try to reuse an ArrayBuffer
that has been passed into a BYOB reader’s read()
method. Instead, user code can re-use the ArrayBuffer
backing the result of the read()
promise, as in the example below.
{{
{{readable
using a single 4KiB buffer.
result
here.read()
by creating
The more recently added extension method readAtLeast()
will always detach the ArrayBuffer
and is unaffected by this feature flag setting.
FormData
parsing supports File
Default as of | 2021-11-03 |
Flag to enable | formdata_parser_supports_files |
Flag to disable | formdata_parser_converts_files_to_strings |
The FormData
API is used to parse data (especially HTTP request bodies) in multipart/form-data
format.
Originally, the Workers runtime’s implementation of the FormData
API incorrectly converted uploaded files to strings. Therefore, formData.get("filename")
would return a string containing the file contents instead of a File
object. This change fixes the problem, causing files to be represented using File
as specified in the standard.
Experimental changes
These changes can be enabled via compatibility_flags
, but are not yet scheduled to become default on any particular date.
HTMLRewriter
handling of <esi:include>
Default as of | TBD |
Flag to enable | html_rewriter_treats_esi_include_as_void_tag |
Flag to disable | TBD |
The HTML5 standard defines a fixed set of elements as void elements, meaning they do not use an end tag: <area>
, <base>
, <br>
, <col>
, <command>
, <embed>
, <hr>
, <img>
, <input>
, <keygen>
, <link>
, <meta>
, <param>
, <source>
, <track>
, and <wbr>
.
HTML5 does not recognize XML self-closing tag syntax. For example, <script src="foo.js" />
does not specify a script element with no body. A </script>
ending tag is still required. The />
syntax simply is not recognized by HTML5 at all and it is treated the same as >
. However, many developers still like to use this syntax, as a holdover from XHTML, a standard which failed to gain traction in the early 2000’s.
<esi:include>
and <esi:comment>
are two tags that are not part of the HTML5 standard, but are instead used as part of Edge Side Includes, a technology for server-side HTML modification. These tags are not expected to contain any body and are commonly written with XML self-closing syntax.
HTMLRewriter
was designed to parse standard HTML5, not ESI. However, it would be useful to be able to implement some parts of ESI using HTMLRewriter
. To that end, this compatibility flag causes HTMLRewriter
to treat <esi:include>
and <esi:comment>
as void tags, so that they can be parsed and handled properly.