Changelog
Explore the recent changes made to CreativeEditor SDK.
Our release notes contain more details on features and changes.
Download the full changelog as a plain text file.
Recent Releases
Version v1.82.0 Changelog August 28, 2026
Breaking Changes
-
Engine/Android:
BlockApi.exporttakes a new optionalprogressCallbackparameter afteroptions. Calls that passonPreExportoruriResolverpositionally must switch to named arguments. -
Editor/Web: Removed the
legacyNonResponsivePanelPositionfeature 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.barUI 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 viacesdk.ui.registerComponent. A newly.img.video.timeline.controls.barFeature API flag gates the whole bar (parallel toly.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 byly.img.spacercomponents, 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 default —cesdk.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 viacesdk.ui.setComponentOrder({ in: 'ly.img.video.clip.menu' }, ...)is unaffected. Breaking: integrators that maintain an explicit feature allowlist must addly.img.video.timeline.clip.menuto keep the button visible (see the v1.82 migration guide; the starter kits list it insrc/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
setStateto keep a block pending. -
Engine:
isCapabilitySupportednow answers for the codecs this build really has.hevcEncodeisfalseon Linux, Windows and Android, where the engine has no HEVC encoder. It wastruebefore. -
Engine/Node: Added
videoCodecto the video export options, withVideoCodec.H264andVideoCodec.HEVC. It defaults to H.264, so existing exports are unchanged. CheckisCapabilitySupported('hevcEncode')first: where the platform has no HEVC encoder, the export fails instead of falling back. -
Engine/Node: Fixed
enableHEVCbeing ignored. It is deprecated; usevideoCodec. -
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:
VideoMimeTypeis'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-captionspackage 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 implementTranscriptionProviderto 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 replaceAutoCaptionsPlugin.captionsGenerationwith their ownCaptionsGeneratorand return their own SRT or VTT file — aproviderstays required either way. -
Editor/Android: Add caption editing to the video editor. Register the
captionsdock 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_editorplugin. 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_cameraplugin. 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 andisActiveindicator, 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
IMGLYEditorproduct to theIMGLYUI-swiftSwift 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 wholeIMGLYUIumbrella.import IMGLYEditorresolves 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
showStepperoption tobuilder.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.decreaseValueandinput.stepper.increaseValue. The keysproperty.textBackground.horizontalPadding.descriptionandproperty.textBackground.verticalPadding.descriptionare gone, because the controls they described are steppers now and name their own buttons. -
Engine: Added the
pdfChunkSizeexport 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-nativefor 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
nullfor the missing fields, matching Android. -
Camera/React Native: Added opt-in Swift Package Manager support to
@imgly/camera-react-nativefor 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
openCamerareceived settings that could not be parsed — the call now rejects with error codeE_PARSINGinstead. -
Editor/Web: Added a
Gapcontrol to the document inspector that adjusts the spacing between the pages of a horizontally or vertically stacked scene, together with aGap Unitdropdown that chooses whether the value is measured inScreen Pixelsor inDesign Units.Screen Pixelsaffects 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 to10000; the engine itself sets no upper bound, but a very large gap inScreen Pixelsstays that size at every zoom level and puts the next page out of reach. Both rows can be hidden with the newly.img.scene.layout.spacingfeature 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/spacingwith a fixed35screen pixels, discarding any gap that had been set throughengine.block.setFloat(stack, 'stack/spacing', …). The current gap is now carried forward instead, including across a round trip through the free layout, and35is 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 throughcesdk.actions.run('scene.create', …)with a page preset already starts at35, so it looked the same before and after, while a scene created without a page preset starts at48and previously dropped to35on the first layout click. Either way, a gap your integration set throughengine.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/spacingandstackSpacing/inScreenspace, so that selecting a stacked layout again restores it. Like the existingfreeLayout/position*keys written by the same code path, these are visible to integrations throughengine.block.findAllMetadata(scene)and are saved with the scene. -
Engine/iOS: Added two
BlockAPI.exportoverloads 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
exportToFileconfiguration 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.setHeightaction to control the video timeline’s height. Callcesdk.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/transitionControlVisibilityeditor setting controlling the clip transition control on the video timeline. Setcesdk.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+F6now 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/Spaceselects a clip (Shiftadds 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/PageDowntake larger steps,Home/Endjump 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.
- Timeline clips are tab stops:
-
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
abortSignalstops the export, on iOS the cancellation of the enclosingTask, and on Android the cancellation of the coroutine. A cancelled export fails withENCODE.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:
relocateResourcenow 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
.imglyarchive stays editable after you load it and move its resources. Before, the scene reported abufferURL 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
ETagcaching 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.webpQualitybeing ignored byexportWithColorMask. 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. Exhaustiveswitchstatements overLicenseErrorkeep 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()andeditor.setURIResolverAsync()now remove the resolver when you give themnullorundefined. 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
exportis 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 returnedBlobis backed by that file. Its content and type are unchanged. Browsers without support keep the previous behavior. The temporary file backs the returnedBlob, 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-hovertheming token, the hover fill for elements sitting on an input background.
Version v1.81.1 Changelog August 26, 2026
Breaking Changes
Non Breaking Changes
- Engine/Swift: Revert the video export cancellation fix introduced in 1.81.0, which could crash the app when a video export was cancelled.
Version v1.81.0 Changelog August 24, 2026
Breaking Changes
- Engine/Android: Removed
TransitionType.None. To remove a transition, destroy the transition block returned byengine.block.getTransition(...).
Non Breaking Changes
- Engine/Android, Editor/Android: Added portable CE.SDK Android agent skills for documentation, explanations, and project scaffolding with Kotlin and Jetpack Compose.
- Editor/Android: Added UI support for transitions, including the
SheetType.Transitionsheet type,InspectorBar.Button.rememberTransition, and buttons in theTimeline. - Editor/Android: Added animation and transition previews for a better editing experience.
- Engine/Web/Android/iOS:
scene.saveToArchiveaccepts a compression option for the scene inside the archive. - Plugins/iOS: Add the
IMGLYPluginAutoCaptionsplugin for automatic caption generation in the video editor. RegisteringAutoCaptionsPluginadds a primary “Generate Automatically” action to the Add Captions sheet that transcribes the scene’s audible content and creates styled, time-synced captions. The built-inGatewayTranscriptionProviderruns the ElevenLabs Scribe v2 speech-to-text model through the IMG.LY AI Gateway using an IMG.LY API key; any other speech-to-text service can be integrated by implementingTranscriptionProvider. - Editor/iOS: Add
EditorConfiguration.Builder.captionsGeneration(_:)to back the Add Captions sheet’s “Generate Automatically” action with a custom caption generation callback. - Editor/iOS: Add caption editing to the video editor. Register the
Dock.Buttons.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. - Engine/Swift, Editor/iOS: Added portable CE.SDK Swift agent skills for documentation, explanations, and project scaffolding across iOS, macOS, and Mac Catalyst.
- Editor/Web: Transitions can now be opened from the inspector bar and the inspector panel.
- Engine: Scenes and archives are now compressed with Zstd by default, making saved scenes far smaller and both saving and loading faster. Saved scene strings change shape: they carry a
UBQ2prefix instead ofUBQ1. Loading accepts either, so existing scenes keep working. - Editor/Android: Fixed the background removal plugin decoding the source image on the main thread, which blocked the UI and triggered a StrictMode
DiskReadViolation. - Editor/Android: Fixed the editor reading file modification times on the main thread when loading file-based images, which triggered a StrictMode
DiskReadViolation. - Camera/Android: Fixed the photo preview reading the captured file’s modification time on the main thread, which triggered a StrictMode
DiskReadViolation. - Engine/Android: HDR videos (HDR10/PQ and HLG) are now tone-mapped to SDR during decoding, fixing severely incorrect colors in preview and export. This uses the HDR-to-SDR tone-mapping request introduced in Android 12, and only takes effect where the device’s video decoder supports it — in practice recent Qualcomm/Snapdragon hardware decoders.
- Engine/Android: Fixed a StrictMode
LeakedClosableViolationcaused by the internal OkHttp cache when a network fetch returned an error response (e.g. HTTP 404). - Editor/Android: the Resize sheet no longer shows the Crop/Cover/Fit content fill mode picker, honoring
SheetType.Crop.Mode.ResizeAll.hasContentFillMode = falseand matching iOS - Editor/Android: Fixed
shareFileresolving the file’s content uri on the main thread, which triggered a StrictModeDiskReadViolationwhen sharing an exported file. The uri is now resolved on a background thread and any failure is surfaced via theerrorstate instead of being thrown. - Engine: Fixed
saveToArchiveleaving remote URLs in the saved scene instead of bundling the referenced bytes. - Engine: Fixed variable-font handling in scene and block archives.
- Engine: Fixed a crash in audio waveform thumbnail generation. The crash could happen once the last requested sample was delivered or when the audio block was destroyed from within the chunk callback.
- Engine: Scene files no longer store the
basePathsetting. AbasePathstored by an older version is ignored on load. - Editor/Flutter: Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.
- Engine/Web: Fixed
scene.getMode()throwing aTypeErrorinstead of returningnullwhen no scene exists. - Engine: A text or caption style preset no longer replaces the text of a block that already exists. A preset writes its own text only when it makes a new block.
- Engine: PDF export with
exportPdfWithHighCompatibility: falsenow embeds photos as their original JPEG data if possible, drastically reducing export time and file size of image-heavy documents such as photo books. - Engine: Added the
pdfImageQualityexport option. Values below the default of 1.0 encode rasterized images (e.g. with effects applied) as lossy JPEG instead of lossless. Rasterized content that keeps transparency stays lossless, because JPEG has no alpha channel. - Engine/Swift: Fixed cancelling a video export leaving the device encoding the whole video.
BlockApi.exportVideosuspended on the engine callback and ignored task cancellation, so dropping the returned stream reported the export as cancelled while the background export engine kept rendering and encoding every remaining frame, holding CPU, GPU and battery until it finished. Cancelling now stops the export and releases the background engine. - Camera/Android: Fixed the photo/video mode toggle ignoring taps in mixed capture mode. The selection indicator briefly moved to the tapped icon and then snapped back without switching the capture mode.
- Engine/Linux: Improved compatibility with H.265 video files in the licensed codec pipeline.
Version v1.80.0 Changelog August 13, 2026
Breaking Changes
- Engine/Android: The automatic default video bitrate now uses the shared resolution/framerate formula, typically producing smaller files for common 30/60 fps HD presets. To keep the previous behavior, pass an explicit bitrate matching the old formula, e.g.
ExportVideoOptions(videoBitrate = width * height * frameRate.toInt() / 4). - Renderer: The base system for the Renderer Docker container has been upgraded from Ubuntu 24.04 to Ubuntu 26.04 to include upstream security vulnerability fixes that were not backported to Ubuntu 24, if you are building a custom image layered on top of our image you might need to adjust your Dockerfile.
- Engine/Web: The default build-in
Space(play/pause) andS(split clip) key bindings were removed from the@cesdk/enginebuilt-in shortcut catalog. Thevideo.playPauseandselection.splitactions are unchanged and can still be bound viaengine.shortcuts.set().
Non Breaking Changes
- Engine: Audio blocks and video fills can now fade in and out. Use
setAudioFadeInandsetAudioFadeOut, or theplayback/fadeIn/*andplayback/fadeOut/*block properties. The easing defaults toLinearand a duration of 0 (the default) disables the fade. - Editor/iOS: The text on path sheet now uses the same two-step flow as the animations sheet. The sheet opens with the path selection list only, and the adjustment controls (path position, direction, and offset) moved to a detail page that opens by tapping the selected path again. The default detent of the sheet changed from medium to tiny to match the filter, effect, and blur sheets.
- Editor/Android: The text on path sheet now uses the same two-step flow as the animations sheet. The sheet opens with the path selection list only, and the adjustment controls (path position, direction, and offset) moved to a detail page that opens by tapping the selected path again.
- Engine: Text on a path now selects the text by default. Its selection frame, alignment and snapping follow the visible text bounds instead of the path’s bounding box; click the path to switch to path selection, click the text to switch back. Only corner handles show while text is selected, and hovering the other representation previews the frame a click would switch to.
- Engine:
getScreenSpaceBoundingBoxXYWHreturns the visible glyph bounds for a selected text-on-path block in text mode; unchanged for unselected blocks and for path selection. - Engine: The clickable area of text on a path is now one continuous band matching the drawn glyphs, fixing flickering hover and clicks landing in the curve’s empty interior.
- Engine: Uniformly scaling text on a path no longer makes the letters wiggle or slide along the curve.
- Engine: Corner-resizing any block with snap-to-grid active no longer lets the anchor corner drift by a sub-pixel amount.
- Engine: Scenes and archives now share one
.imglyfile format. The newloadAPI opens any scene or archive file — including existing.sceneand.zipfiles. The previous load methods keep working too. - Editor/Web: A single “Import” option replaces “Import Design” and “Import Archive”. Scenes and archives saved from the editor now download as
.imglyfiles. - Engine/Android: Fixed a native memory leak that leaked the full payload of every
ByteBufferthe engine returned to Kotlin. This affectedBlockApi.export,exportWithColorMask,exportVideoandsaveToArchive,SceneApi.saveToArchive,EditorApi.getResourceData(once per chunk) and the buffer APIs. The leaked memory was native heap, so it counted against the app’s memory budget but stayed invisible to the Java heap profiler. Returned buffers are now reclaimed by the garbage collector. - Engine/Android: Fixed a leak where every export left behind a live
HandlerThread, along with roughly 4.6 MiB of native heap that was only reclaimed once that thread exited. This affectedBlockApi.export,exportWithColorMaskandexportVideo. Apps that exported repeatedly, such as batch or preview flows, accumulated one thread per export until the process was killed. - Editor/Android:
LibraryContent.Sections withaddGroupedSubSectionswhose asset source reports no groups now fall back to a single flat section instead of rendering an empty section - Editor/Android: categories consisting of a single
LibraryContent.SectionwithaddGroupedSubSectionsnow render their grouped subsections instead of auto-expanding into a flat grid of the section’sexpandContent - Editor/Android: the header count of a
LibraryContent.SectionwithaddGroupedSubSectionsnow shows the total across all groups instead of the count of a single group - Editor/Android: Fixed a crash (
IndexOutOfBoundsException) that could occur while editing text. - Engine: Text selection and cursor positions are now clamped to the current text.
- Editor/Web: Fixed crop mode overwriting a user-configured
page/allowResizeInteractionsetting. The value is now restored to its previous state when leaving crop mode instead of always being forced tofalse. - Engine: Fixed
getDominantColors. This function no longer counts as an export event. - Editor/Flutter: Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.
- Editor/Web: Fixed the Animations section missing for groups in the advanced video editor. Selecting a group now shows its animation controls in the inspector panel, matching the standard video editor.
- Engine/Web: Added the missing
Mod+Ccopy andMod+Xcut default keyboard shortcuts and registered headlesscopy,cut, andpasteactions; the split shortcut is nowsinstead ofMod+X. - Engine: Fixed undo/redo restoring a stale camera position when the restored history snapshot.
- Engine: Fixed image blocks that showed the preview image instead of the current image when the block is small on screen. The preview image is now only shown while the current image loads.
- Editor/Web: Fixed an issue where the inspector panel was switching to text properties while a page title is being edited.
- Editor/iOS: Fixed the export “cancel” confirmation dialog appearing in inconsistent positions during video export. It now anchors consistently to the progress sheet’s dismiss button.
- Engine: Fixed a hang when disposing the engine while network requests were still in flight on Apple platforms.
- Engine: Fixed page thumbnails (for example in the editor’s page overview) appearing vertically stretched.
- Engine: Fixed PDF export silently returning a corrupted file instead of an error when the device runs out of memory while finalizing the document.
- Plugins/Web: Fixed PDF/X-4 output from
@imgly/plugin-print-ready-pdfs-webfailing preflight metadata checks. Document info and XMP metadata now carry identical creation/modification dates, creator, producer, and title; values inherited from the input PDF no longer override them; non-ASCII titles are written correctly; and the XMP metadata stream is no longer compressed. - Engine/Web: Fixed a crash when saving a scene to an archive that references a font which is not currently loaded, for example an unused typeface variant.
- Engine: Fixed right-to-left text overflowing the right edge of a fixed text frame for wrapped lines.
- Editor/Web: Opening a color picker no longer freezes on scenes with many images. The image colors palette now shows the images on the current page, reuses previous results, and refreshes them after document edits.
- Engine: The
videoBitratevideo export option now accepts two named modes in addition to an explicit number:'System'(default — Web and iOS defer to the platform encoder; Android and GStreamer use the shared formula) and'Auto'(a bounded default derived from the output resolution and framerate, e.g. 5 Mbps at 720p30, 8 Mbps at 1080p30, 40 Mbps at 4K30). On iOS useVideoBitrate.auto, on AndroidVideoBitrate.Auto. - Engine/Web: Pass
videoBitrate: 'Auto'to avoid video exports freezing with an out-of-memory error caused by the browser choosing a near-lossless bitrate (Safari reached ~300 Mbps). - Engine/Android: The automatic default video bitrate now uses the shared resolution/framerate formula, producing smaller default files than before.
- Plugins/Web: AI Gateway failures now show a localized, human-readable message instead of the raw HTTP status and JSON response body. Running out of credits, an expired token, a model that is not on your plan, a temporary outage, and an unreachable gateway each get their own message.
- Plugins/Web: A request that never reaches the AI Gateway — the browser is offline, the gateway is unreachable, or the response was blocked for missing CORS headers — now asks the user to check their connection instead of reporting a failed generation. It is thrown as a
GatewayErrorwithcode: 'network_error'. - Plugins/Web: A generation failure the gateway reports inside an open stream now uses the reason the gateway sent, so a rejected prompt or a provider rate limit no longer claims the AI service is temporarily unavailable.
- Plugins/Web: Fixed AI quick actions failing silently. A failed generation stopped the spinner without telling the user anything; it now shows the same error notification as the generation panel.
- Plugins/Web: Added
GatewayErrorandisGatewayErrorexports to@imgly/plugin-ai-generation-web. Gateway failures are thrown as aGatewayErrorcarryingcode,status,operation, andrequestId, so an error-handling middleware can branch on the failure reason — for example to show a “Manage credits” action forinsufficient_credits. - Plugins/Web: Fixed the
durationoption on a provider’soutput.notification.errorbeing ignored. - Editor/Web: Fixed missing German translations for the DPI and page settings labels, which previously fell back to English.
- Engine: Fixed a native crash that could occur when audio waveform generation reached the end of the audio file.
- Engine: Exporting a rotated block with
allowTextOverhangno longer crops the result. - Editor/Web: Fixed an issue where the typeface library panel did not populate
queryData.querywhen querying asset sources, so custom asset sources implementing search viaqueryData.queryreceived an empty string. The panel no longer adds alabelfilter predicate on top of the query, so each source’s own search matching fully decides the results. - Engine: Picking another text curve while the text baseline is open in vector edit mode no longer leaves the previous curve’s anchor handles and outline on the canvas. The edit session now re-reads the new baseline path instead of keeping the stale one.
- Engine: Text that exceeds the length of its path remains selectable by clicking its visible glyphs.
- Engine: Resizing a selected text path with its corner handles now preserves the path’s aspect ratio.
- Engine: Text on a path whose offset makes it wrap around the end of the curve is now selectable on both sides of the wrap, and its selection frame covers all of its glyphs.
- Engine: Exporting a text block that sits on a curve no longer crops the glyphs that reach outside of the curve. The exported area now covers all of the rendered text instead of just the curve.
- Editor/iOS: Fixed the video timeline occasionally freezing and losing one of the split halves when splitting a clip on the background track.
- Editor/iOS: Fixed the voiceover recording panel sometimes opening with its top edge clipped.
- Engine: Fixed undo/redo of a page addition or removal changing the canvas zoom.
Version v1.79.0 Changelog July 28, 2026
Breaking Changes
- Engine/Swift, Editor/iOS, Camera/iOS: Packages for Apple platforms are now built with Xcode 26.4.1 and Swift 6.3.1, which are the new minimum requirements for using them.
Non Breaking Changes
-
Editor/Web: Added the following new keyboard shortcuts:
F6/Shift+F6— cycle focus forward / backward through the main editor regions (canvas, inspector bar, canvas menu).Alt+1/Alt+2/Alt+3— move focus directly to the canvas, the inspector bar, or the canvas menu.Escape— dismiss the tooltip that is currently shown.
-
Engine: Added asset source faceting.
findAssetsaccepts afacetsrequest (property pathsgroups,tags, ormeta.<key>) and returns value distributions with counts over the matched set. Local asset sources compute these automatically; custom sources can return them from theirfindAssetscallback. -
Engine/Android: Added the structured
filterandfacetsparameters to asset queries and facet distributions on query results. -
Engine/Swift: Added the structured
filterandfacetsparameters to asset queries and facet distributions on query results. -
Editor/Web: The typeface library’s language filter now derives its options from typeface
meta.languagesvia asset facets, instead ofgroups. -
Editor/Web: Added the UI for clip-to-clip transitions. Add one between two adjacent clips on the timeline, choose a type from the library (cross fade, cross blur, wipe, push, slide, and more), tune its settings with a live canvas preview, and apply or remove transitions across a whole track at once.
-
Engine: Added clip-to-clip transitions — a new API (
createTransition,setTransition,removeTransition,getTransition,supportsTransition), exposed in the Web, Android, iOS, and Node.js bindings, with a catalog of transition types (none,cross-fade,cross-blur,cross-spin,cross-zoom,cross-warp,push,slide,stack,splice,diagonal-splice,fade,fade-to-white,fade-to-black,wipe,line-wipe,clock-wipe,color-wipe,gradient-fade,chop,two-stripes). Transitions overlap adjacent clips with a clamped duration, cross-fade audio automatically, and expose editable properties (duration, direction, color, slices, and amorphflag) via generic block setters; when morph is enabled, position, rotation, scale, and shape are interpolated between the outgoing and incoming clip. -
Editor/Web: Added keyboard shortcuts that mirror pointer/drag gestures on the canvas and the video timeline, so both can be driven from the keyboard for accessibility.
- Canvas transforms (selected block): nudge the crop area with the arrow keys, rotate with
Alt+arrows, and resize withMod+arrows (orMod+Alt+arrows to resize from the opposite edge). HoldShiftfor a larger step. - Video timeline (selected clip): move a clip earlier/later with the arrow keys, insert it into a gap while pushing later clips with
Mod+arrows, move it to the track above/below or to a new track withMod(+Shift)+ArrowUp/ArrowDown, and trim its in/out points withAlt(+Shift)+arrows. HoldShiftfor a larger step. - Playhead: skim frame-by-frame with
,/., jump further withShift+,/Shift+., and jump to the start/end withHome/End.
See the Keyboard shortcuts guide for the full list.
- Canvas transforms (selected block): nudge the crop area with the arrow keys, rotate with
-
Engine: Added the
text/useContextualAlternatesandcaption/useContextualAlternatesboolean properties to enable or disable the OpenType contextual alternates (calt) feature during text shaping. Contextual alternates remain enabled by default. Disabling them keeps a font’s context-dependent glyph substitutions (such as the connectedtswashes in Caveat) from being applied, so identical characters render with identical glyphs. -
Editor/Android: The asset library now refreshes automatically when a source’s contents change via
engine.asset.assetSourceContentsChanged(sourceId=_). Any open library showing that source re-queries and updates in place. -
Editor/Web: Fixed the Bold/Italic and Underline/Strikethrough toggles being unresponsive on caption blocks in the video editor. These controls now apply to the selected caption, matching their behavior for text blocks. The inspector bar’s font weight/style dropdown is now also available for captions.
-
Editor/Flutter: Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.
-
Editor/iOS: The “Could not create View for …” error messages shown when the Dock, Canvas Menu, Inspector Bar, Navigation Bar, or an editor component fails to build are now localizable (and ship with German translations), matching the rest of the editor UI. Previously they were hardcoded in English.
-
Editor/iOS: Fixed the sheet dismiss button rendering a doubled circle under iOS 26 Liquid Glass.
-
Engine/Node:
@cesdk/nodeno longer probes the browserlocalStorageglobal during initialization on Node.js. On Node 22.4+ the experimental Web Storage global is a getter thattypeofevaluates, which printed anExperimentalWarning(Node 22.x) or threwERR_INVALID_ARG_VALUE(Node 23+/24) when--localstorage-filewas not provided. Headless Node has no browser Web Storage, so the engine now short-circuits this feature detection there. Browser detection is unchanged. -
Editor/Web: Fixed the “Resize Page” panel rendering completely empty when no page preset sources are configured. The page size inputs are now always shown and only the preset library section is omitted.
-
Engine: Rendering a block with a broken fill, effect, or frame reference (e.g. from a corrupt scene file) now flags the block with an error state instead of crashing the render loop.
-
Engine: Loading blocks or templates whose serialization contains references to missing elements now removes those references and flags the affected blocks with an error state, instead of leaving the references pointing at unrelated blocks, which could corrupt rendering.
-
Engine: Added the block error code
BROKEN_BLOCK_REFERENCE, reported when a broken block reference is removed on load or encountered during rendering. -
Editor: Fixed snapping guides appearing for hidden blocks and pages.
-
Engine: Fixed a crash when rendering text whose font resource had been evicted under memory pressure, e.g. while generating page thumbnails for the page overview. Text now falls back to the default font while the evicted font reloads and switches back automatically once it is ready.
-
Editor/Web: Fixed timeline duration formatting to zero-pad single-digit minutes when hours are present (e.g.
2:01:51.7instead of2:1:51.7). -
Editor/Web: Fixed the typeface library panel collapsing an expanded typeface’s variants when a search was typed just before expanding it. Search mode now activates as you type instead of after the debounced query settles, so the list is no longer torn down under an in-progress interaction.
-
Engine: Loading a video whose codec is not supported (e.g. AV1 video or Opus audio in an MP4) now fails with a clear, actionable error naming the actual codec fourcc and the supported codecs to re-encode to, instead of a generic “OTI=0” message. The failure is surfaced as a distinct
VIDEO_CODEC_UNSUPPORTED/AUDIO_CODEC_UNSUPPORTEDerror code so it can be distinguished from a generic decode failure. -
Editor/Web: Fixed video clip thumbnails in the timeline sometimes not updating after replacing a video, and sometimes staying stuck on the loading indicator.
-
Engine: Per-character and per-word text animations that fade each glyph (Pan, Fade, Blur, Zoom, …) now play back smoothly on large text blocks, including curved text
-
Engine: Underlines and strikethroughs now animate together with the text during per-character and per-word in and out animations, instead of only appearing once the animation finishes
-
Editor/Web: Fixed published starter kit repositories shipping the editor configuration in a root-level folder outside
src/imgly. Thesrc/imglyfolder is now self-contained across all starter kits, so copying it into a project yields a complete, working integration as documented. -
Engine: Fixed a crash (
tried to use the Error of an object with a Result) when a video decoder reported an error, e.g. exporting a scene with an H.264 High 4:4:4 10-bit (yuv444p10le) video on the server-side renderer. Such exports now fail with a properVIDEO_DECODING_UNSUPPORTEDerror. -
Engine/Android: Fixed a crash when the text block being edited was destroyed, e.g. when exiting text editing with empty text.
-
Editor/iOS: Fixed sheet dismiss and close buttons sometimes requiring multiple taps to close on iOS 26.
-
Editor/Web: Fixed audio continuing to play when selecting another block while previewing a trim in the inspector bar.
-
Editor/Web: Fixed a crash (“Maximum update depth exceeded”) when selecting another block while the trim panel was open in the Advanced editor.
-
Editor/Android: Fixed timeline trimming setting clip durations slightly short of the dragged length, e.g. 4.9s instead of 5.0s.
-
Editor/Android: Fixed a crash (
UnsupportedOperationException) when a design block type that the editor UI does not support yet gets selected, for example a caption in a scene authored with the web editor. Such blocks stay selectable on the canvas, and the canvas menu and inspector bar now stay hidden for them instead of crashing the editor.
Version v1.78.0 Changelog July 17, 2026
Breaking Changes
Non Breaking Changes
- Editor: Engine error dialogs across Web, iOS, Android, Flutter, and React Native now show customer-facing, localizable copy keyed off the structured engine error
code, falling back to the engine’s English message when no copy is authored — so a dialog never shows a blank or a raw code. You can override this copy per error code and resolve it yourself in custom error handlers. See the Custom Error Messages guide for authoring copy and the Error Catalog for the full list of structured error codes. - Editor/iOS:
EngineSettings(baseURL:)now accepts an optionalURLand falls back to the default CE.SDK CDN whennil, so you can pass an optional base URL directly without branching. - Editor/Web: The color picker for line shapes now supports gradients.
- Engine: Movement constraints now keep text on the page by its visible letters, not just its text box, so letters that stick out past the box no longer spill off the page when moving or resizing. On by default; toggle it with the
features/movementConstraintsRespectTextOverhangsetting. - Editor/Web: Added a Path control for text blocks to place text on a curve (Circle, Arch, Wave) with adjustable position, direction and offset, plus Edit Path for a custom baseline. Gated by the new
ly.img.text.pathfeature (with per-control sub-features). - Plugins/Web: The AI generation “Generate” button now stays disabled until every required input is provided. Previously, filling a single required input (e.g. the prompt) enabled it even when another required input (e.g. an image) was still missing, which could trigger a failed generation request.
- Engine/Android: Fixed a crash during export teardown when an engine event stream was collected after
Engine.stop(). - Engine: Fixed a crash (
RuntimeError: unreachable) inblock.saveToArchivewhen a text block referenced a font whose bytes were not yet resident (e.g. an unresolved remote font). - Engine: Fixed the editor freezing when importing large caption/subtitle (SRT/VTT) files or styling large caption tracks. Style changes now spread across a caption track in linear time instead of quadratic.
- Engine: Fixed corner-handle resizing of blocks whose width or height is sized as a percent of their parent (for example captions on the video canvas).
- Engine: Fixed content-aware resize emitting a degenerate “double-flip” transform (both scale axes negative combined with a multiple-of-2π rotation) for page-filling images. Such images now get a clean, axis-aligned transform, so cropping them after resizing no longer moves the crop frame off the canvas.
- Editor/Flutter: Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.
- Editor/iOS: The asset library now refreshes automatically when a source’s contents change via
engine.asset.assetSourceContentsChanged(sourceID:). Any open library showing that source re-queries and updates in place, matching the web editor. - Editor/iOS: Fixed the sheet title bar and close button overlapping the content of compact effect sheets (Filter, Effect, Blur, Animation) when the iOS 26 Liquid Glass design is enabled.
- Editor/Web: Keep the text being edited visible above the on-screen keyboard on mobile web. The canvas reserves the keyboard area and pans the camera to the text cursor.
- Engine/Node:
@cesdk/nodenow bundles the engine-level font-fallback files (fonts/) and emoji font (emoji/NotoColorEmoji.ttf) in the npm package, so default font fallback and emoji rendering work out of the box without reaching the IMG.LY CDN. The@cesdk/nodeself-hosting asset bundle (imgly-assets.zip) now also includes thefonts/andemoji/directories; previously they were missing, which broke the documented self-hosting path. - Engine/Web: Fixed video export freezing on Safari when the project contained an uploaded video. Safari treats OPFS read handles as exclusive per file, so the export worker could not read an upload the editor was already reading. OPFS is now disabled on Safari and uploads fall back to in-memory blob URLs.
- Engine: Fixed movement constraint capping block resizing too early. The cap now follows the block’s axis-aligned bounding box in page space, so resizing — including rotated blocks — can grow to the size the constraint actually permits.
- Engine: Fixed a crash when loading a scene or block archive whose fetched data is not a valid zip.
- Editor/Web: Fixed the shape options dropdown in the inspector bar not being keyboard accessible. Opening it now moves focus into the panel, keeps focus contained while navigating its controls, restores focus to the trigger on close, and dismisses on Escape.
- Editor/Web: Fixed snapping guides ignoring movement constraints when moving or resizing.
- Engine: Fixed
setEditMode('Text')so thatsetTextCursorRangeand other text-cursor APIs work synchronously immediately after, without an intermediate engine update. - Engine/Web: Fixed an issue where the on-screen keyboard would not open on iOS when entering text edit mode programmatically inside a user gesture.
- Engine: A text block placed on a path now returns to automatic sizing when the path is removed, instead of staying at the fixed size adopted for the curve.
- Engine: A text block placed on a path now keeps a stable set of editable points when re-entering path editing, instead of re-subdividing the path each time.
- Engine: Fixed a video fill whose source failed to load (for example because of a CORS or network error) being re-fetched on every render frame with no limit. A failed video load now keeps its error state like image fills do; use
forceLoadResources/forceLoadAVResourceto explicitly retry it. - Editor/Web: The typeface library now fetches font previews lazily as rows scroll into view and renders typeface names immediately in a fallback font, keeping the font picker responsive on slow networks and low-end devices. The live per-font preview is preserved and arrives progressively.
- Engine: Fixed text on curved paths to respect paragraph-level horizontal alignment.
- Editor: Fixed caret placement for empty aligned text on curved paths.
- Editor: Fixed caret hit testing, pointer selection, and selection highlights for text on curved paths that wrap across the start or end of an open path.
- Editor: Fixed overlapping selection highlights on curved text from rendering darker where selection geometry intersects.
- Engine/Web:
@cesdk/engineagain publishes its default asset sources (ly.img.*) to the CDN, fixing asset resolution failures during initialization for custom-UI integrations that rely on the defaultbaseURL. - Engine/Web:
@cesdk/engineand@cesdk/cesdk-jsnow bundle the font-fallback and emoji files in their npm packages, so text and emoji render without reaching the IMG.LY CDN. - Engine/Node:
@cesdk/node’simgly-assets.zipnow includes the full asset content library (ly.img.*), so self-hosting the default asset sources works. Previously it shipped only the engine core, fonts, and emoji. - Engine: Fixed text on a curve ignoring the automatic horizontal text alignment. Right-to-left text with
Autoalignment now aligns to the end of the path, matching regular text frames. - Engine: Fixed underline and strikethrough lines on text on a curve bridging the gap between the end and the beginning of the text when a path offset wraps the text around the path.
- Engine: Fixed the text cursor of right-aligned text on a curve sometimes jumping to the start of the path when placed at the end of the text.
- Editor/Web: Fixed the text “Styles” button staying active in Preview for placeholders that do not allow character changes. It is now hidden when the
text/characterscope is disallowed, matching the other style controls. - Editor/Web: Fixed the show/hide toggle in a line’s color panel. It now hides and shows the line, for solid colors and gradients alike, instead of doing nothing or dismissing the gradient.
- Engine: Fixed a hidden line becoming visible again after the scene was saved and reloaded.
- Engine: Fixed a hidden line with a gradient rendering a stray triangle instead of nothing.
- Editor/Android: Fixed the resize sheet unexpectedly closing when selecting a page size preset.
- Engine: Fixed
onActiveChangednot being triggered when loading the same scene or applying the same template twice in a row. - Engine/Web: Fixed a crash when saving a scene to an archive that references a font which was never loaded (for example an unused typeface variant). Such resources are now left as external references instead of being bundled.
Version v1.77.1 Changelog July 9, 2026
Breaking Changes
Non Breaking Changes
- Engine/Web:
@cesdk/engineagain publishes its default asset sources (ly.img.*) to the CDN, fixing asset resolution failures during initialization for custom-UI integrations that rely on the defaultbaseURL. - Engine/Web:
@cesdk/engineand@cesdk/cesdk-jsnow bundle the font-fallback and emoji files in their npm packages, so text and emoji render without reaching the IMG.LY CDN. - Engine/Node:
@cesdk/node’simgly-assets.zipnow includes the full asset content library (ly.img.*), so self-hosting the default asset sources works. Previously it shipped only the engine core, fonts, and emoji. - Engine: Improved performance when
transparentClickThroughEnabledis enabled
Version v1.77.0 Changelog July 2, 2026
Breaking Changes
Node.js Support
- Engine/Node: Raised the minimum supported Node.js version to 22. Node.js 20 no longer receives security updates as of May 2026, we strongly recommend updating to a supported version.
Asset Sources & Registration
- Engine (Swift + Android): Several built-in asset source IDs were renamed or merged — update any hardcoded IDs:
ly.img.vectorpath→ly.img.vector.shape,ly.img.colors.defaultPalette→ly.img.color.palette, andly.img.filter.lut+ly.img.filter.duotone→ly.img.filter(one source for both LUT and duotone). BecauseaddDefaultAssetSources/addDemoAssetSourcesstill iterate the old IDs, the four renamed/merged IDs are skipped silently against the default asset base URL — shapes, the default palette, and filters go missing until you re-register with the new IDs viaaddLocalAssetSourceFromJSON(Swift) /addLocalSourceFromJSON(Android). The default starter kits now also registerly.img.text,ly.img.text.styles,ly.img.text.curves, andly.img.text.components. - Editor/iOS: Filter selection now uses a single
ly.img.filtersource covering both LUT and duotone effects, detected at runtime via asset metadata. Shape and sticker group identifiers are simplified (e.g."filled"instead of"//ly.img.cesdk.vectorpaths/category/filled"); update any hardcoded group identifiers. - Editor/Android: Filter selection now uses a single
ly.img.filtersource covering both LUT and duotone effects, detected at runtime via asset metadata. - Editor/iOS + Android: Starter kits now register
ly.img.text(basic text presets) andly.img.caption.presets(caption styles) alongside the existing default sources. - Editor/Flutter + React Native: The default
baseUrinow resolves to the updated asset content. If you self-host, copy theassets/directory fromhttps://cdn.img.ly/packages/imgly/cesdk-<flutter|react-native>/<version>/imgly-assets.zipand pointbaseUriat your hosted location. - Migration guide: Migrating to v1.77 (iOS, Android) covers the full old → new asset source ID mapping and how to register sources. For Web, the Migrating to v1.77 guide covers the corresponding text source changes.
Camera & Capture Modes
- Camera/Android: Added photo and mixed (photo + video) capture modes.
CameraConfigurationgainscaptureType(Photo/Video/Mixed),captureCount(Single/Multi),photoClipDuration, andshowsPhotoPreview; results now arrive asCameraResult.Captures(List<Capture>)(withCapture.Photo(uri, clipDuration)/Capture.Video(recording)) via a newCaptureMediaActivityResultContract.CaptureVideo/CaptureVideo.Inputare renamed toCaptureMedia/CaptureMedia.Input(old names@Deprecated(level = ERROR)) andCameraResult.Record([Recording])is@Deprecated(level = ERROR)— extract recordings with the newList<Capture>.videosextension, and swap theis CameraResult.Record ->arm foris CameraResult.Captures ->in exhaustivewhens. - Camera/iOS: Added photo and mixed capture modes via
captureType(.photo/.video/.mixed) andcaptureCount(.single/.multi); captures arrive as a newCaptureenum (.photo(Photo)/.video(Recording)) throughCameraResult.capture([Capture]), and dual-camera mode now captures both cameras (Photo.imagescarries one or two images).CameraResult.recording([Recording])is now@available(*, unavailable, renamed: "capture")— extract recordings with the new[Capture].videosextension and swap the.recordingarm for.capturein exhaustive switches. (The deprecatedResult<[Recording], CameraError>callback initializer is unaffected.) - Camera/ReactNative: The bridge no longer emits
CameraRecordingResult— pure-video sessions return aCameraCaptureResultwithcaptures: Capture[], andPhotochanged from{ uri, duration }to{ images: PhotoImage[], duration }. Replaceresult.recordings.forEach(...)withresult.captures.forEach(...)switching on eachCapture’sphoto/videofield; replacephoto.uriwithphoto.images[0].uri. - Camera/Flutter: The bridge no longer emits
CameraRecording— pure-video sessions return aCameraResultwith a populatedcapture: CameraCapture, andPhotochanged from{ uri, duration }to{ images: List<PhotoImage>, duration }(with a typedRect). Readresult.capture?.capturesand pattern-match eachCapture’sphoto/videofield. - Editor/Android: The IMG.LY camera dock now launches in
Mixed/Multifrom a video editor (captured photos become timeline image-fill blocks using each photo’sclipDuration) and inPhoto/Singlefrom a non-timeline editor (design, photo, apparel, postcard). The design starter-kit dock button now opens the IMG.LY camera (Dock.Button.rememberImglyCamera()) instead of the system camera. - Editor/iOS: When opened from a video editor the camera launches in
.mixed/.multi(captured photos become timeline image-fill blocks whose duration matchesCameraConfiguration.photoClipDuration, 5 seconds by default; dual-camera photos lay out as a PIP); in non-timeline editors it launches in.photo/.single. The design starter-kit dock now usesDock.Buttons.imglyCamera()instead of the systemUIImagePickerControllerflow.
Background Removal
- Editor/iOS:
BackgroundRemovalPluginnow takes aBackgroundRemovalConfigurationand defaults to the IMG.LY IS-Net backend (VisionBackgroundRemovalConfigurationrestores the previous Apple Vision behavior). TheOptionsstruct is removed, and the package ships as four library products so unneeded targets can be excluded. - Editor/Android:
ly.img:plugin-background-removalis now the base package; add a concrete implementation (ly.img:plugin-background-removal-imglyorly.img:plugin-background-removal-google).Dock.Button.rememberBackgroundRemovalnow requires aconfigparameter, anddockModifierreceivesBackgroundRemovalConfig.
Error Handling
- Engine: Error message wording was standardized across the SDK. If you branch on error message substrings (e.g.
error.message.includes(…)), switch to the stableerror.code— existing substring matches may no longer match. See the Error Catalog for the full list of structured error codes. - Engine: Calling
addAsset,removeAsset, orapplyAssetPropertyon a custom asset source that does not implement the operation now throws an error carrying the matchingBINDING.ASSET_SOURCE_ADD_UNSUPPORTED,BINDING.ASSET_SOURCE_REMOVE_UNSUPPORTED, orBINDING.ASSET_SOURCE_APPLY_PROPERTIES_UNSUPPORTEDcode — previouslyaddAsset/removeAssetsilently did nothing andapplyAssetPropertynever completed. Implement the operation or catch the error if you are probing for support.
Keyboard Shortcuts
- Editor/Web: Keyboard shortcuts are now a public, customizable registry via
cesdk.shortcuts, and the listener binds to the editor container instead of thedocument— shortcuts only fire when focus is inside the editor. Restore page-wide behavior withcesdk.shortcuts.setRoot(...), or disable the layer withcesdk.shortcuts.setEnabled(false). The registry exposesset,get,list,remove,has,clear,setEnabled,addScope, andsetRoot; each shortcut is an object withkeys(a chord like'Mod+z'or a sequence array),run(an action id or a function),scope, and optionalwhen,description,category, andsequenceTimeout. See the Migrating to v1.77 guide for details. - Engine/Web: The same keyboard-shortcut registry is available on the engine layer at
engine.shortcuts, so any@cesdk/engineintegration gets shortcuts without the editor UI (same methods).
Editor Configuration
- Editor/Android: Editor configuration composition was fixed so component lambdas that explicitly return
nulloverride parent components instead of falling back to them.
Deprecations
All items below remain functional this release; migrate before they are removed.
- Engine (Swift + Android): The asset-source helper layer —
DefaultAssetSource,DemoAssetSource,populateAssetSource(...),addDefaultAssetSources(...),addDemoAssetSources(...)— is deprecated. Register sources directly viaaddLocalAssetSourceFromJSON(Swift) /addLocalSourceFromJSON(Android) pointing at each source’scontent.json. - Engine (Swift + Android): Asset-source URL constants (
Engine.assetBaseURL/Engine.Companion.assetBaseUri) are deprecated and will be removed in a future version. Build your ownbaseURLfrom bundled assets — for exampleBundle.main.url(forResource: "IMGLYAssets", withExtension: "bundle")on iOS. The IMG.LY CDN is for development and evaluation only; self-host for production. - Editor/Android:
AppearanceAssetSourceType.LutFilterandDuoToneFilterstill resolve but are deprecated — migrate toAppearanceAssetSourceType.Filter. - Editor/iOS:
TextAssetSourceis deprecated. The default text library now uses the split text sources (ly.img.text,ly.img.text.styles,ly.img.text.curves,ly.img.text.components); register and use those instead. - Editor/Android:
TextAssetSourceandAssetSourceType.Textare deprecated. Use the split text sources (AssetSourceType.TextPlain,TextStyles,TextCurves,TextComponents) instead. - Engine: The control-gizmo flags
showMoveHandles,dynamicMoveHandleVisibility,showResizeHandles,showScaleHandles, andshowRotateHandlesare deprecated (still functional) — use the newcontrolGizmo/*HandleVisibilitysettings instead. - Plugins/Web:
convertToPDFX3is now a deprecated alias ofconvertToPDFX.
New Features
AI Image Generation
- Editor/Android: Added the
AIImageGenerationPluginplugin that provides image generation features using AI. - Editor/iOS: Added AI Image Generation plugin (
IMGLYPluginAIImageGeneration)
Text on a Path (Curved Text)
- Engine: Added text-on-curve support. Six new public API methods (
setTextOnPath,getTextOnPath,setTextOnPathOffset,getTextOnPathOffset,setTextOnPathFlipped,getTextOnPathFlipped) let text blocks follow a validated SVG baseline path. Three new properties (text/pathOffset,text/pathFlipped,text/pathExternalRef) control proportional path offset, flipped placement, and the active curve asset reference. The existing vertical alignment (text/verticalAlignment) controls the text’s vertical orientation relative to the curve:Topplaces the bottom of the glyphs on the curve (text above it),Centercenters the glyphs on the curve, andBottomplaces the top of the glyphs on the curve (text below it). - Engine/Web/Android/iOS: The new text-on-path API methods are available on all platforms, e.g.
engine.block.setTextOnPath,engine.block.getTextOnPath. - Engine: Style presets can now place text on a curve. The baseline path lives in the preset’s flat
propertiesmap like any other key:text/path(a virtual property routed throughsetTextOnPath, inheriting its SVG validation and path-bounds sizing; an explicitnullclears the path) alongside the reflectedtext/pathOffsetandtext/pathFlippedproperties. - Engine: Added the Circle, Arch, Wave, and Elevate curve presets to the
ly.img.text.curvesasset source, applied like any other style preset. - Editor/Web: Text-on-curve presets appear as the Curved Text section of the Text library, backed by the
ly.img.text.curvesasset source. - Editor/Android: Added a UI for placing text on a path. The new inspector bar button
InspectorBar.Button.rememberTextOnPath(...)— included in the default inspector bar for text blocks — opens the new sheetSheetType.TextOnPath(style)with a grid of preset curves backed by thely.img.text.curvesasset source, plus path position, direction, and offset controls. - Editor/iOS: Added a UI for placing text on a path. The new inspector bar button
InspectorBar.Buttons.textOnPath(...)— included in the default inspector bar for text blocks — opens the new sheetSheetType.textOnPath(style:)with a grid of preset curves backed by thely.img.text.curvesasset source, plus path position, direction, and offset controls.
Text Presets & Library
- Editor/Web: Reworked the built-in text presets into reusable style presets that apply a complete look (font, color, outline, background, shadow, and animations) in a single step. The default Text library (
ly.img.text) groups them into sections — Plain Text (Default / Elegant / Modern Tech themes), Text Styles (outline, glow, neon, …), Text Combinations (pre-designed text layouts), and Curved Text (text-on-path) — backed by thely.img.text,ly.img.text.styles,ly.img.text.components, andly.img.text.curvesasset sources. TheTextAssetSourceandTextComponentAssetSourceplugins wire all of these into the singlely.img.textentry. The text “Styles” inspector button restyles a block from the same library minus Text Combinations (text designs create new blocks and aren’t valid restyle targets). - Editor/Web:
cesdk.ui.setReplaceAssetLibraryEntriesnow accepts{ entry, excludeSourceIds }objects alongside plain entry IDs, letting you hide specific asset sources from a replacement panel without affecting how that entry behaves on insert. - Editor/Web: Added new caption style presets. The
CaptionPresetsAssetSourceplugin provides them through thely.img.caption.presetsasset source and applies them via the engine’s declarative style-preset mechanism, so captions and text now share the same one-step styling. - Editor/Android: Added
InspectorBar.Button.rememberTextPresets()— a “Presets” inspector-bar button for text blocks that opens a restyle picker offering Plain Text, Text Styles, and Curved Text presets; tapping one restyles the selected block in place via the engine’s style-preset apply path. The button appears once any of thely.img.text,ly.img.text.styles, orly.img.text.curvessources is registered. - Editor/Android: The default asset library “Text” tab now offers four sections — Plain Text, Text Styles, Text Combinations, and Curved Text — each backed by its own asset source (
ly.img.text,ly.img.text.styles,ly.img.text.components,ly.img.text.curves). Plain Text drills into its Default, Elegant, and Modern Tech themes. Tapping a preset creates a pre-styled text block. In the Elements tab these appear as a single “Text” group whose preview mixes all of the text sources. Custom asset libraries can compose these sections viaLibraryContent.Section. - Editor/Android: Added
LibraryContent.Section.groupTitleKeyPrefix— sections expanded from asset groups can derive each group section’s title from a localization key (<prefix><group>), falling back to a humanized group name. - Editor/iOS: Added
InspectorBar.Buttons.textPresets()— a “Presets” inspector-bar button for text blocks that opens a restyle picker offering Plain Text, Text Styles, and Curved Text presets; tapping one restyles the selected block in place via the engine’s style-preset apply path. The button appears once thely.img.text.stylessource is registered. - Editor/iOS: The default asset library “Text” tab now offers four sections — Plain Text, Text Styles, Text Combinations, and Curved Text — each backed by its own asset source (
ly.img.text,ly.img.text.styles,ly.img.text.components,ly.img.text.curves). Plain Text drills into its Default, Elegant, and Modern Tech themes. Tapping a preset creates a pre-styled text block. In the Elements tab these appear as a single “Text” group whose preview mixes all of the text sources. Custom asset libraries can compose these sections viaAssetLibrarySection.
Typeface Library & Language Groups
- Editor/Web: Introduced a new typeface library panel (browse every source, search, filter by language/source) replacing the fonts dropdown.
- Editor/Android + iOS: Every typeface in the
ly.img.typefacesource now declares the language groups it covers (for examplelatin,cyrillic,greek,hebrew) via the assetgroupsfield — query them withengine.asset.getGroups(sourceId)(Android) /getGroups(sourceID:)(iOS) or narrow font queries with group-filteredfindAssets. The umbrella version in every source’scontent.jsonmoves to7.0.0; no sources are added, renamed, or removed and no source IDs change, so no registration changes are required. If you self-host, copy theassets/directory from the platform’simgly-assets.zip. - Editor/Flutter + React Native: Typefaces in the default asset content now declare the language groups they cover via the asset
groupsfield. No source IDs change. - Engine/Web: The default asset source now tags every built-in typeface with language groups so the typeface library can filter the fonts by language.
Text Formatting UI
- Editor/Android + iOS: Added a text formatting UI that stays anchored to the keyboard while the IME is open.
Text Runs API
- Engine (Web / Android / Swift): Added
getTextRunsreturning an ordered list of per-runTextRunInfo(color, font weight, font style, font size, text case, typeface, resolved font file URI, text decoration, and kerning):engine.block.getTextRuns(id, from, to)(Web),getTextRuns(block, from, to)→List<TextRunInfo>(Android), andgetTextRuns(_ id:, in subrange:)→[TextRunInfo](Swift).
Crop — Original Aspect Ratio
- Editor/iOS + Android: Added an “Original” crop preset to the crop sheet that reverts a block to the intrinsic aspect ratio of its image or video content.
- Engine (Swift + Android): Added
canRevertToOriginalRatio(BlockAPI.canRevertToOriginalRatio(_:)/BlockApi.canRevertToOriginalRatio(block)) to query whether a block can revert to the intrinsic aspect ratio of its image or video content.
Control Gizmo Handle Visibility
- Engine: New
controlGizmo/moveHandleVisibility,controlGizmo/resizeHandlesVisibility,controlGizmo/scaleHandlesVisibilityandcontrolGizmo/rotateHandlesVisibilitysettings ('auto' | 'always' | 'never', default'auto'). Use'always'to keep a handle visible while editing text, so a block can be moved, resized or rotated while typing. (These supersede the oldershow*Handlesflags — see Deprecations.)
Actions Registry
- Engine: Added
engine.actions, a registry of named editor commands — undo, redo, delete, duplicate, group, align, crop, text formatting, zoom, pan, and many more. Run one by id (engine.actions.run('undo')), change what a built-in does, or add your own. Clicks, double-clicks, wheel zoom, and right-click/long-press run through the same registry, so an override applies consistently across the editor. Available with@cesdk/engineand@cesdk/node; the register, override, and keyboard-rebinding APIs are not yet exposed on the iOS and Android bindings.
Structured Errors
- Engine/Web: Errors thrown by
CreativeEngineare nowEngineErrorinstances (extendingError) with a stablecode(e.g."SCENE.NOT_VALID") pluscategory,hint,args,docsUrl, andsilent. Existingtry/catchcode that readserror.messagekeeps working — new code can branch onerror.codeinstead of matching message strings. A typedEngineErrorCodeunion of all codes is exported from@cesdk/engine(and re-exported from@cesdk/cesdk-jstogether withEngineError/isEngineError) for compile-time-checked branching.error.codestays astring, so unknown or future codes never break consumers. See the Migrate to Structured Errors guide for how to move off message-string matching. - Engine/Swift: Thrown
NSErrors now carry the structured fields inuserInfo(EngineErrorCodeKey,EngineErrorCategoryKey, …);domainandcodeare unchanged. Thehintand docs URL surface through Foundation’s standard slots (localizedRecoverySuggestion/helpAnchor). Wrap an error withEngineError(error)to readcode,category,hint,args,docsURL, andsilent, then branch oncodeinstead oflocalizedDescription. Use theEngineErrorCodeenum toswitchon codes without bare strings. See the Migrate to Structured Errors guide for how to move off message-string matching. - Engine/Android:
EngineExceptionnow exposescode,category,hint,args,docsUrl, andsilent. Existing code that readse.messagekeeps working — new code can branch one.codeand surface the relevant docs page viae.docsUrl. Use theEngineErrorCodeconstants inly.img.engineto branch without bare strings. See the Migrate to Structured Errors guide for how to move off message-string matching. - Editor: Engine error dialogs across Web, iOS, Android, Flutter, and React Native now show customer-facing, localizable copy keyed off the structured engine error
code, falling back to the engine’s English message when no copy is authored — so a dialog never shows a blank or a raw code. You can override this copy per error code and resolve it yourself in custom error handlers. See the Custom Error Messages guide for authoring copy and the Error Catalog for the full list of structured error codes.
Node-Native Engine & ESM Build
- Engine/Node: New
@cesdk/node-nativepackage shipping a native N-API addon for macOS (arm64, x64) and Linux x64 (glibc ≥ 2.39). Drop-in replacement for@cesdk/node(WASM) with GPU rendering, real video/audio export, and no WebAssembly memory ceiling. Switch the import —import CreativeEngine from '@cesdk/node-native'— and the existing code keeps working. Windows, Alpine/musl, Linux arm64, and AWS Lambda are unsupported in this release; those workloads stay on@cesdk/node. Licensing requirements are unchanged from@cesdk/node— see the package README and https://img.ly/pricing for details. Nightly builds publish under the@devdist-tag for early validation. - Engine/Node: Ship a real ESM build alongside the existing CJS build.
importresolves to./build/index.mjsand exposesCreativeEngineas the default export plus all named exports (LogLevel, color helpers,MimeType, etc.);requirecontinues to return theCreativeEngineclass with named exports attached as properties. No source code changes are required for existing CJS consumers.
Print & PDF Output
- Plugins/Web: Added
convertToPDFXto@imgly/plugin-print-ready-pdfs-web. Supports both PDF/X-3 and PDF/X-4 viaoutputStandard, defaulting to PDF/X-4 so live transparency is preserved and vector text on transparent pages is no longer rasterized. (SupersedesconvertToPDFX3— see Deprecations.) - Engine/Renderer: Added support for underlayer settings, text overhang, and PDF device CMYK export options
Improvements & Behavior Changes
Typefaces & Font Library
- Editor/Web: Removed the font style/weight dropdown from the default text controls; weight and style are now set via the typeface library panel and the bold/italic toggles.
- Editor/Web: The typeface select tooltip now shows the selected typeface name.
- Engine:
ly.img.document-typefacesasset source stays in sync with the scene. Entries are removed once no text or caption block references the typeface anymore, andonAssetSourceUpdatedfires after every mutation.
Text Presets & Library
- Editor/Web: The default
ly.img.textlibrary keeps the source ID it has used since earlier versions, but its content changed from the basic Title / Headline / Paragraph entries to the new Plain Text style presets (per-asset IDs are now group-scoped, e.g.ly.img.text.default.title); thely.img.text.styles,ly.img.text.curves, andly.img.text.componentssources join the same entry. See the Migrating to v1.77 guide for details. - Editor/Web: Caption style presets now set the caption’s font size and frame, scaled to the page, so applying one sizes the caption consistently and the size scales with the page resolution.
Keyboard Shortcuts
- Engine: Keyboard shortcuts are no longer handled inside the engine. If you embed
@cesdk/enginewithout the CE.SDK editor UI and relied on the engine reacting to key presses (undo/redo, delete, arrow-key nudge, and so on), handle the key events yourself and dispatch the matching command throughengine.actions. Integrations that use the prebuilt CE.SDK editor are unaffected — on the web it maps keys to actions for you.
Performance
- Engine: Added viewport-aware page culling for multi-page scenes. Only visible pages are processed each frame, dramatically improving performance for photobook-style scenes with 100+ pages. Controlled via
features/viewportCullingEnabledsetting (enabled by default). - Editor/Android: Improved pages mode performance for large scenes. Page thumbnails are now rendered sequentially with an in-memory cache, so re-entering pages mode displays thumbnails instantly.
Bug Fixes
Engine
- Fixed a data race in the audio time-stretcher that could crash playback when scrubbing or splitting a video clip at a playback speed other than 1.
- Fixed line shapes losing their gradient or image fill and turning solid black. Lines now render gradient, image, and video fills correctly.
- Fixed movement constraint clamping for rotated blocks. The constraint now follows the block’s axis-aligned bounding box in page space, so rotating a block no longer lets its visible bounds drift past the page edge along its long axis.
- Fixed PDF exports with
exportPdfWithDeviceCMYKlosing spot color names. Spot colors now keep their name in the exported PDF, so print shops can match them to the correct ink. - Fixed system font fallback for characters not covered by the assigned typeface on Node and Node-Native. The hosted fallback fonts are now resolved from the IMG.LY CDN when a local
baseURL/basePathis configured (as on Node), instead of from a local path where they are not available — so unsupported characters render the same as in the browser. A remotebaseURL(e.g. a self-hosted CDN mirror) is still used as-is. - Fixed lines disappearing when combined with another element through a boolean operation. A line now contributes its visible (stroked) footprint to the combined shape, and a result that takes its color from a line now uses the line’s color.
- Fixed a video fill whose source failed to load (for example because of a CORS or network error) being re-fetched on every render frame with no limit. A failed video load now keeps its error state like image fills do; use
forceLoadResources/forceLoadAVResourceto explicitly retry it.
Engine/Web
- Fixed jittery video playback on Firefox. H.264 videos containing B-frames are now decoded in presentation order instead of decode order, eliminating the jumping and twitching artifacts that appeared while a video was playing.
Engine/Node
- Fixed
targetWidth/targetHeightbeing silently ignored byexportVideoin@cesdk/node-native. Passing both dimensions now resizes the exported video as documented, matching the WASM binding — no explicituseTargetSizeflag required.
Engine/Android
- Fixed a potential crash when overlapping engine directory cleanup operations delete stale temporary files.
Editor/Web
- Fixed uneven inspector bar spacing — corrected the doubled flex gap around zero-width spacers and removed the redundant horizontal margin that made the trim bar inset wider than other bars.
- Fixed the caption panel input losing focus immediately after clicking “Create Manually”, which interrupted typing the first caption.
- Fixed an issue causing the shadow inspector to be visible for page blocks.
Editor/iOS
- Fixed a regression where pressing Backspace on an empty list item deleted the whole paragraph in a single keystroke. The first Backspace now clears the bullet/number while keeping the paragraph, and a second Backspace merges it with the previous paragraph (matching Web and Android). Affects both the hardware and on-screen keyboard.
- Fixed the Crop sheet’s Reset button. It is now correctly disabled when the crop has no modifications, and tapping it clears all crop edits while keeping the block in crop mode.
- Fixed undo/redo after a page resize leaving the canvas zoom misaligned. The view now re-fits the page on every history step while the resize sheet is open.
- Dashed and dotted strokes no longer flicker while adjusting the stroke width.
Editor/Android
- Dashed and dotted strokes no longer flicker while adjusting the stroke width.
Editor/Flutter
- Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.
Version v1.76.1 Changelog June 17, 2026
Breaking Changes
Non Breaking Changes
- Engine/Web, Editor/Web: Fixed a critical issue around the API endpoints used by the licensing mechanism.
Version v1.76.0 Changelog June 3, 2026
Breaking Changes
- Editor/RN: Fixed exported artifact files on Android being named with a
.tmpextension instead of the format-specific extension (e.g..mp4,.png,.pdf).EditorBuilderDefaults.getExportResultnow requires amimeType: MimeTypeargument; callers that override the export builder must pass theMimeTypeof the exported buffer. - Editor/Flutter: Fixed exported artifact files on Android being named with a
.tmpextension instead of the format-specific extension (e.g..mp4,.png,.pdf).EditorBuilderDefaults.getExportResultnow requires amimeType: MimeTypeargument; callers that override the export builder must pass theMimeTypeof the exported buffer.
Non Breaking Changes
- Engine: Added
subscribeToHistoryWithKind, whose callback receives aHistoryUpdatedistinguishing snapshot changes (Updated) from activations viasetActiveHistory(Activated), so consumers can ignore pure preview-mode activations. The existingsubscribeToHistoryis deprecated in favor of the new method. - Engine/Web: Added
engine.editor.onHistoryUpdatedWithKind((kind) => …), whose callback receives aHistoryUpdate('Updated'or'Activated').engine.editor.onHistoryUpdatedis deprecated in favor of the new method. - Engine/Swift: Added
EditorAPI.onHistoryUpdatedWithKindandonHistoryUpdatedWithKindPublisher, which emitHistoryUpdate.EditorAPI.onHistoryUpdatedandonHistoryUpdatedPublisherare deprecated in favor of the new members. - Engine/Android: Added
EditorApi.onHistoryUpdatedWithKind(), which returnsFlow<HistoryUpdate>.EditorApi.onHistoryUpdated()is deprecated in favor of the new method. - Editor/Android: Added the
BackgroundRemovalplugin for removing image backgrounds in the editors. - Editor/Android: Added support for multi-clip foreground tracks in the timeline, including split, gap-aware trim and move, and respect for locked clips.
- Editor/Android: Long-press a clip on the timeline to drag it within or across tracks, or into a gap to create a new track.
- Editor/Android: The video starter kit’s Dock and InspectorBar no longer include
Dock.Button.rememberReorder()/InspectorBar.Button.rememberReorder()— long-press drag on the timeline replaces them. The functions remain available for consumers who want to add the buttons back. - Editor/Android: The video starter kit’s InspectorBar no longer includes
InspectorBar.Button.rememberMoveAsClip()/InspectorBar.Button.rememberMoveAsOverlay()— drag-and-drop between background and foreground tracks on the timeline replaces them. The functions remain available for consumers who want to add the buttons back. - Engine/Web: Added optional
filterparameter toengine.asset.findAssetsfor structured property predicates ({ property, contains?, equals? }) combined withand/or/notcombinators. See Querying Assets guide for details. - Engine/Web: Custom asset sources now receive the structured
filterin theirfindAssetscallback alongside the existingquery/tags/groupsfields. - Engine/Web: Added
block.getTextCharacterInkBoxes(id, from, to)— returns the tight ink-paint bounding box of each grapheme cluster in[from, to), in global scene coordinates. - Engine/Android: Added
BlockApi.getTextCharacterInkBoxes(block, from, to)returningList<CharacterInkBox>. - Engine/iOS: Added
block.getTextCharacterInkBoxes(_:in:)returning[CharacterInkBox]. - Engine: Added
setContentFillHorizontalAlignment,getContentFillHorizontalAlignment,setContentFillVerticalAlignment, andgetContentFillVerticalAlignmentto control the alignment of the content fill within a block when usingContainorCoverfill modes. Useful for templates where the inserted image’s aspect ratio is unknown and should pin to a specific edge (e.g. top-left) rather than always centering. - Editor/Web: Added content fill alignment controls in the crop inspector. Can be disabled via
cesdk.feature.enable('ly.img.crop.fillAlignment', false). - Editor/iOS: Added support for multi-clip foreground tracks in the timeline, including split, gap-aware trim and move, and respect for locked clips.
- Editor/iOS: The default video editor’s Dock and InspectorBar no longer ship
Dock.Buttons.reorder()/InspectorBar.Buttons.reorder()— long-press drag on the timeline replaces them. The factories remain available for consumers who want to add the buttons back. - Editor/iOS: Drag clips between background and foreground tracks on the timeline.
- Editor/iOS: Long-press a clip on the timeline to drag it within or across tracks, or into a gap to create a new track. Background clips reorder using the same gesture.
- Engine: Added paragraph-granular line height API:
setTextLineHeightandgetTextLineHeightallow each paragraph in a text block to carry its own line height multiplier, independent of the block-leveltext/lineHeightdefault. - Engine: Added
scene.setFontSizeUnit()/scene.getFontSizeUnit()to choose howsetTextFontSize,getTextFontSizes, and the font-size float properties (text/fontSize,text/min/maxAutomaticFontSize, and the matchingcaption/*properties) interpret values on a per-scene basis (PointorPixel). The engine continues to store font sizes in points internally; this only affects API-boundary interpretation. - Engine:
scene.create()gained an overload that acceptsdesignUnitand an optionalfontSizeUnit. WhenfontSizeUnitis omitted it is auto-paired withdesignUnit(Pixel→Pixel, others →Point). - Editor/Web: Added a font-size unit selector to the page resize panel, and the font-size input now displays the scene’s unit (
pxorpt). The new selector is gated by thely.img.scene.fontSizeUnitfeature key (enabled by default; disable viacesdk.feature.disable('ly.img.scene.fontSizeUnit')). - Editor/Android: Added a font-size unit selector to the page resize dialog.
- Editor/iOS: Added a font-size unit picker to the page resize overlay.
- Engine: Added
setTextKerningandgetTextKerningsAPI for per-range character kerning offset control. - Engine: Added
text/useKerning,text/useContextualLigatures, andtext/useDiscretionaryLigaturesboolean properties to text and caption blocks, enabling independent control of OpenType kerning (kern), contextual ligatures (clig), and discretionary ligatures (dlig) viagetBool/setBool. - Engine: Text and caption blocks now render
InnerandOuterstroke positions in addition toCenter, matching shape behavior. ThesetStrokePositionAPI no longer returns an error for text blocks. - Editor/Web: The stroke position selector is now shown for text and caption blocks in the Inspector.
- Engine: Line shapes are now true open-path lines instead of thin rectangles. Stroke caps can now be configured for both line and dash endpoints.
- Editor/iOS: Updated the value of the
ly_img_editor_timeline_add_audio_option_musicresource from “Music” / “Musik” to “Audio” / “Audio”. - Editor/Android: Fixed the “Add Audio” timeline menu’s library option reusing the dock’s
ly_img_editor_dock_button_audiostring. It now uses the dedicatedly_img_editor_timeline_add_audio_option_musicresource. - Editor/Android: Opening the filter sheet, opening the crop sheet, or uploading an asset no longer crashes when the corresponding asset source is not registered. The affected feature degrades gracefully instead.
- Editor/Android: Fixed voiceover sheet controls being drawn under the system navigation bar on devices with 3-button navigation.
- Engine: Fixed click-through on images with effects or a blur applied.
- Engine: Fixed
exportPdfWithDeviceCMYKderiving the DeviceN alternate color from RGB instead of CMYK when a spot color carried both definitions. - Engine: Routed the evaluation-license banner and the
EventSubscriptionService::initEventCallbacks errorStateChangedline to stderr instead of stdout, so callers can keep stdout clean for structured output (e.g. piping engine results throughjq). On emscripten the banner now goes throughemscripten_console_error(browser DevTools,console.error; Node.jsprocess.stderr); on native targets it goes throughUBQ_ERRPRINTLN(FD 2). - Engine: Fixed glyph overhangs (e.g., descenders) being clipped when exporting text with
allowTextOverhang: true. - Editor/Flutter: Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.
- Editor/Web: Fixed the per-image sub-section labels in the color picker’s “More” view, which previously showed the raw translation key (e.g.
libraries.ly.img.colors.panel...) instead of the image’s name. - Camera/iOS: Multiple Dual Camera and reaction clips now share a single track per camera angle instead of creating a new track per recording, both when entering the Video Editor from the camera and when adding recordings to an existing timeline.
- Engine/Swift: Fixed fast single-finger gestures on iOS being silently dropped before reaching the engine, causing quick page-carousel swipes and other gestures to occasionally do nothing.
- Editor/iOS: Fix corrupted target color icon in the Recolor effect on iOS 26.
- Editor/iOS: Fixed a “Tried to get solid color fill value on a block that has no such fill color” error when opening a scene whose named blocks have image, video, or non-linear-gradient fills.
- Editor: Fixed multi-selection bounding box and resize behavior when an audio block is selected together with visual blocks. The selection frame now stays around the visual blocks only, and resizing no longer affects audio tracks.
- Engine: Improved page-carousel swipe feel.
- Editor/Web: Silenced
findDOMNodedeprecation warning emitted byreact-draggableby passingnodeRefto everyDraggable/DraggableCoreinstance. - Engine: Fixed the corner-rounding slider producing a triangular bevel on shapes with mild bends (e.g. Organic Dot 1/2). Mild junctions now smooth progressively with the slider; sharper corners still round as before.
- Editor/Web: Fixed an issue where the slider’s optional numeric input was letting users commit values that did not land on the slider’s
stepgrid. - Engine: Fixed move-handle snap targets being offset from the design block frame for text blocks with a background fill. All four edges (left/right/top/bottom) now consistently snap to the design block frame bounds; background-color padding is no longer factored into the snap geometry or the dragged-segment indicator.
- Engine:
setStrokeDashArrayandsetStrokeDashOffsetnow reject NaN and infinity inputs with a clear error message, matching the validation already used by the rest of the float-typed stroke setters. - Engine: Custom dash patterns now scale with the shape when resizing from a corner, keeping the dash spacing visually consistent.
- Editor/Android: Updated the English translation of
ly_img_editor_sheet_format_text_label_frame_clippingfrom “Frame Clipping” to “Clipping”. - Editor/iOS: Updated the English translation of
ly_img_editor_sheet_format_text_label_frame_clippingfrom “Frame Clipping” to “Clipping”. - Editor/Web: Inspector sliders bound to a block property (e.g. brightness, contrast) now reliably update the undo state on slow CPUs.
- Editor/Web: Fixed an issue where the
fillandstrokeplaceholder sections where enabled for stickers blocks. - Engine: Fixed slowdowns and occasional freezes when applying adjustments, filters, or effects to images.
- Engine: Fixed an issue where video clip thumbnails not updating after replacing the underlying video in some cases.
- Engine: Added a new
playback/showAllBlockssetting that keeps every element visible on the canvas at once, even ones that would otherwise only appear at certain playback times. Off by default. - Renderer: Fixed
--page <index>selecting the wrong page on multi-column/spread layouts. The CLI now selects pages in document order, matching whole-scene PDF export, instead of reordering them by canvas position. - Engine: Fixed an issue where PDF exports with
exportPdfWithDeviceCMYKenabled could render thin shape outlines far too thick, turning small icons into oversized solid shapes. - Editor/Web: Fixed an issue where the audio track in the video editor timeline could be hidden on initial load until the timeline was collapsed and re-expanded.
- Editor/Android: Fixed tapping a placeholder page not opening any replace library. The library now matches the page’s fill — images for an image fill, videos for a video fill.
- Editor/Android: The inspector bar now shows a Replace button for a page with an image or video fill, opening the matching library (images or videos) to replace the page’s fill.
- Editor/iOS: Fixed tapping a placeholder page opening the full asset library instead of one matching the page’s fill (images for an image fill, videos for a video fill).
- Editor/iOS: The inspector bar now shows a Replace button for a page with an image or video fill, opening the matching library (images or videos) to replace the page’s fill.