2 hours ago
apexcharts.js

💎 Version 7.5.1

A patch for one bug in the Weave inventory that 7.5.0 introduced, found by the first thing to consume it: api.drawn() kept listing an overlay after the plugin had cleared it away, because declarations were dropped only on a chart redraw and switching an overlay off does not cause one.

Nothing else changed, and no plugin needs to do anything differently.

gzip
7.5.0 default bundle 269,856 B
7.5.1 default bundle 269,879 B

Both are dist/apexcharts.min.js gzipped at the default level, which is the figure npm run build prints.

Upgrading is npm install apexcharts@7.5.1.

🐛 Fixes

Drop a plugin's declarations when it empties its layer

api.drawn() reported drawings that were no longer on screen.

Declarations were cleared in one place, at the start of each draw pass, on the reasoning that layers are wiped there and repainted from state, so an inventory could never outlive what it described. That holds only for a plugin whose drawing is driven by chart renders.

An overlay plugin is not. Switching an overlay off is an interaction: it empties its layer and repaints, and no chart render happens, because going through one to remove a drawing would be an expensive way to do nothing. The declaration made for the previous paint then survived, and drawn() went on listing a trend line the viewer had just dismissed.

That is worse than the incompleteness the owner column exists to own up to. A reader can see that a list covers only the features which opted in; they cannot see that a row in it is stale.

Emptying the layer is the plugin saying, in the only way this API gives it, that it is drawing nothing. So that is now what it means:

api.on('draw', () => {
  const layer = api.layer()
  layer.line({ x1, y1, x2, y2, stroke: '#888' })
  api.declare({ id: 'trend', label: 'Trend' })
})

// When the viewer switches the overlay off, with no redraw involved:
layer.clear() // the declaration goes with the drawing

Scoped to the plugin that cleared. Another plugin's declarations are none of its business, and a clear that emptied the whole map would let one plugin erase everyone's work from a readout.

Found by the first thing to consume drawn() rather than by review: an inventory panel that listed an overlay which had been switched off. An API with no consumer is an API whose lifecycle has not been tested, and this one was published without one.

10 hours ago
apexcharts.js

💎 Version 7.5.0

A minor release for plugin authors. Weave goes to API v6 with four additions, and the theme running through all of them is the same: the chart knew something a plugin had no way to ask for, so the plugin either guessed, or reached for the caller's config, or did without.

The largest of the four ends a pattern this library had been quietly asking plugins to use. Options indexed by series position have no per-series escape hatch, so a plugin wanting one value for its own series had to write the array covering every series and put the caller's back afterwards. api.claim() replaces that with something the host resolves at the point it reads the option, so nothing is written at all.

Everything here is additive. No plugin needs to declare apiVersion: 6 to keep working, and a plugin that wants the new surface while still running on older hosts can now ask for it by name.

gzip
7.4.0 default bundle 268,612 B
7.5.0 default bundle 269,856 B

Both measured the same way, gzip at its default level over dist/apexcharts.min.js, so they are comparable with each other. Earlier release notes quoted a figure from the CI build, which lands a few hundred bytes apart from the committed bundle.

No API breaking changes. Upgrading is npm install apexcharts@7.5.0.

✨ New

Weave v6: api.capabilities and api.can()

The version integer never answered the question a plugin actually has, which is "does this host have X". A plugin declaring a version newer than the host is skipped outright, so one that supports several hosts declares the lowest version it can run on and then has to discover anything above that. Until now it did so by sniffing the facade for function members, which means every plugin reimplements the same guesswork against a surface it is deliberately not supposed to know the shape of.

if (api.can('claim')) {
  // ...
}

api.capabilities is the whole list, for logging and support. Names describe the capability rather than the version that introduced it, and are permanent once published: removing one is a breaking change on the same terms as removing a member.

