Search Docs
Loading...
Skip to content

Version v1.82.0 Changelog August 28, 2026

Breaking Changes

  • Engine/Android: BlockApi.export takes a new optional progressCallback parameter after options. Calls that pass onPreExport or uriResolver positionally must switch to named arguments.

  • Editor/Web: Removed the legacyNonResponsivePanelPosition feature flag. Integrations that set it no longer force the wide layout.

  • Editor/Web: The video timeline controls bar is now driven by the Component Order APIs under the new ly.img.video.timeline.controls.bar UI area (cesdk.ui.setComponentOrder, getComponentOrder, insertOrderComponent, updateOrderComponent, removeOrderComponent). The built-in controls are registered as components (ly.img.video.timeline.background, .split, .playbackInfo, .playPause, .loop, .zoom, .toggle) and custom components can be added via cesdk.ui.registerComponent. A new ly.img.video.timeline.controls.bar Feature API flag gates the whole bar (parallel to ly.img.canvas.bar). Breaking: the SDK no longer ships a built-in order for this bar — without configuration the controls bar is empty and not rendered. Set the order explicitly to keep the previous controls. The bar’s internal DOM also changed from a fixed three-column grid to a flat flex row driven by ly.img.spacer components, so custom CSS targeting the old internal group containers no longer applies. To restore the previous controls:

    cesdk.ui.setComponentOrder({ in: 'ly.img.video.timeline.controls.bar' }, [
    'ly.img.video.timeline.background',
    'ly.img.video.timeline.split',
    'ly.img.spacer',
    'ly.img.video.timeline.playbackInfo',
    'ly.img.video.timeline.playPause',
    'ly.img.video.timeline.loop',
    'ly.img.spacer',
    'ly.img.video.timeline.zoom',
    'ly.img.video.timeline.toggle'
    ]);

    See the v1.82 migration guide and the starterkit-video-editor-ts-web / starterkit-advanced-video-editor-ts-web repositories (and the full starter kit upgrade) for more info.

  • Editor/Web: The clip ellipsis button on timeline clips can now be hidden through a dedicated Feature API flag, ly.img.video.timeline.clip.menu. It is enabled by defaultcesdk.feature.disable('ly.img.video.timeline.clip.menu') hides the button, cesdk.feature.enable(...) shows it again. The flag gates only the trigger; the clip context menu order set via cesdk.ui.setComponentOrder({ in: 'ly.img.video.clip.menu' }, ...) is unaffected. Breaking: integrators that maintain an explicit feature allowlist must add ly.img.video.timeline.clip.menu to keep the button visible (see the v1.82 migration guide; the starter kits list it in src/imgly/config/features.ts).

  • Engine: A block that has only a preview image is no longer pending. It renders the preview, so an export finishes. Use setState to keep a block pending.

  • Engine: isCapabilitySupported now answers for the codecs this build really has. hevcEncode is false on Linux, Windows and Android, where the engine has no HEVC encoder. It was true before.

  • Engine/Node: Added videoCodec to the video export options, with VideoCodec.H264 and VideoCodec.HEVC. It defaults to H.264, so existing exports are unchanged. Check isCapabilitySupported('hevcEncode') first: where the platform has no HEVC encoder, the export fails instead of falling back.

  • Engine/Node: Fixed enableHEVC being ignored. It is deprecated; use videoCodec.

  • Engine: Fixed missing picture on HEVC exports with audio.

  • Engine: Fixed an export that was refused leaving the encoder busy, which failed every later export.

  • Engine/Web: VideoMimeType is 'video/mp4' only. 'video/quicktime' was in the type, but the engine has never written a QuickTime file and rejected it at run time. Use 'video/mp4'. QuickTime stays valid for media you import.