Each name is probed off the facade that was actually built rather than copied from a constant, so a member that is ever made conditional drops out of the list instead of being advertised and then missing. The list is an array with the lookup behind a closure rather than a frozen Set, because Object.freeze does not touch a Set's internal slots: add() and delete() would go on working, and one plugin could quietly edit what every later plugin is told.

scales is deliberately not a capability. It is null for non-axis charts, which is a fact about the chart rather than about the host, and advertising it would tell a plugin on a pie chart that projection is available.

api.claim(): set an option for your own series, without writing the caller's config

stroke.dashArray and dataLabels.enabledOnSeries are indexed by series position. There is no per-series form of either, so a plugin that adds a computed series and wants it dashed, or wants the chart to stop printing labels over it, has had to write the array covering every series including the caller's, then restore what it found.

7.4.0 added api.info.stroke so a plugin could at least see what to restore, which made the pattern survivable rather than sound. Four things are wrong with it. The restore is stale the moment the caller calls updateOptions. It leaks if the plugin throws in between. A caller who wrote a single number gets it flattened into an array. And two plugins doing it at once fight, with the winner decided by execution order.

const claim = api.claim('stroke.dashArray', [
  { series: 'Revenue (forecast)', value: 6 },
])

claim.release()

A claim says what the plugin wants, and the host answers with it where the option is READ. Nothing is written, so there is nothing to restore, releasing is a deletion, and a caller's own updateOptions composes with the claim rather than reverting it. Claims resolve in order, so two plugins on one series produce a defined winner instead of whichever happened to run last.

Name the series rather than its position where you can. A name is resolved each time the option is read, so the claim follows that series when the caller adds, removes or reorders others.

Claimable options are an allowlist, stroke.dashArray and dataLabels.enabledOnSeries to begin with, each declaring its value type so a wrong one is dropped rather than drawn. An option that is not on the list returns null rather than throwing, so a plugin built against a newer host degrades instead of breaking. Every claim is released on teardown, on destroy, and if the host disables the plugin after repeated errors, so none can outlive the plugin holding it.

api.drawn() and api.declare(): what is on the chart

A plugin that wants to list what a chart is showing had no way to learn it. It knows its own overlays and can read the series off api.data, but the caller's annotations, another plugin's overlays and the ink strokes a viewer drew were all invisible to it. A layers panel and an export summary are the same question, and both were unanswerable.

api.drawn() // [{ id, kind, label, owner, visible }, ...]

api.declare({ id: 'trend-1', label: 'Trend' })

drawn() reports the series, the caller's annotations, and whatever plugins have declared, each entry naming its owner. The owner is the point rather than decoration: the list is only ever as complete as the features that opted into it, so a reader can say what its inventory covers instead of presenting a partial list as everything.

declare() is how a plugin joins, called from its draw handler. Declarations are cleared with the layers at the start of every draw, so an inventory can never outlive the drawing it describes, and declaring the same id twice replaces it rather than growing a duplicate row.

Read only, deliberately. Removing or hiding another feature's output is a much larger promise than this platform makes: it would mean one plugin reaching into another's state with no way for the owner to refuse.

One limitation worth knowing. Annotations do not carry a caller id. The id on a point annotation is the key of a deferred-execution entry rather than a handle on the drawing, so entries fall back to annotation:<type>:<index> and take their label from label.text where the caller wrote one.

api.info.title, and the modifier keys on a pointer event

Two small reads.

api.info.title is what the chart calls itself. A plugin that has to name this chart to somebody, a page-level readout listing several of them, otherwise heads each row with the container's id, which is a string written for a stylesheet rather than for a reader. The title is the name the page already chose and already shows. It is an empty string rather than undefined for an untitled chart, so it drops into a template without a guard.

api.info.title // 'Revenue by region', or ''

modifiers on the pointer payload reports the keys held during the interaction. Shift-click to add to a selection is the gesture that page-level coordination wants and could not express, because the keys exist only on the DOM event, which the pointer handler had been discarding.

api.pointer((e) => {
  if (e.modifiers.shift) { /* add to the selection */ }
})

Always the same four booleans, shift, ctrl, alt and meta, never partial and never undefined, because a plugin writes e.modifiers.shift inside a viewer's click and a sometimes-missing key is how that becomes a crash. All four are false where there was no DOM event, which is the honest answer for a keyboard or programmatic selection.

🐛 Fixes

The LICENSE branches on which plan the product needs

Two changes, both generated from one template shared across the organisation.

Products with no free tier no longer print the Community sections. Their files told a reader under $2M in revenue that they could use the product for free, and said it in five separate places: the dual-license opening, the Community section itself, the non-profit budget branch, the line about work built only from free features, and the acceptance list. The runtime never agreed: those products check the licence over the whole product, so no key means a watermark whatever the customer earns.

Products that do have a free tier now say what is in it. The Community section described who qualifies, on revenue, non-profit status or educational use, and never what you actually get. ApexCharts and the others with a free tier now list which features are free and which need Premium, taken from the same lists the pricing page renders.

🧹 Housekeeping

The Weave feature module is now 4.48 KB gzipped on top of core, up about 1.2 KB in this release, against a Tier-1 budget of roughly 5 KB. That was measured by building the default bundle with and without it, which the build reports as 263.53 KB and 259.05 KB gzipped, because the budget test checks Tier-1 membership rather than bytes. Worth measuring again before the next addition rather than assuming the headroom is still there.

11 hours ago
embed-pdf-viewer

Release Next v3.0.0-next.14

@cloudpdf/contract@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Describe measurement annotation fields and add typed APIs to read page viewports and update page calibration.

@cloudpdf/engine@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Expose page measurement calibration and viewport reads in the cloud engine, and deliver viewport change events with document version coherence.

  • #800 by @LazyCompiler – Cloud-backed search honours the ignoreWhitespace query flag, which travels inside the search token, and search cursors are pinned to it: replaying a cursor minted with the flag against a query without it (or vice versa) is rejected with InvalidArg, matching the local engine.

@cloudpdf/sdk@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Add generated page viewport and scale APIs and measurement annotation types.

@cloudpdf/server@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Persist page measurement calibration in layer artifacts with authorization and audit events. Calibration advances the document version while retaining existing page cache versions and annotation scales.

  • #800 by @LazyCompiler – The layer search routes (/v1/docs/:docId/layers/:layerName/search/{rects,full}/data) accept ignoreWhitespace=true alongside the other query flags and forward it to the engine, so a cloud search for invoice finds a letter-spaced i n v o i c e. Combining it with regex=true is rejected with InvalidArg, and the flag is carried by the search tokens that page through results.

@embedpdf/core-annotation@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Add distance drawing with separate endpoint and leader placement, four geometry handles, and directly draggable captions. Keep previews, hit testing, and selection bounds aligned, including short dimensions with outside arrows and displaced-label connectors. Measurement labels use the engine's PDF-coordinate rounding rules.

    Rotate measurements around the center of their complete oriented selection frame, including leaders and displaced captions. Use the same frame for pointer rotation, quarter turns, reset, selection, and hit testing, keeping the center stable after a saved appearance is reloaded. Attach the rotation handle to the selection border without extra measurement-specific spacing.

    Add perimeter and area creation through the existing polyline and polygon gestures, live labels, direct caption dragging, and complete selection bounds. Carry manual PDF-space caption centers through whole-shape transforms while vertex edits leave them fixed. Reject invalid area creation and vertex edits.