Non Breaking Changes

  • Editor/Android: Add automatic caption generation. The new ly.img:plugin-auto-captions package adds a Generate Automatically action to the Add Captions sheet that transcribes the video’s speech into time-synced, styled captions. Register it with .then(::AutoCaptionsPlugin) { provider = GatewayTranscriptionProvider(apiKey = "sk_…") } to use ElevenLabs Scribe through the IMG.LY AI Gateway, or implement TranscriptionProvider to plug in any other speech-to-text service. Generation runs in a cancellable state and leaves the scene untouched when cancelled; captions land in a single undo step. Integrators who want to own the whole pipeline can replace AutoCaptionsPlugin.captionsGeneration with their own CaptionsGenerator and return their own SRT or VTT file — a provider stays required either way.

  • Editor/Android: Add caption editing to the video editor. Register the captions dock button to let users create captions manually, import SRT/VTT files, edit caption text and timing on a dedicated timeline lane, apply style presets, and fine-tune a selected caption from the caption inspector (Edit Captions, Style, Split, Format, Fill & Stroke, Text Background, Delete). While editing, an action bar above the keyboard merges, splits, adds, and deletes captions, and steps to the caption above or below; merging, adding, and deleting are also available by swiping a row. Return splits a caption at the cursor — or starts the next one at the end of the text — and Backspace at the start merges into the caption above, or deletes it when empty. Style presets and core styling — font, size, alignment, colors, and background — apply to every caption on the track. Captions are burned into the exported video by the engine.

  • Editor/Flutter: Added Swift Package Manager support to the imgly_editor plugin. Flutter 3.44 and later resolves the plugin via Swift Package Manager by default; CocoaPods keeps working on older Flutter versions.

  • Camera/Flutter: Added Swift Package Manager support to the imgly_camera plugin. Flutter 3.44 and later resolves the plugin via Swift Package Manager by default; CocoaPods keeps working on older Flutter versions.

  • Editor/Web: Added builder.Tabs() to switch between views inside a panel. Only the selected tab builds its content, each tab takes an optional icon, tooltip and isActive indicator, and the arrow keys, Home and End move between them.

  • Editor/Web: The animations panel shows In, Loop and Out as tabs rather than stacked sections, each marked when that group has an animation applied. The inspector’s Design/Placeholder switch and the caption panel’s Content/Style switch use tabs too.

  • Editor/iOS: Add an IMGLYEditor product to the IMGLYUI-swift Swift package. You can now depend on the editor on its own — the product the Starter Kit guides tell you to add — instead of pulling the whole IMGLYUI umbrella. import IMGLYEditor resolves against it directly.

  • Editor/Web: Bounded numeric controls in the inspector now have a minus and a plus button inside the input. A press steps the value and stops at the control’s limits, holding a button repeats the step, and a whole press becomes one undo step. Typing a value still works. The buttons are not tab stops, because the field’s Up and Down arrow keys already step.

  • Editor/Web: These controls replace their slider with a stepper: letter spacing, line height and paragraph spacing; polygon sides, star points, star inner diameter, line width and corner radius; cutout smoothing; and text background corner radius.

  • Editor/Web: These controls keep their field and gain the buttons: stroke width, cutout offset, grid width and height, shadow distance and blur, and text background horizontal and vertical padding.

  • Editor/Web: The font size control gains the same buttons and keeps its preset list. The list now opens on a click on the field, or with Alt+ArrowDown, and replaces the dropdown button beside it.

  • Editor/Web: Added a showStepper option to builder.NumberInput() that renders the same decrement and increment buttons.

  • Editor/Web: Added the translation keys input.stepper.change, input.stepper.decrease, input.stepper.increase, input.stepper.decreaseValue and input.stepper.increaseValue. The keys property.textBackground.horizontalPadding.description and property.textBackground.verticalPadding.description are gone, because the controls they described are steppers now and name their own buttons.

  • Engine: Added the pdfChunkSize export option, which sets the upper bound in bytes for a single chunk of PDF output. It matters most for a streamed export, where it is the memory the caller holds for one chunk: a larger value lowers the per-chunk overhead and raises that memory, a smaller value does the opposite. Leaving it unset keeps the engine default. A value outside the supported range is clamped into it rather than failing the export.

  • Engine: Added per-page progress reporting to PDF export on Web, iOS, and Android, mirroring video export progress. See the Export to PDF guide.

  • Editor/Web: The export dialog now shows a progress bar instead of a spinner while a multi-page PDF exports.

  • Editor/React Native: Added opt-in Swift Package Manager support to @imgly/editor-react-native for React Native’s experimental SPM mode (npx react-native spm, React Native 0.87 and later). CocoaPods currently remains the default integration path.

  • Editor/React Native: Fixed a crash on iOS when an export result contained no artifact, scene, or thumbnail — the result now carries null for the missing fields, matching Android.

  • Camera/React Native: Added opt-in Swift Package Manager support to @imgly/camera-react-native for React Native’s experimental SPM mode (npx react-native spm, React Native 0.87 and later). CocoaPods currently remains the default integration path.

  • Camera/React Native: Fixed a crash on iOS when openCamera received settings that could not be parsed — the call now rejects with error code E_PARSING instead.

  • Editor/Web: Added a Gap control to the document inspector that adjusts the spacing between the pages of a horizontally or vertically stacked scene, together with a Gap Unit dropdown that chooses whether the value is measured in Screen Pixels or in Design Units. Screen Pixels affects the canvas preview only — it keeps the gap constant on screen at any zoom level, while exports always interpret the gap in design units. Switching the unit never rewrites the number, so the same value is reinterpreted rather than converted. Both controls are shown only while a horizontal or vertical stack layout is active and the stack holds at least two pages — a stack’s spacing sits between its children, so there is nothing for it to do on a single page. The value is limited to 10000; the engine itself sets no upper bound, but a very large gap in Screen Pixels stays that size at every zoom level and puts the next page out of reach. Both rows can be hidden with the new ly.img.scene.layout.spacing feature flag.

  • Editor/Web: The scene layout buttons in the document inspector no longer reset the gap between pages. Previously, switching to a stacked layout — or clicking the already-active layout button — overwrote stack/spacing with a fixed 35 screen pixels, discarding any gap that had been set through engine.block.setFloat(stack, 'stack/spacing', …). The current gap is now carried forward instead, including across a round trip through the free layout, and 35 is used only when no stack exists to read a gap from. Whether this is visible depends on how the scene was created: a scene created through cesdk.actions.run('scene.create', …) with a page preset already starts at 35, so it looked the same before and after, while a scene created without a page preset starts at 48 and previously dropped to 35 on the first layout click. Either way, a gap your integration set through engine.block.setFloat(stack, 'stack/spacing', …) is no longer discarded.

  • Editor/Web: Switching a scene to the free layout now stores the stack gap on the scene in the metadata keys stackSpacing/spacing and stackSpacing/inScreenspace, so that selecting a stacked layout again restores it. Like the existing freeLayout/position* keys written by the same code path, these are visible to integrations through engine.block.findAllMetadata(scene) and are saved with the scene.

  • Engine/iOS: Added two BlockAPI.export overloads that deliver the exported PDF incrementally in bounded chunks instead of building the whole document in memory, so large multi-page documents such as photo books and magazines export without exhausting memory. One writes the bytes into a file as they are encoded, the other hands each chunk to a closure. Because the chunks are handed over synchronously, a slow destination throttles the encoder rather than buffering chunks in memory.

  • Editor/iOS: Added the exportToFile configuration helper, which fuses exporting and writing the result to a file into a single streamed pass so the full document is never held in memory.

  • Editor/Web: Added a timeline.setHeight action to control the video timeline’s height. Call cesdk.actions.run('timeline.setHeight', { height: 320 }) to give the timeline a fixed height, { height: 'auto' } to restore the default content-hugging behaviour, or { maxHeight: 400 } to cap how tall the auto-growing timeline may get.

  • Editor/Web: Added a timeline/transitionControlVisibility editor setting controlling the clip transition control on the video timeline. Set cesdk.engine.editor.setSetting('timeline/transitionControlVisibility', 'always') to keep the control shown, or 'hover' (the default) to reveal it on hover/focus.

  • Editor/Web: Added keyboard shortcuts for moving between editor regions:

    • F6 / Shift+F6 now also cycle through the timeline, the navigation bar, the dock, the canvas bars, and open panels.
    • Alt+4 — move focus to the timeline.
    • Alt+5 — move focus to the navigation bar.
    • Alt+6 — move focus to the dock.
    • Alt+7 / Alt+8 — move focus to the canvas bar above / below the canvas.
  • Editor/Web: Improved keyboard and screen-reader accessibility of the video timeline and the editor chrome:

    • Timeline clips are tab stops: Enter / Space selects a clip (Shift adds to the selection), and screen readers announce the clip’s name, duration, and selection state.
    • The playhead is an operable slider: arrow keys step, Shift+Arrow, PageUp / PageDown take larger steps, Home / End jump to the start and end. Clicking it no longer moves keyboard focus.
    • The trim inspector, the trim handles, and the timeline resize handle can be operated with the arrow keys.
    • Popover menus such as the clip context menu navigate with the arrow keys, and the clip context-menu button has an accessible name.
    • The navigation bar, dock, canvas bars, inspector bar, and panels are exposed as ARIA landmarks.
    • Panels no longer trap keyboard focus. A panel opened from a control moves focus into it and returns focus to that control or block when it closes.
    • A collapsed timeline and hidden UI elements (an empty inspector bar, covered stacked panels) are skipped by keyboard navigation.
    • Focus rings are no longer clipped by scrolling containers and no longer appear after pointer interactions.
  • Engine/Web, Engine/Node: The default typeface assets now ship as WOFF2 instead of TTF. The font files are about 66% smaller, so editors load fonts faster on slow connections. Scenes that reference the previous TTF files continue to work.

  • Engine/Web, Engine/Node: A PDF export that uses a WOFF2 font embeds the glyph outlines instead of the font program. This already applied to WOFF and variable fonts, and now also applies to the default typefaces. The rendered output and the text search stay the same.

  • Editor/Web: The cutout inspector panel now shows the Offset and Smoothing controls again.

  • Editor/Web: Fixed an issue where the highlighted option in dropdowns could scroll out of view while navigating with the Arrow Up and Arrow Down keys.

  • Engine: Cancelling a PDF export now stops it. Before, an export that was cancelled kept rendering every remaining page and only the result was dropped. On Web an abortSignal stops the export, on iOS the cancellation of the enclosing Task, and on Android the cancellation of the coroutine. A cancelled export fails with ENCODE.EXPORT_CANCELLED.

  • Engine: The licensed codec concurrency limit now only applies when video or audio codecs are actually used. Image-only workloads no longer reserve a codec license slot, and a video operation fails with a clear error when all slots are in use.

  • Engine/Node Native: Engine creation no longer stops the JavaScript event loop while the license server activates an API key. This applies to the native bindings only.

  • Editor/Flutter: Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.

  • Editor/Web: A font size applies to the selected part of a text, whether stepped, typed or picked from the list.

  • Editor/iOS: A video picked from the photo roll now keeps its own duration instead of being added as a 5 second clip. The duration is read from the video when it is imported, so it also shows on the asset library tile.

  • Engine: relocateResource now moves every reference to a resource, also the references that carry a URL fragment. A variable font keeps its weight after the move.

  • Engine: A saved .imgly archive stays editable after you load it and move its resources. Before, the scene reported a buffer URL and could not be saved.

  • Editor/Web: Fixed an issue in Safari where edge artifacts on asset library cards remained visible on low pixel density displays, even without hovering.

  • Engine: Saving to a string with a resource callback no longer hangs, and no longer reports the resources of an earlier save.

  • Engine: Saving a scene that nothing has edited now gives the same bytes every time. Before, the blocks, the selection, the block metadata, the spot colours and the template variables were written in an internal order that moved on every load, so hashing a scene to detect a change, content-addressed storage and ETag caching all reported a change that had not happened. The saved content was never affected.

  • Engine: Thin seams no longer appear on the canvas between opaque blocks that share a straight, axis-aligned edge.

  • Engine/Swift: Fixed ExportOptions.webpQuality being ignored by exportWithColorMask. WebP exports with a color mask now use the given quality instead of the default.

  • Engine/Swift: Deprecated LicenseError.missing. An empty license key activates evaluation mode instead of failing, so this error is never thrown. Exhaustive switch statements over LicenseError keep compiling unchanged.

  • Editor/Android: Fixed dragging a clip into a gap narrower than the clip on an overlay track moving that clip and its left-hand neighbour to the start of the timeline. The clip now lands right after its neighbour and pushes the following clips later.

  • Editor/iOS: Fixed dragging a clip into a gap narrower than the clip on an overlay track moving that clip and its left-hand neighbour to the start of the timeline. The clip now lands right after its neighbour and pushes the following clips later.

  • Engine/Web/Node: editor.setURIResolver() and editor.setURIResolverAsync() now remove the resolver when you give them null or undefined. Before, the resolver stayed active.

  • Engine: Exporting a still image of a block containing a video fill now waits for the frame at the current playback time to be decoded. Previously the export could return the previously decoded frame, so stills taken at different playback times (timeline scrubbing, thumbnail-at-time) could come back identical.

  • Editor/Web: Fixed an issue where the Animations control and the “Allow to Change Animations” placeholder option were enabled in design-based starterkits.

  • Engine/Linux: Improved compatibility with H.265 video files in the licensed codec pipeline.

  • Engine/Swift: Export results no longer copy the whole payload when they cross into Swift. This lowers the peak memory of image, PDF, video, audio and color mask exports by the size of one result.

  • Engine/Node: Export results no longer copy the whole payload when they cross into JavaScript, which lowers the peak memory of every export by the size of one result. Applies to @cesdk/node-native.

  • Engine: Fixed a video export result becoming invalid when a later export started. Keeping the data of one export while starting the next one now works.

  • Engine/Node: A PDF export no longer builds the whole document in memory. The engine writes it to a file in the temp directory while the export runs, so the peak no longer grows with the number of pages. Large multi-page documents such as photo books and magazines export without exhausting memory. The result of export is unchanged.

  • Engine/Node: Platform capabilities are now detected while the engine starts. Before this, every capability reported unsupported, so features that ask for one, such as the staged export above, never ran.

  • Engine/Web: PDF exports via engine.block.export() are now written to a temporary file (origin private file system) while the export runs, instead of being assembled in memory, on browsers that support it. Exporting a large document no longer holds the finished file in memory and the returned Blob is backed by that file. Its content and type are unchanged. Browsers without support keep the previous behavior. The temporary file backs the returned Blob, so it stays on disk after the export and is collected automatically.

  • Engine/Android, Engine/Swift: PDF exports are now written to a temporary file while the export runs, instead of being assembled in memory. Exporting a large document no longer holds the finished file in memory. The exported bytes are unchanged. The temporary file is removed as soon as the export result is released.

  • Editor/Web: Softened the light theme’s hover fill (--ubq-interactive-hover), which held the same colour as the input background. Buttons, asset cards, select options, checkboxes and the timeline clip seam all hover differently now.

  • Editor/Web: Added the --ubq-interactive-input-hover theming token, the hover fill for elements sitting on an input background.