@embedpdf/engine-core@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Add measurement DTOs, page calibration contracts, and shared distance, perimeter, area, and number-format helpers. Caption positions use PDF coordinates and support partial updates and explicit resets.

    Report invalid geometry for crossing, overlapping, or degenerate area boundaries while accepting either winding and an explicit closing vertex.

  • #800 by @LazyCompiler – Add the ignoreWhitespace flag to SearchQuery. A literal query folded with it drops whitespace on both sides instead of collapsing it, so invoice finds the letter-spaced i n v o i c e that OCR'd scans and tracked-out headings produce, and total amount finds totalamount. Hits still span the original text including the dropped whitespace, and wholeWord boundaries are checked on the original text. The flag is literal-only — validateSearchQuery rejects it together with regex (ignore-whitespace-with-regex) — and it round-trips through search tokens. foldText gains the matching dropWhitespace option, and the shared search conformance suite covers the flag.

@embedpdf/engine@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Support distance, perimeter, and area measurements through the local engine. Add page measurement viewport reads and calibration writes, with persistence in saved PDFs and layers and viewport change events.

@embedpdf/engine-services@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Read and write PDF measurement dictionaries and viewports, derive labels on geometry or scale edits, and preserve imported labels on style edits. Move manual shape captions with rigid geometry transforms and validate measurement input before native writes.

    Avoid an additional full-document buffer copy when exporting a saved PDF.

  • #800 by @LazyCompiler – Local engines honour the ignoreWhitespace search flag: a query carrying it re-folds the cached page text with whitespace dropped, so invoice finds a letter-spaced i n v o i c e, and search cursors key on the flag so a resumed search never mixes hits from the two folds. Combining the flag with regex is rejected with InvalidArg.

@embedpdf/react@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Add the measurement feature entry with reactive calibration, page-scale, and readout hooks. Render rotated distance captions and use the standard square handles for measurement endpoints and leaders during annotation gestures.

@embedpdf/plugin-annotation@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Add distance and calibration presets, point-based viewport scale selection, and per-annotation recalculation reports. Persist leader and caption edits in native PDF fields, preserve the measured endpoints during offset edits, and keep derived measurement values read-only in comments.

    Use the standard selection spacing for measurement annotations.

    Keep locally created and edited measurements vector-rendered after the engine saves their appearance, matching the existing annotation lifecycle and avoiding repeated switches to raster rendering.

    Add area and perimeter presets with scale snapshots captured at the first vertex. Persist shape captions and derived values through ordinary annotation edits, retaining vector rendering after engine responses.

@embedpdf/plugin-measurement@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Introduce page calibration, scale presets, units, precision, measurement readouts, and optional recalculation of existing annotations. Report partial results across pages and support session-only calibration on older engines.

    Expose area unit choices and independent area-unit updates that preserve distance formatting.

@embedpdf/viewer-chrome@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Add a Measure toolbar with distance drawing, a scale sidebar, and known-length calibration controls. Support Escape to cancel an unfinished drawing, with English and Spanish labels.

    Use distinct calibration and scale-setting icons that inherit the viewer's theme and active-state colors.

    Add Perimeter and Area tools, dynamic stroke-colored measurement icons across toolbar and cursor, separate area-unit controls, selected area/perimeter readouts, and a reset-label-position action.

@embedpdf/viewer@3.0.0-next.14

Minor Changes

  • #827 by @bobsingor – Export MeasurementToken through every viewer entry point so applications can access page calibration and measurement controls through the viewer handle.

@cloudpdf/viewer@3.0.0-next.14

@cloudpdf/viewer-react@3.0.0-next.14

@embedpdf/core-acrojs@3.0.0-next.14

@embedpdf/core-geometry@3.0.0-next.14

@embedpdf/core-js-sandbox@3.0.0-next.14

@embedpdf/core@3.0.0-next.14

@embedpdf/core-signature@3.0.0-next.14

@embedpdf/core-stage@3.0.0-next.14

@embedpdf/core-ui@3.0.0-next.14

@embedpdf/engine-runtime@3.0.0-next.14

@embedpdf/engine-runtime-darwin-arm64@3.0.0-next.14

@embedpdf/engine-runtime-darwin-x64@3.0.0-next.14

@embedpdf/engine-runtime-linux-arm64@3.0.0-next.14

@embedpdf/engine-runtime-linux-x64@3.0.0-next.14

@embedpdf/engine-runtime-linuxmusl-arm64@3.0.0-next.14

@embedpdf/engine-runtime-linuxmusl-x64@3.0.0-next.14

@embedpdf/engine-runtime-wasm32@3.0.0-next.14

@embedpdf/engine-runtime-win32-arm64@3.0.0-next.14

@embedpdf/engine-runtime-win32-x64@3.0.0-next.14

@embedpdf/angular@3.0.0-next.14

@embedpdf/web@3.0.0-next.14

@embedpdf/plugin-actions@3.0.0-next.14

@embedpdf/plugin-commands@3.0.0-next.14

@embedpdf/plugin-form@3.0.0-next.14

@embedpdf/plugin-i18n@3.0.0-next.14

@embedpdf/plugin-interaction@3.0.0-next.14

@embedpdf/plugin-link@3.0.0-next.14

@embedpdf/plugin-metadata@3.0.0-next.14

@embedpdf/plugin-page-edit@3.0.0-next.14

@embedpdf/plugin-redaction@3.0.0-next.14

@embedpdf/plugin-render@3.0.0-next.14

@embedpdf/plugin-search@3.0.0-next.14

@embedpdf/plugin-selection@3.0.0-next.14

@embedpdf/plugin-shell@3.0.0-next.14

@embedpdf/plugin-signature@3.0.0-next.14

@embedpdf/plugin-stage@3.0.0-next.14

@embedpdf/plugin-stamp@3.0.0-next.14

@embedpdf/plugin-view-manager@3.0.0-next.14

@embedpdf/viewer-react@3.0.0-next.14

15 hours ago
ant-design

6.6.5

  • 🐞 Fix numeric 0 content rendering across Result, message, notification, Avatar, Modal, Descriptions, and Form.Item. #59153 #59125 #59289 @bhumin18 @nrps9909 @QDyanbing
  • Upload
    • 🐞 Fix Upload.Dragger custom style.height being overridden when the height prop is not set. #59319 @dogledogle
    • ♿ Fix Upload file names being focusable as buttons when no preview action is available. #59295 @QDyanbing
  • Transfer
    • 🐞 Fix Transfer calling a stale onSelectChange callback after it is replaced or removed. #59307 @yunfeizhu
    • 🐞 Fix Transfer footer callbacks not receiving direction when using rest parameters. #59303 @QDyanbing
  • 🐞 Fix Avatar not retrying image loading after srcSet changes. #59297 @QDyanbing
  • 🐞 Fix Anchor scrolling and Table and Transfer range selection using stale values after updates. #59308 @QDyanbing
  • 🐞 Fix Select inconsistent single and multiple heights after customizing global fontSize or lineHeight. #59298 @zombieJ
  • 🤖 Fix Tooltip, Popover, Popconfirm, and Slider TypeScript definitions accepting unsupported rc Tooltip props. #59288 @QDyanbing
  • 🛎 Fix Drawer not warning that destroyOnClose is deprecated. #59299 @dogledogle

  • 🐞 修复 Result、message、notification、Avatar、Modal、Descriptions 和 Form.Item 无法正确渲染数值 0 内容的问题。#59153 #59125 #59289 @bhumin18 @nrps9909 @QDyanbing
  • Upload
    • 🐞 修复 Upload.Dragger 未设置 height 属性时自定义 style.height 被覆盖的问题。#59319 @dogledogle
    • ♿ 修复 Upload 没有可用预览操作时文件名仍可作为按钮聚焦的问题。#59295 @QDyanbing
  • Transfer
    • 🐞 修复 Transfer 在替换或移除 onSelectChange 后仍调用旧回调的问题。#59307 @yunfeizhu
    • 🐞 修复 Transfer 使用剩余参数的 footer 回调无法获取 direction 的问题。#59303 @QDyanbing
  • 🐞 修复 Avatar 图片加载失败后更新 srcSet 无法重新加载的问题。#59297 @QDyanbing
  • 🐞 修复 Anchor 滚动及 Table 和 Transfer 范围选择在更新后仍使用旧值的问题。#59308 @QDyanbing
  • 🐞 修复 Select 自定义全局 fontSizelineHeight 后单选与多选高度不一致的问题。#59298 @zombieJ
  • 🤖 修正 Tooltip、Popover、Popconfirm 和 Slider 的 TypeScript 类型定义,避免接受实际无效的 rc Tooltip 属性。#59288 @QDyanbing
  • 🛎 修复 Drawer 未提示 destroyOnClose 已废弃的问题。#59299 @dogledogle
19 hours ago
zip.js

v2.16.0

What's Changed in v2.16.0

New features

  • A fallback codec class passed as CompressionStreamFallback or DecompressionStreamFallback can declare two static flags, now documented on CompressionStreamLike and DecompressionStreamLike. supportedFormats lists the formats the class supports, e.g. ["deflate-raw", "gzip"], and the library reads it instead of probing a format by constructing the class. requiresModule, when true, says the class cannot be constructed before the module of the worker is ready, the WebAssembly module of zip.js or the module loaded by the init function passed to initWorker: the library then waits for that module, uses the native codec instead when the module fails to load, and opens a compression class as "gzip" to read the CRC-32 of the data from the trailer, so such a class must support that format

Performance

  • With checkCrc32: true, the WebAssembly codec and the native DecompressionStream verify the CRC-32 while inflating, so the separate pass over the output on the JavaScript thread is gone for those two codecs. On the WebAssembly codec the check costs about 7 ms per 20 MB instead of 15, and reading a 20 MB text entry takes 53 ms instead of 62 ms on Node.js; on Node's DecompressionStream the pass was already overlapped by the threadpool and the gain is within the noise. Entries compressed with deflate64 or a registered codec, AES entries whose CRC-32 is not stored, and the pure-JavaScript zlib port keep the separate pass. The mechanism is the one the writer has used since 2.15.0: the raw deflate data is framed as gzip with a trailer holding the CRC-32 and size declared by the entry, which the inflater checks
  • HttpReader with combineSizeEocd: true, the option, off by default, that fetches the last 64 KB of the archive with the request that reads its size, now serves the entry data lying in those bytes from that response. Reading an archive shorter than 64 KB costs that one request, where each entry used to issue a range request of its own, and in a larger archive an entry stored in its last 64 KB costs no extra request. With useXHR: true the reader already behaved that way

Bug fixes

  • On a host whose DecompressionStream lacks "deflate-raw", Chromium 80 to 102 and Node.js 18 for instance, an entry with a corrupted CRC-32 read with checkCrc32: false was delivered as if it were valid, and an entry whose stored uncompressed size was wrong failed only after a 5 second watchdog. The gzip decoder of such a host checks the CRC-32 and size in the trailer it is given regardless, so the verification is free: a corrupted entry now fails with ERR_INVALID_CRC32 whatever checkCrc32 says, and a wrong size fails with ERR_INVALID_UNCOMPRESSED_SIZE as soon as the output has been read
  • With useCompressionStream: false and a CompressionStreamFallback or DecompressionStreamFallback whose constructor throws, the entry now fails with that error. It used to be served silently by the gzip format of the native codec, so useCompressionStream: false was not honoured

Documentation

  • BENCHMARKS.md states the cost of the CRC-32 check on read: about 7 ms per 20 MB on the WebAssembly codec, within the noise on Node's DecompressionStream, and about 15 ms on the pure-JavaScript zlib port, which keeps a separate pass

Tests and continuous integration

  • New tests pin the gzip trailer on the inflate side, with the corrupted CRC-32 and size errors on the WebAssembly and native codecs and the raw route with the check off, the end of archive cache of HttpReader with the request counts of a small archive and of an entry in the cached tail, the propagation of a fallback codec failure, the CRC-32 and size verification on a host without "deflate-raw", and the formats such a host is asked for on the deflate and inflate sides
  • The continuous integration runs on Ubuntu 26.04, and the reader stream release test allows 30 s per step instead of 5, a test timeout only, which the Firefox 102 lane of the native build exceeded under load in three of four runs

Full Changelog: https://github.com/gildas-lormeau/zip.js/compare/v2.15.0...v2.16.0

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

21 hours ago
next.js

v16.4.0-canary.37

Misc Changes

  • Preserve closed-parameter restrictions in client route prediction: #98889
  • [test] Fix deployment tests that relied on implicit startup: #98935
  • Turbopack: Add support for specifying additional roots: #98003
  • Turbopack: Add symlinks and additional roots to NFT metadata: #98469

Credits

Huge thanks to @gnoff, @unstubbable, and @bgw for helping!

1 days ago
formatjs

formatjs_cli: 1.7.4

1.7.4 (2026-09-19)

Bug Fixes

  • deps: update Ruff crates together to 0.16.7 (#7461) (d8725bb)

Binaries

  • macOS Apple Silicon: formatjs_cli-darwin-arm64
  • Linux ARM64: formatjs_cli-linux-arm64
  • Linux x86_64: formatjs_cli-linux-x64
  • Windows x64: formatjs_cli-win32-x64.exe

Installation

# macOS (Apple Silicon)
curl -LO https://github.com/formatjs/formatjs/releases/download/formatjs_cli_v1.7.4/formatjs_cli-darwin-arm64
chmod +x formatjs_cli-darwin-arm64
sudo mv formatjs_cli-darwin-arm64 /usr/local/bin/formatjs

# Linux
curl -LO https://github.com/formatjs/formatjs/releases/download/formatjs_cli_v1.7.4/formatjs_cli-linux-x64
chmod +x formatjs_cli-linux-x64
sudo mv formatjs_cli-linux-x64 /usr/local/bin/formatjs

# Linux ARM64
curl -LO https://github.com/formatjs/formatjs/releases/download/formatjs_cli_v1.7.4/formatjs_cli-linux-arm64
chmod +x formatjs_cli-linux-arm64
sudo mv formatjs_cli-linux-arm64 /usr/local/bin/formatjs
# Windows x64 (PowerShell)
curl.exe -LO https://github.com/formatjs/formatjs/releases/download/formatjs_cli_v1.7.4/formatjs_cli-win32-x64.exe

Verification

Verify the checksums:

curl -LO https://github.com/formatjs/formatjs/releases/download/formatjs_cli_v1.7.4/checksums.txt
shasum -a 256 -c checksums.txt
1 days ago
formatjs

eslint-plugin-formatjs: 8.0.5

8.0.5 (2026-09-19)

Dependencies

  • The following workspace dependencies were updated
    • dependencies
      • @formatjs/icu-messageformat-parser bumped to 3.5.20
      • @formatjs/ts-transformer bumped to 4.4.22
1 days ago
formatjs

react-intl: 12.1.2

12.1.2 (2026-09-19)

Dependencies

  • The following workspace dependencies were updated
    • dependencies
      • @formatjs/icu-messageformat-parser bumped to 3.5.20
      • @formatjs/intl bumped to 6.1.2
      • intl-messageformat bumped to 12.1.2
1 days ago
formatjs

@formatjs/unplugin: 1.2.12

1.2.12 (2026-09-19)

Dependencies

  • The following workspace dependencies were updated
    • dependencies
      • @formatjs/icu-messageformat-parser bumped to 3.5.20
      • @formatjs/ts-transformer bumped to 4.4.22