<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>CE.SDK – IMG.LY Blog</title><description>Posts tagged CE.SDK on the IMG.LY blog.</description><link>https://img.ly/blog/tag/ce-sdk/</link><language>en-us</language><image><url>https://img.ly/apple-touch-icon.png</url><title>CE.SDK – IMG.LY Blog</title><link>https://img.ly/blog/tag/ce-sdk/</link></image><atom:link href="https://img.ly/blog/tag/ce-sdk/rss.xml" rel="self" type="application/rss+xml"/><generator>Astro</generator><lastBuildDate>Tue, 01 Sep 2026 09:42:43 GMT</lastBuildDate><ttl>60</ttl><item><title>Evaluating CoDesign MCP performance in resizing</title><link>https://img.ly/blog/evaluating-codesign-mcp-performance-in-resizing/</link><guid isPermaLink="true">https://img.ly/blog/evaluating-codesign-mcp-performance-in-resizing/</guid><description>One approved design, five ad formats, six AI models, the same brief. All six came back with ads you could ship, and Gemini 3.7 Flash did it for thirty cents. Here is what our automated checks can prove about that work, and what they cannot.</description><pubDate>Fri, 21 Aug 2026 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You designed a banner. The same day, you need it in five sizes, and none of them can be wrong.&lt;/p&gt;
&lt;p&gt;We handed that job to six AI models through &lt;a href=&quot;https://img.ly/codesign/&quot;&gt;CoDesign&lt;/a&gt; MCP: take this approved design and rebuild it for five ad formats. All six came back with ads you could ship. Gemini 3.7 Flash did it for thirty cents and passed every check we wrote.&lt;/p&gt;
&lt;p&gt;That is what CoDesign MCP is for. You point an AI assistant such as Claude at your approved design, name the formats you need, and it opens the file, rebuilds the layout for each one and exports production files. What comes back is an editable design file, not a picture of one.&lt;/p&gt;
&lt;p&gt;Speed and price are the easy things to measure. We wanted to measure quality too, so we built an eval that runs the job automatically, opens every result and reports what passed. This is the first scenario out of that suite.&lt;/p&gt;
&lt;h2 id=&quot;three-banners-one-brief&quot;&gt;Three banners, one brief&lt;/h2&gt;
&lt;p&gt;Three different models were handed the same 320×50 slot, cut from the same master creative against the same brief, and all three came back with an ad you could traffic tomorrow. Every one of them keeps the wordmark and the button, nothing is clipped, and no type is set below 11px.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Three 320×50 mobile banners built from the same ATLAS master by three different models&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1200px) 1200px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1200&quot; height=&quot;207&quot; src=&quot;https://img.ly/_astro/hook-three-mobile-strips.Q8QXs3k1_2XYzx.webp&quot; srcset=&quot;/_astro/hook-three-mobile-strips.Q8QXs3k1_Z1pTCV1.webp 640w, /_astro/hook-three-mobile-strips.Q8QXs3k1_2oKvSC.webp 750w, /_astro/hook-three-mobile-strips.Q8QXs3k1_27uKLv.webp 828w, /_astro/hook-three-mobile-strips.Q8QXs3k1_ZNKOe4.webp 1080w, /_astro/hook-three-mobile-strips.Q8QXs3k1_2XYzx.webp 1200w&quot;&gt;&lt;/p&gt;
&lt;p&gt;The 300×250 they came from carried five things: the wordmark, the headline, a retention chart, the offer line and the button. At 320×50 the wordmark and the button survive and the chart cannot, which leaves room for exactly one line of copy, so each model had to choose between the headline and the offer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One dropped the headline and kept the offer, “14-day free trial”.&lt;/li&gt;
&lt;li&gt;One kept the headline but cut “your users” down to “users” to buy itself the line.&lt;/li&gt;
&lt;li&gt;One kept the headline whole across two lines and dropped the offer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We have opinions about which of those reads best, the way any design team would. What we do not have is a way to prove one of them correct, because the choice depends on whether this campaign is selling the product or the trial, and that lives in the media brief rather than in the design. Our checks can confirm that all three are valid and that none of them are broken; they cannot tell you which one the campaign actually needed. Grading the half that has a right answer and leaving the other half to the people who own the brief is the distinction our evals are built around.&lt;/p&gt;
&lt;h2 id=&quot;what-is-gradeable-and-what-is-not&quot;&gt;What is gradeable and what is not&lt;/h2&gt;
&lt;p&gt;The obvious thing to evaluate is the thing that demos well, prompt in and poster out, but we were more interested in the work that actually fills a designer’s week, which is mostly derivative. The design decisions were made once, at the master, and everything after that is a matter of carrying them faithfully into thirty other shapes. That is more technical work than creative work, which is exactly why it is worth handing to an agent.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Three valid 300×600 versions of the same ATLAS banner, differing in type size and spacing&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1200px) 1200px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1200&quot; height=&quot;702&quot; src=&quot;https://img.ly/_astro/gradeable-three-halfpage-variants.D3Bbuya5_2lpIzm.webp&quot; srcset=&quot;/_astro/gradeable-three-halfpage-variants.D3Bbuya5_Z1FdAzV.webp 640w, /_astro/gradeable-three-halfpage-variants.D3Bbuya5_Z1ihu0z.webp 750w, /_astro/gradeable-three-halfpage-variants.D3Bbuya5_FqKnt.webp 828w, /_astro/gradeable-three-halfpage-variants.D3Bbuya5_ZWQJb7.webp 1080w, /_astro/gradeable-three-halfpage-variants.D3Bbuya5_2lpIzm.webp 1200w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Ask which of the finished designs is better and you have a question with no ground truth to appeal to, since human raters disagree with each other and LLM judges reliably prefer their own output. You could ask a lot of humans and rank the results, but that is not something you can run on every build. Wrong designs, though, are wrong in ways you can query: text sitting behind another block, content off the page, type under the legibility floor. Part of design quality is judgement and part of it is fact, and what we have built grades the second part, which means everything below is an automated result rather than a design review. A model can pass every check we wrote and still make an ugly ad.&lt;/p&gt;
&lt;h2 id=&quot;what-we-are-doing-right-now&quot;&gt;What we are doing right now&lt;/h2&gt;
&lt;p&gt;When a model finishes a scenario, programmatic checks open the result and ask whether it is plausibly good. That starts with whether the run produced every design artifact and .imgly file at the right sizes, and the rest depends on the scenario: in a localization run we also check that the words were actually replaced.&lt;/p&gt;
&lt;p&gt;This is a technical floor rather than a grade. LLM judges are still unreliable enough that we do not use one on output quality, because if it is hard for us as designers to say which design is more correct, it is harder for a model, and the result would be noise.&lt;/p&gt;
&lt;p&gt;In the future we plan to experiment more with such methodologies but we also do not want to rely on the false security of an extremely noisy grading process.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;The eval suite&amp;#39;s comparison view for the display-banner matrix&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 2396px) 2396px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;2396&quot; height=&quot;1344&quot; src=&quot;https://img.ly/_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_8PXp1.webp&quot; srcset=&quot;/_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_Znaqv1.webp 640w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_Z20zsc2.webp 750w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_Z26h51n.webp 828w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_Z1Eg8Vb.webp 1080w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_CxK9F.webp 1280w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_Z1lqFrF.webp 1668w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_ZgDr5i.webp 2048w, /_astro/evals-suite-comparison-resize-matrix.CV8e1T_u_8PXp1.webp 2396w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The comparison view for the display-banner matrix: cost and time sitting directly above what each model actually produced. The 1/1 counts runs, one repeat per cell, not check scores.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;one-master-five-ad-sizes&quot;&gt;One master, five ad sizes&lt;/h2&gt;
&lt;p&gt;The scenario is a display campaign, because that is the version of this problem customers actually have: the same size matrix, every campaign. The master is a 300×250 MPU for ATLAS, an imaginary product-analytics SaaS running a free-trial campaign, carrying a wordmark, the headline “See what your users &lt;strong&gt;actually&lt;/strong&gt; do”, a retention bar chart labelled “43% retained”, the line “14-day free trial. No card.”, and a “Start free trial” button.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;The ATLAS 300×250 master at the top, with an arrow fanning down to the same ad rebuilt at 300×600, 728×90, 320×50 and 160×600&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1200px) 1200px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1200&quot; height=&quot;675&quot; src=&quot;https://img.ly/_astro/master-and-five-sizes.CzF5wnY5_21RxX1.webp&quot; srcset=&quot;/_astro/master-and-five-sizes.CzF5wnY5_FUIkG.webp 640w, /_astro/master-and-five-sizes.CzF5wnY5_Z7tPBU.webp 750w, /_astro/master-and-five-sizes.CzF5wnY5_mzCbS.webp 828w, /_astro/master-and-five-sizes.CzF5wnY5_Zpv1pN.webp 1080w, /_astro/master-and-five-sizes.CzF5wnY5_21RxX1.webp 1200w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The 300×250 master at the top, and the four other sizes on the media plan cut from it. ATLAS is our own fixture, not a real customer.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The brief asks for the full matrix: 300×250, 728×90, 160×600, 300×600 and 320×50. Those sizes span a 16:1 swing in aspect ratio, so the right answer at each one is a genuinely different composition, and at some of them it means taking content out rather than shrinking it.&lt;/p&gt;
&lt;p&gt;Ten checks grade the result and two of them do the real work. &lt;strong&gt;&lt;code&gt;728×90: the chart was dropped, not shrunk&lt;/code&gt;&lt;/strong&gt; kills the model that squashes a bar chart into a 90-pixel strip, which satisfies every geometric constraint in the brief while being completely wrong. &lt;strong&gt;&lt;code&gt;the five sizes are different layouts&lt;/code&gt;&lt;/strong&gt; kills the model that scales one composition five ways and calls it a matrix.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Contact sheet of six 728×90 leaderboards, master first&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1280px) 1280px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1280&quot; height=&quot;676&quot; src=&quot;https://img.ly/_astro/sheet-display-leaderboard.BStENqrh_1X5bgP.webp&quot; srcset=&quot;/_astro/sheet-display-leaderboard.BStENqrh_2uIgrs.webp 640w, /_astro/sheet-display-leaderboard.BStENqrh_Z1sXCsn.webp 750w, /_astro/sheet-display-leaderboard.BStENqrh_Z1JQH3t.webp 828w, /_astro/sheet-display-leaderboard.BStENqrh_Z2gFqpY.webp 1080w, /_astro/sheet-display-leaderboard.BStENqrh_1X5bgP.webp 1280w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The master first, then the six 728×90 leaderboards. Every model that delivered deleted the retention chart.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Every model that delivered arrived at the same composition, wordmark left, headline across the middle, offer underneath it, button on the right and the retention chart deleted, which is six models from five different vendors reaching the same answer independently. We did not expect that, and it is still the result we find hardest to stop thinking about.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Contact sheet of six 160×600 skyscrapers, master first&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1280px) 1280px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1280&quot; height=&quot;676&quot; src=&quot;https://img.ly/_astro/sheet-display-skyscraper.C88KXRcA_Z1lHK5K.webp&quot; srcset=&quot;/_astro/sheet-display-skyscraper.C88KXRcA_Z2cPTfD.webp 640w, /_astro/sheet-display-skyscraper.C88KXRcA_1krJOz.webp 750w, /_astro/sheet-display-skyscraper.C88KXRcA_ZmDw0F.webp 828w, /_astro/sheet-display-skyscraper.C88KXRcA_Z1S3Ozm.webp 1080w, /_astro/sheet-display-skyscraper.C88KXRcA_Z1lHK5K.webp 1280w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The same six at 160×600, master first. With vertical room they all kept the chart. The flat format is where the decision to drop it had to be made.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;which-model-is-best-for-using-with-codesign-mcp&quot;&gt;Which model is best for using with CoDesign MCP?&lt;/h2&gt;





























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;#&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;model&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;checks&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;model spend&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;time&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;tool calls&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;gemini-3.7-flash&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10 / 10&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$0.30&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;6.7 min&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;37&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;2&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;glm-5.2&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10 / 10&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$0.40&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;8.2 min&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;25&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;3&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;gpt-5.6-sol&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10 / 10&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$0.52&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4.0 min&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;35&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;4&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;grok-4.6&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10 / 10&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$1.20&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;20.9 min&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;39&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;5&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;claude-fable-5&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10 / 10&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$3.95&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10.3 min&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;26&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;6&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;claude-opus-5&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10 / 10&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$3.97&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;18.8 min&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;40&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Running this scenario illustrates general numbers across our eval suite. The 6 models above are consistently able to follow the prompts to produce different output designs as requested in the scenario. These numbers also highlight quite the spread in model costs and time spend. What you do not see in these numbers is that glm 5.2, gpt-5.6-sol and grok 4.6 are producing suboptimal designs in our opinion. They are valid, but subjectively fable, opus and gemini 3.7 consistently across runs and across scenarios perform simply better.&lt;/p&gt;
&lt;p&gt;The biggest surprise for us is &lt;strong&gt;Gemini 3.7 Flash&lt;/strong&gt;, which produced the whole five-size matrix for $0.30 in model spend, in under seven minutes. At thirty cents a designer opens six composed variants instead of a blank artboard and takes the best one further, which changes what the tool is for.&lt;/p&gt;
&lt;p&gt;Meanwhile there were no surprises regarding &lt;strong&gt;Opus 5.0 and Fable 5.0&lt;/strong&gt;, both models perform really well - but are slow and expensive.&lt;/p&gt;
&lt;h2 id=&quot;what-does-it-mean-for-codesign-mcp&quot;&gt;What does it mean for CoDesign MCP&lt;/h2&gt;
&lt;p&gt;You can now resize a master design into 5 different sizes reliably for $0.30 using Gemini 3.7 Flash and the CoDesign MCP.&lt;/p&gt;
&lt;p&gt;If you are on a Claude Subscription plan, you might just want to continue using your Claude Code with the CoDesign MCP since it offers the best overall design quality - even if it’s slow and somewhat expensive.&lt;/p&gt;
&lt;p&gt;We will continue to work on upgrading and improving measurements of how well CoDesign MCP works with different models, looking into other scenarios like localization (translating and changing a design for a different locality and language) as well as rebranding existing design assets.&lt;/p&gt;
&lt;p&gt;You can install CoDesign MCP at &lt;a href=&quot;https://img.ly/codesign/&quot;&gt;&lt;strong&gt;img.ly/codesign&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Dustin</dc:creator><dc:creator>Mirko</dc:creator><media:content url="/_astro/key-visual-resize-fanout.qeZDEyVs.png" medium="image"/><category>AI</category><category>Insights</category><category>CE.SDK</category></item><item><title>CE.SDK v1.78 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-78-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-78-0-release-notes/</guid><description>A typography and reliability release: curve text with a dedicated path control in the web editor, plus a broad set of engine and editor fixes across web, mobile, and backend.</description><pubDate>Tue, 21 Jul 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;CE.SDK v1.78 is a typography and reliability release. It adds a dedicated path control for curved text on the web, alongside a broad set of engine and editor fixes across web, mobile, and backend.&lt;/p&gt;
&lt;p&gt;Let’s dive in.&lt;/p&gt;
&lt;h2 id=&quot;more-expressive-typography&quot;&gt;More Expressive Typography&lt;/h2&gt;
&lt;h3 id=&quot;curve-text-with-a-dedicated-path-control-on-the-web&quot;&gt;Curve Text with a Dedicated Path Control on the Web&lt;/h3&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/07/cesdk-text-on-path-curves.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;The web editor gains a Path control for text blocks. Users can place text on a curve using Circle, Arch, and Wave presets, then adjust position, direction, and offset directly in the inspector.&lt;/p&gt;
&lt;p&gt;For custom shapes, Edit Path lets users draw their own baseline instead of picking a preset, so text can follow whatever curve a design calls for. This builds on the text-on-path support added in v1.77.&lt;/p&gt;
&lt;p&gt;→ &lt;a href=&quot;https://img.ly/docs/cesdk/js/text/edit-c5106b/&quot;&gt;Edit Text Documentation (Web)&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;improvements&quot;&gt;Improvements&lt;/h2&gt;
&lt;h3 id=&quot;keep-edited-text-above-the-mobile-keyboard&quot;&gt;Keep Edited Text Above the Mobile Keyboard&lt;/h3&gt;
&lt;p&gt;On mobile web, the canvas reserves space for the on-screen keyboard and pans to the text cursor, so the text being edited stays visible while typing.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;browse-typefaces-smoothly-on-slow-networks&quot;&gt;Browse Typefaces Smoothly on Slow Networks&lt;/h3&gt;
&lt;p&gt;The web typeface library shows font names immediately and loads previews lazily as rows scroll into view, keeping the picker responsive on low-end devices.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;refresh-ios-asset-libraries-automatically&quot;&gt;Refresh iOS Asset Libraries Automatically&lt;/h3&gt;
&lt;p&gt;On iOS, an open library updates in place when its source’s contents change, matching the web editor.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;stability-and-fixes&quot;&gt;Stability and Fixes&lt;/h2&gt;
&lt;p&gt;This release includes a broad set of stability, performance, and rendering fixes across the engine and editors. Among them: a Safari video-export fix for projects that contain uploaded video, faster handling of large caption files, curved-text caret and selection fixes, iOS effect-sheet and web keyboard-accessibility fixes, and archive-loading crash guards. See the changelog for the full list.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;
&lt;p&gt;All improvements, breaking changes, and fixes are in the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/v1-78-0/&quot;&gt;v1.78.0 changelog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thank you for building with IMG.LY.&lt;/em&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="/_astro/cesdk-178-curve-text-path.BBFnDznS.jpg" medium="image"/><category>Release Notes</category><category>CE.SDK</category></item><item><title>13 Questions Teams Ask Themselves Before Choosing IMG.LY</title><link>https://img.ly/blog/13-questions-before-choosing-an-editor-sdk/</link><guid isPermaLink="true">https://img.ly/blog/13-questions-before-choosing-an-editor-sdk/</guid><description>Before integrating an in-app editor, teams ask the same 13 questions. Each one answered straight, backed by real customer data, covering speed, scaling, brand control, AI, and vendor risk.</description><pubDate>Fri, 19 Jun 2026 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most teams evaluating an in-app editor arrive with the same shortlist of questions. These are the 13 that come up most across &lt;a href=&quot;https://img.ly/case-studies/&quot;&gt;600+ customers&lt;/a&gt; and &lt;a href=&quot;https://img.ly/blog/imgly-impact-report/&quot;&gt;28 structured interviews&lt;/a&gt;, each answered straight, with the numbers behind it.&lt;/p&gt;

&lt;h2 id=&quot;why-integrate-an-editor-instead-of-building-our-own&quot;&gt;Why integrate an editor instead of building our own?&lt;/h2&gt;
&lt;p&gt;A production-ready SDK turns months of editor engineering into a couple of weeks of integration. &lt;a href=&quot;https://img.ly/blog/strategic-guide-to-creative-editing-when-to-build-when-to-buy/&quot;&gt;Building an equivalent editor in-house&lt;/a&gt; runs 6 to 12 months and ties up two or three senior developers. The median IMG.LY customer reaches production within just 14 days, roughly 13× faster than the in-house route. For fast-moving companies especially, staying on your core is what pays off. Time spent on the editor is time not spent on what actually sets your product apart.&lt;/p&gt;
&lt;h2 id=&quot;cant-we-just-use-an-open-source-library-like-fabricjs-or-konva&quot;&gt;Can’t we just use an open-source library like Fabric.js or Konva?&lt;/h2&gt;
&lt;p&gt;You can, and some companies do. The problems start once you need more than a drawing surface. Open-source canvas libraries give you that surface and little else, no text on a path, no video timeline, no background removal, no cross-platform parity, and no ready-made UI. You build all of that yourself, and then you own the maintenance forever. The library is free, the year of senior engineering it takes to reach production quality is not.&lt;/p&gt;
&lt;figure class=&quot;imgly-q&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;It was very buggy, lack of features, not looking good, and we decided to not go deeper.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class=&quot;role&quot;&gt;Engineering lead at a company that evaluated open source before CE.SDK&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;CE.SDK gives you the engine and the UI in one SDK, with the same rendering across web, iOS, and Android. If you want the full breakdown, we put open source next to building and buying in our &lt;a href=&quot;https://img.ly/blog/build-vs-buy-is-fabric-js-right-for-you/&quot;&gt;Fabric.js comparison&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;how-fast-can-we-realistically-be-in-production&quot;&gt;How fast can we realistically be in production?&lt;/h2&gt;
&lt;p&gt;A working prototype usually takes about two days, and a production-ready integration around two weeks. That time goes into wiring the existing SDK and API into your product and styling it to fit. Our &lt;a href=&quot;https://img.ly/docs/cesdk/react/get-started/build-with-ai-k7m9p2/&quot;&gt;AI developer tooling&lt;/a&gt; accelerates the process even more, giving your AI coding assistant full CE.SDK context for the integration. For fast-moving companies, this can be a real booster. &lt;a href=&quot;https://img.ly/case-studies/plai/&quot;&gt;Plai&lt;/a&gt; went from deal to live in about a month, then quickly scaled to thousands of ad campaigns with the new editor in place.&lt;/p&gt;
&lt;h2 id=&quot;every-design-edit-request-lands-on-my-team-how-do-we-scale-that&quot;&gt;Every design edit request lands on my team. How do we scale that?&lt;/h2&gt;
&lt;p&gt;You stop being the bottleneck. Instead of your team producing every asset, users edit themselves inside your product, so output scales with your user base, not your headcount.&lt;/p&gt;
&lt;figure class=&quot;imgly-q&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;When you&apos;re dealing with a graphic designer who has a queue of work, you usually need to wait.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class=&quot;role&quot;&gt;Product lead at an IMG.LY customer&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The digital agency &lt;a href=&quot;https://img.ly/case-studies/digitas/&quot;&gt;Digitas&lt;/a&gt; built its dealer portal on CE.SDK, and removing that bottleneck led to 85% of videos being created fully in-app, with active users making 3× more than before. None of that work routes through a design team.&lt;/p&gt;
&lt;p&gt;The same engine also scales without anyone editing at all. Run it headless and it &lt;a href=&quot;https://img.ly/use-cases/creative-automation/&quot;&gt;generates assets automatically&lt;/a&gt;. One template plus your data renders thousands of on-brand variants through the API. &lt;a href=&quot;https://img.ly/case-studies/postbuddy/&quot;&gt;PostBuddy&lt;/a&gt;, for example, does exactly this. Its users choose a template, upload a CSV, and the engine auto-generates thousands of personalized, print-ready postcards, with no one editing a single one. Self-serve covers the one-offs, automation covers the scale.&lt;/p&gt;
&lt;h2 id=&quot;our-users-arent-designers-how-do-we-keep-results-on-brand-without-manual-review&quot;&gt;Our users aren’t designers. How do we keep results on-brand without manual review?&lt;/h2&gt;
&lt;p&gt;With guardrails you set. Templates, locked brand elements, and constraints let a non-designer produce polished, on-brand work by default, because the editor only exposes what you allow. The output can even beat the professionals.&lt;/p&gt;
&lt;figure class=&quot;imgly-q&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;I built a better-looking asset in the portal than the agency ever did.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;strong&gt;Martin Röhr&lt;/strong&gt; &lt;span class=&quot;role&quot;&gt;— Senior Project Manager, &lt;a href=&quot;https://img.ly/case-studies/digitas/&quot;&gt;Digitas&lt;/a&gt;&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Nobody has to check the output later, because the guardrails already did.&lt;/p&gt;
&lt;h2 id=&quot;we-already-have-an-editor-is-replacing-it-worth-the-costs&quot;&gt;We already have an editor. Is replacing it worth the costs?&lt;/h2&gt;
&lt;p&gt;The editing experience is part of the sale. When the flow is smooth, more users finish what they start, and completion is conversion. A clunky editor quietly costs you sales.&lt;/p&gt;
&lt;figure class=&quot;imgly-q&quot;&gt;
&lt;div class=&quot;q-body&quot;&gt;
&lt;p&gt;&quot;Our brand didn&apos;t match our experience. You could see it in our bounce rates,&quot; says Tom Rowe, and the difference is easy to spot: &quot;you can tell when competitors are using the old platform just by looking at it.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;figcaption&gt;&lt;strong&gt;Tom Rowe&lt;/strong&gt; &lt;span class=&quot;role&quot;&gt;— Product &amp;#x26; Engineering, &lt;a href=&quot;https://img.ly/case-studies/print-bar/&quot;&gt;The Print Bar&lt;/a&gt;&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When the status quo quietly costs deals, the editor should not be treated as a nice-to-have, but as an essential.&lt;/p&gt;
&lt;h2 id=&quot;will-it-match-our-products-look-and-feel&quot;&gt;Will it match our product’s look and feel?&lt;/h2&gt;
&lt;p&gt;Yes, and that fit is exactly what an SDK gives you. The UI is fully customizable. You can theme it, restyle it, or drive the engine from your own interface in a headless setup. It acts as a native part of your product instead of a third-party tool bolted on. Swiss Post, which runs over a million personalized postcards a year on it, confirms this, calling CE.SDK “the only solution allowing a specialized, on-brand UI.”&lt;/p&gt;
&lt;h2 id=&quot;we-ship-on-web-ios-and-android-do-we-need-three-different-tools&quot;&gt;We ship on web, iOS, and Android. Do we need three different tools?&lt;/h2&gt;
&lt;p&gt;No. One creative engine renders identically across web, iOS, and Android, so a template built on one platform looks the same on every other and your team keeps one mental model instead of maintaining three separate integrations. You build once instead of rebuilding the editor per OS.&lt;/p&gt;
&lt;h2 id=&quot;our-users-want-ai-features-do-we-have-to-build-those-too&quot;&gt;Our users want AI features. Do we have to build those too?&lt;/h2&gt;
&lt;p&gt;AI editing ships inside the editor, not as a separate project. Background removal and generative tools like text-to-image and image-to-video are ready to use, and CE.SDK is bring-your-own-model, so you plug in the providers you want instead of running inference yourself. That can move the top line on its own.&lt;/p&gt;
&lt;figure class=&quot;imgly-q&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;We are seeing a 10x increase in new signups month over month in May — that was due to the fact that you can now auto-generate really beautiful-looking ads from scratch.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;strong&gt;Hikari Senju&lt;/strong&gt; &lt;span class=&quot;role&quot;&gt;— Founder &amp;#x26; CEO, &lt;a href=&quot;https://img.ly/case-studies/omneky/&quot;&gt;Omneky&lt;/a&gt;&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;where-does-our-users-data-actually-go&quot;&gt;Where does our users’ data actually go?&lt;/h2&gt;
&lt;p&gt;By default, processing happens client-side, in the browser or on the device, so images and video never touch our servers. For customers with strict data-security requirements that is often a deciding factor, and it is increasingly named as a must-have in AI-driven research. Nothing leaves the user’s machine unless you deliberately choose a server-side workflow. And since IMG.LY is based in Germany, GDPR compliance and EU data residency come built in.&lt;/p&gt;
&lt;h2 id=&quot;if-we-build-on-this-are-we-locked-in&quot;&gt;If we build on this, are we locked in?&lt;/h2&gt;
&lt;p&gt;It is a fair concern, and a different one from whether the vendor sticks around. Your designs and templates stay yours. You can export both your scenes and the rendered output, as PNG, JPEG, PDF, and the scene file itself, and you can run the engine on your own infrastructure, fully headless if you want. You are integrating a component, not handing your data model to someone else, and switching the component out later is possible.&lt;/p&gt;
&lt;h2 id=&quot;can-we-depend-on-this-provider-when-it-matters&quot;&gt;Can we depend on this provider when it matters?&lt;/h2&gt;
&lt;p&gt;IMG.LY is an established company based in Germany, with a real team of people behind the product rather than a side project that could disappear next quarter. 600+ organizations, from startups to large global enterprises and government agencies, run the SDK in production, together generating around 500 million creations a month. Names on that list include Mercedes-Benz, Lufthansa, SAP, Polaroid, and Ticketmaster. You also get a dedicated contact who stays reachable when you need help, not an anonymous ticket queue, and the SDK keeps shipping new capabilities release after release, so the foundation you build on only gets stronger.&lt;/p&gt;
&lt;h2 id=&quot;how-do-we-know-itll-work-before-were-all-in&quot;&gt;How do we know it’ll work before we’re all in?&lt;/h2&gt;
&lt;p&gt;You don’t have to trust the pitch, you can prove it yourself. The trial is self-serve. A developer can spin up an account and start building with the real SDK without going through sales, then judge the integration and the docs firsthand. It doesn’t need to take long either, thanks to the &lt;a href=&quot;https://img.ly/docs/cesdk/react/get-started/build-with-ai-k7m9p2/&quot;&gt;AI developer tooling&lt;/a&gt; that helps your assistant generate accurate integration code. That’s how most teams who picked IMG.LY decided, because seeing it run in your own stack removes the guesswork before you commit.&lt;/p&gt;
&lt;h2 id=&quot;recognize-a-few-of-these&quot;&gt;Recognize a few of these?&lt;/h2&gt;
&lt;p&gt;These are exactly the questions a careful team should ask before building on someone else’s technology. If you’re working through them, we’re glad to help: &lt;a href=&quot;https://img.ly/demos/&quot;&gt;try the SDK yourself&lt;/a&gt; or &lt;a href=&quot;https://img.ly/forms/contact-sales/&quot;&gt;contact our team&lt;/a&gt;. Reaching out is no commitment, and we’re happy to dig into your specific case. And to see how it played out for other companies, our &lt;a href=&quot;https://img.ly/case-studies/&quot;&gt;case studies&lt;/a&gt; offer interesting insights.&lt;/p&gt;
</content:encoded><dc:creator>Marc</dc:creator><media:content url="/_astro/hero.6P1TMcLb.jpg" medium="image"/><category>Insights</category><category>CE.SDK</category></item><item><title>Starter Kits: A New Way to Use and Configure Our Editor</title><link>https://img.ly/blog/starter-kits-mobile/</link><guid isPermaLink="true">https://img.ly/blog/starter-kits-mobile/</guid><description>This release replaces CE.SDK&apos;s prebuilt mobile editors with Starter Kits: complete, ownable editor projects for iOS and Android. Full config control, no surprise UI changes.</description><pubDate>Wed, 22 Apr 2026 17:14:54 GMT</pubDate><content:encoded>&lt;p&gt;When we built the first version of CE.SDK’s mobile editors, we optimized for speed and ease of integration. We designed a set of ready-made solution editors: &lt;strong&gt;Photo&lt;/strong&gt;, &lt;strong&gt;Design&lt;/strong&gt;, &lt;strong&gt;Video&lt;/strong&gt;, &lt;strong&gt;Postcard&lt;/strong&gt;, and &lt;strong&gt;Apparel Editor.&lt;/strong&gt; Each is built around the use cases we believed would meet the needs of most of our customers. With one component and a license key, you had a full creative editor running in your app. That approach got products to market fast, and for many teams it was exactly the right starting point.&lt;/p&gt;
&lt;p&gt;But products evolve, and so do the needs around it.&lt;/p&gt;
&lt;p&gt;As integrations matured, teams needed deeper configuration, more granular control, and the ability to shape the editor into something uniquely theirs. What starts as “give us a &lt;em&gt;working&lt;/em&gt; photo editor” becomes “give us &lt;em&gt;our&lt;/em&gt; photo editor.”&lt;/p&gt;
&lt;p&gt;That’s why, starting with CE.SDK &lt;code&gt;v1.73&lt;/code&gt; on iOS and Android, CE.SDK evolves from a set of preconfigured solution editors into a single, flexible &lt;code&gt;Editor&lt;/code&gt; foundation paired with &lt;strong&gt;Starter Kits:&lt;/strong&gt; complete, working editor projects that you own, customize, and control entirely.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Starter Kits for Mobile: Fast set-up, full ownership and customization.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 2000px) 2000px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;2000&quot; height=&quot;857&quot; src=&quot;https://img.ly/_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_Z2sdwmF.webp&quot; srcset=&quot;/_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_1FOJJF.webp 640w, /_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_ZBqwOH.webp 750w, /_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_Zsh1Bm.webp 828w, /_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_ZrjQtD.webp 1080w, /_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_16oUNc.webp 1280w, /_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_1DVoxS.webp 1668w, /_astro/starter-kits-design-editor-video-apparel-mobile-ios-android-1_Z2sdwmF.webp 2000w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here’s what that means and why it’s worth it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;what-changed&quot;&gt;What changed&lt;/h2&gt;
&lt;p&gt;Previously, you integrated CE.SDK by dropping in a solution-specific component: &lt;strong&gt;PhotoEditor, DesignEditor, VideoEditor&lt;/strong&gt;, &lt;strong&gt;ApparelEditor and PostacardEditor&lt;/strong&gt;. Each came with built-in UI, default behaviors, and preconfigured toolbars. You could adjust &lt;em&gt;some&lt;/em&gt; of it through configuration APIs, but the foundation was managed internally by our SDK.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;v1.73&lt;/code&gt;, those components are replaced by a single &lt;strong&gt;Editor&lt;/strong&gt; entry point that starts minimal without any configuration and a set of &lt;strong&gt;Starter Kits&lt;/strong&gt; that provide the full experience you’re used to.&lt;/p&gt;
&lt;p&gt;Each Starter Kit matches a previous solution: Photo, Design, Video, Postcard, and Apparel. You download it, drop it into your project, and you have the same editor as before.&lt;/p&gt;
&lt;p&gt;With Starter Kits, the setup becomes explicit and lives in &lt;strong&gt;your&lt;/strong&gt; &lt;strong&gt;own codebase&lt;/strong&gt;. Instead of relying on built-in defaults inside a prebuilt solution, you &lt;strong&gt;start from a ready-made configuration&lt;/strong&gt; structure that you can inspect, own, and change directly.&lt;/p&gt;
&lt;p&gt;And if none of the starter kits match your needs, you can build your own editor from scratch using our configuration directly.&lt;/p&gt;
&lt;p&gt;Before, you were always starting from one of the predefined solutions and trying to bend it to fit your use case, which was limited and often frustrating. Now, the building blocks are there for you to assemble however you want.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;what-are-the-benefits&quot;&gt;&lt;strong&gt;What are the benefits?&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id=&quot;the-full-picture-in-one-place&quot;&gt;The full picture in one place&lt;/h3&gt;
&lt;p&gt;Configuration used to be spread across multiple APIs and documentation pages. It wasn’t always clear what you could customize, where to find the right setting, or whether a particular behavior was even exposed for modification.&lt;/p&gt;
&lt;p&gt;With a starter kit, the configuration &lt;em&gt;is&lt;/em&gt; the documentation. Open the configuration file, and you see every callback, every toolbar item, every setting, the complete scope of what the editor does.&lt;/p&gt;
&lt;p&gt;This also makes production behavior safer. Critical parts of the editor setup are now explicit in your code rather than implied by SDK defaults. Your team can see exactly what is configured, why, and review changes through your normal development process.&lt;/p&gt;
&lt;h3 id=&quot;more-control-and-capability-over-your-editor&quot;&gt;More control and capability over your editor&lt;/h3&gt;
&lt;p&gt;Starter kits unlock customizations that were simply not possible before: restructure how the editor initializes; inject custom logic between loading phases; defines layouts from the ground up; build workflows that are unique to your product; and more.&lt;/p&gt;
&lt;p&gt;The old configuration APIs drew a line between “customizable” and “not customizable.” Starter kits erase that line. &lt;strong&gt;If you can see it in the code, you can change it&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In simple terms, you can now adapt the editor to your product, instead of adapting your product to the editor, and this was one of our main drivers.&lt;/p&gt;
&lt;h3 id=&quot;opt-in-never-opt-out&quot;&gt;Opt in, never opt out&lt;/h3&gt;
&lt;p&gt;Until now, an SDK update could introduce visible changes to your editor, like a new toolbar button, a different menu option, a changed default, without you asking for it. Your release process had to account for UI changes that came from a dependency, not from your team.&lt;/p&gt;
&lt;p&gt;With CE.SDK &lt;code&gt;v1.73&lt;/code&gt;, that dynamic is reversed. SDK updates bring new features, engine improvements, performance gains, and bug fixes. But your editor UI stays exactly as you left it. New features and components become building blocks you adopt on your own schedule, documented, with examples, and ready when your implicit decide to add them. Nothing shows up in your product unless you put it there.&lt;/p&gt;
&lt;h3 id=&quot;two-paths-your-choice&quot;&gt;Two paths, your choice&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Start from a Starter Kit&lt;/strong&gt;&lt;br&gt;
Download the one that matches your use case, run it, and customize from there. Each kit is a proven, production-ready structure that handles the complexity of editor setup so you don’t have to figure it out from scratch. Most teams will take this path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build from scratch&lt;/strong&gt;&lt;br&gt;
If you have very specific requirements or prefer to architect everything yourself, the Editor view accepts raw configuration directly. The starter kits serve as comprehensive, living reference implementations. Even if you never use them directly, they show you exactly how every piece fits together.&lt;/p&gt;
&lt;h3 id=&quot;the-engine-you-rely-on-hasnt-changed&quot;&gt;The engine you rely on hasn’t changed&lt;/h3&gt;
&lt;p&gt;It’s worth saying clearly: the core of CE.SDK, the rendering engine, export pipeline, asset handling, performance characteristics, and everything that powers the creative experience is unchanged. We improved how you configure and integrate the editor, not what powers it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;the-tradeoff&quot;&gt;The Tradeoff&lt;/h2&gt;
&lt;p&gt;The old one-component integration was genuinely convenient for getting started. With starter kits, you have a small module in your project, a handful of well-organized files that you own and maintain.&lt;/p&gt;
&lt;p&gt;We believe this is the right tradeoff for any team building a real product. The moment you need to customize anything you’ll be able to clearly structured and to modify without limits.&lt;/p&gt;
&lt;p&gt;At its core, this change is about moving from implicit behavior to explicit control, and we believe that is the better long-term contract with our customers. Your editor should not change in meaningful ways unless you decide it should. Your upgrade path should be predictable. And your team should be able to understand the integration by reading its own code.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;We’ve written detailed migration guides that walk through every change with before-and-after examples. Each guide also links to the starter kit repositories for your platform:&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;iOS&lt;/th&gt;&lt;th&gt;Android&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Migration Guide&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/ios/to-v1-73-ab14fb/&quot;&gt;Upgrading to v1.73&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/android/to-v1-73-ab14fb/&quot;&gt;Upgrading to v1.73&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Photo Editor&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-photo-editor-ios&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-photo-editor-android&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Design Editor&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-design-editor-ios&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-design-editor-android&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Video Editor&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-video-editor-ios&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-video-editor-android&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Postcard Editor&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-postcard-editor-ios&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-postcard-editor-android&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Apparel Editor&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-apparel-editor-ios&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/imgly/starterkit-apparel-editor-android&quot;&gt;GitHub&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;We’re here to help with the transition. If you have questions, reach out to our support team or open an issue on the starter kit repositories.&lt;/p&gt;</content:encoded><dc:creator>João</dc:creator><media:content url="https://blog.img.ly/2026/04/starter-kits-mobile.jpg" medium="image"/><category>Starter Kits</category><category>CE.SDK</category></item><item><title>CE.SDK v1.69 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-69-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-69-0-release-notes/</guid><description>Agent Skills turns your AI coding assistant into a CE.SDK expert. Ship editors in minutes, not days. Plus Starter Kits, PPTX import, and video editor updates.</description><pubDate>Fri, 27 Feb 2026 18:29:53 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;v1.69 is the biggest developer experience release we’ve shipped.&lt;/strong&gt; &lt;em&gt;Agent Skills&lt;/em&gt; collapse the time from idea to working editor from days to under a minute. Production-ready &lt;em&gt;Starter Kits&lt;/em&gt; eliminate days of boilerplate setup. &lt;em&gt;PPTX and Canva Importer&lt;/em&gt; lets users bring their existing designs directly into your editor. And a comprehensive video overhaul across Web, iOS, and Android closes the gap between CE.SDK and native professional editing apps.&lt;/p&gt;
&lt;p&gt;Let’s dive in!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;introducing-imgly-agent-skills-for-cesdk&quot;&gt;Introducing IMG.LY Agent Skills for CE.SDK&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/agent-skill-design-editor-photo-editor-video-whitelabel-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The biggest change to CE.SDK’s developer experience since launch.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;AI agents have changed how developers build. With Agent &lt;em&gt;Skills&lt;/em&gt;, CE.SDK works natively with your AI agent.&lt;/p&gt;
&lt;p&gt;Install the plugin for Claude Code or Cursor and your AI coding agent becomes a CE.SDK expert with bundled access to guides, API references, and starter kits across 10 web frameworks. No external services, no MCP servers, no context-switching.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What your developers can now do:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/cesdk:build&lt;/code&gt;&lt;/strong&gt; — Describe a use case in plain language. The agent detects the framework, pulls the right starter kit, and scaffolds a working project autonomously.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/cesdk:explain&lt;/code&gt;&lt;/strong&gt; — Ask any CE.SDK implementation question and get answers adapted to the specific framework and experience level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/cesdk:docs-[framework]&lt;/code&gt;&lt;/strong&gt; — Retrieve guides and API references directly from the IDE, without leaving the editor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1776px) 1776px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1776&quot; height=&quot;1073&quot; src=&quot;https://img.ly/_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_Z2pLGsr.webp&quot; srcset=&quot;/_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_ZSgJxt.webp 640w, /_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_2mBBIp.webp 750w, /_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_7zDq3.webp 828w, /_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_1m1QkW.webp 1080w, /_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_1wOErv.webp 1280w, /_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_ZPvEli.webp 1668w, /_astro/build-photo-editor-video-editor-with-claude-codex-ai-chatgpt-1_Z2pLGsr.webp 1776w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For your product, this means:&lt;/strong&gt; developers prototype in minutes, not days. Non-technical team members can now build and extend functional editors independently. And onboarding new engineers to CE.SDK shrinks from a multi-day ramp to a single session.&lt;/p&gt;
&lt;p&gt;→ &lt;a href=&quot;https://img.ly/blog/img-ly-agent-skills-web/&quot;&gt;Quick Start &amp;#x26; Full Announcement&lt;/a&gt;&lt;br&gt;
→ &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/agent-skills-f7g8h9/?ref=img.ly&quot;&gt;Explore Agent Skills Documentation&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;launch-in-minutes-with-production-ready-starter-kits-for-web&quot;&gt;Launch in Minutes with Production-Ready Starter Kits for Web&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/starterkits-web-photo-editor-video-editor-design-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Previously, getting CE.SDK running in a real product meant adapting complex demo projects: stripping features, adjusting architecture, and undoing assumptions baked into example code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Starter Kits replace all of that with pre-configured, production-ready editor UIs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Specialized kits for Photo, Video, and Design editors are scoped, clean, and immediately deployable. Each kit starts with a focused feature set. You explicitly opt in to what you need, so your UI stays performant and your users don’t see capabilities they can’t use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For your product, this means:&lt;/strong&gt; a functional, shippable editor in minutes rather than days of setup. Clean architecture from day one, without accumulating technical debt.&lt;/p&gt;
&lt;p&gt;→ &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/vanilla-js/quickstart-yef23s/&quot;&gt;Explore Starter Kit Documentation&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;let-users-bring-their-pptx--canva-designs-to-cesdk&quot;&gt;Let Users Bring Their PPTX &amp;#x26; Canva Designs to CE.SDK&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/pptx-canva-importer-import-canva-designs.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Some customers don’t start from scratch. They have existing creative assets locked inside PowerPoint and Canva, and until now, bringing those into CE.SDK required manual recreation.&lt;/p&gt;
&lt;p&gt;The new PPTX Importer removes that barrier.&lt;/p&gt;
&lt;p&gt;Users can import native PowerPoint files or export &lt;strong&gt;Canva designs&lt;/strong&gt; as PPTX and bring them directly into your CE.SDK-powered editor, with layouts, elements, and structure intact.&lt;/p&gt;
&lt;p&gt;→ &lt;a href=&quot;https://img.ly/demos/pptx-template-import/web/&quot;&gt;Try the PPTX Import Demo&lt;/a&gt;&lt;br&gt;
→ &lt;a href=&quot;https://www.npmjs.com/package/@imgly/pptx-importer&quot;&gt;View PPTX npm&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;professional-grade-video-editing-across-platforms&quot;&gt;Professional-Grade Video Editing Across Platforms&lt;/h2&gt;
&lt;p&gt;This release expands CE.SDK’s video features across web &amp;#x26; mobile platforms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Control Video Speed (iOS &amp;#x26; Android)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/slow-speed-on-reel-tiktok-videos-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Users can now adjust the playback speed of video and audio clips via a dedicated Speed UI. This has been one of the most-requested mobile features and is now available on both platforms.&lt;br&gt;
→ &lt;a href=&quot;https://img.ly/docs/cesdk/ios/create-video/control-daba54/#playback-speed&quot;&gt;View Video Speed Documentation iOS&lt;/a&gt;&lt;br&gt;
→ &lt;a href=&quot;https://img.ly/docs/cesdk/android/create-video/control-daba54/#playback-speed&quot;&gt;View Video Speed Documentation Android&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create Video Groups in the Timeline (Web)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/group-timeline-tracks.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Multiple clips can now be combined into a single manageable unit with synchronized timing, trimming, and a unified timeline representation.&lt;/p&gt;
&lt;p&gt;This enables complex, multi-layer content production and speeds up the design process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Video Timeline Now Grows Automatically (Web)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/growing-timeline.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;The timeline now automatically adjusts its height based on content. Manual track configuration is gone, and complex projects are easier to pick up for your new users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use a Clutter-Free iOS Timeline (iOS)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1480px) 1480px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1480&quot; height=&quot;643&quot; src=&quot;https://img.ly/_astro/cleaner-timeline-ios_Z25tajS.webp&quot; srcset=&quot;/_astro/cleaner-timeline-ios_Z1hQmLR.webp 640w, /_astro/cleaner-timeline-ios_2nXdsr.webp 750w, /_astro/cleaner-timeline-ios_jkXE4.webp 828w, /_astro/cleaner-timeline-ios_2in6s2.webp 1080w, /_astro/cleaner-timeline-ios_6rsyz.webp 1280w, /_astro/cleaner-timeline-ios_Z25tajS.webp 1480w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Non-video tracks now show a single thumbnail per clip, reducing clutter in multi-layer timelines on your iOS app.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;Full Changelog&lt;/h2&gt;
&lt;p&gt;See all technical details, breaking changes, and performance improvements in the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/v1-69-0/&quot;&gt;v1.69.0 Changelog.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thank you for building with IMG.LY.&lt;/em&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2026/02/creative-editor-sdk-v169-imgly-whitelabel-design-editor-video-editor-react.jpg" medium="image"/><category>Release Notes</category><category>CE.SDK</category><category>Agent Skills</category><category>Agentic Development</category><category>AI</category><category>Starter Kits</category></item><item><title>Building a CapCut-Like Video Editor with CE.SDK and AI</title><link>https://img.ly/blog/capcut-like-video-editor-web-react/</link><guid isPermaLink="true">https://img.ly/blog/capcut-like-video-editor-web-react/</guid><description>How to built a browser-based video editor with a dark CapCut-inspired UI, multi-track timeline, and AI-powered content generation... in under 200 lines of code.</description><pubDate>Thu, 26 Feb 2026 22:50:34 GMT</pubDate><content:encoded>&lt;h3 id=&quot;build-this-with-ai-in-minutes&quot;&gt;&lt;strong&gt;Build this with AI in minutes&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;This tutorial is a great way to understand how CE.SDK works under the hood. But if you just want to get to the result, you can build this entire editor using &lt;a href=&quot;https://img.ly/docs/cesdk/react/get-started/agent-skills-f7g8h9/&quot;&gt;IMG.LY Agent Skills&lt;/a&gt;, no manual setup required.&lt;/p&gt;
&lt;p&gt;Install the skills, then run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/cesdk:build Build a CapCut-like video editor with a dark theme, multi-track timeline, AI video/image/audio generation, background removal, and MP4 export.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Want to understand a specific concept in depth? Use &lt;code&gt;/cesdk:explain&lt;/code&gt;, for example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/cesdk:explain How does the video timeline and block hierarchy work?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;CapCut has set the standard for accessible video editing. Its dark UI, intuitive timeline, and AI-powered features make it feel like a professional tool that anyone can use. But what if you could build something similar embedded directly in your own web application in minutes? Yes, minutes!&lt;/p&gt;
&lt;p&gt;In this tutorial, we’ll walk through how we built a CapCut-like video editor using &lt;a href=&quot;https://img.ly&quot;&gt;IMG.LY’s CreativeEditor SDK (CE.SDK)&lt;/a&gt; for React. The finished editor includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;multi-track timeline&lt;/strong&gt; for video, audio, text, and &lt;a href=&quot;https://img.ly/demos/video-captions/web/&quot;&gt;captions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trim, split, and join&lt;/strong&gt; operations on video clips&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;CapCut-inspired dark theme&lt;/strong&gt; built with CSS custom properties&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI video generation&lt;/strong&gt; (text-to-video, image-to-video) via Minimax, Kling, and Pixverse&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI image generation&lt;/strong&gt; (text-to-image, image editing) via RecraftV3, IdeogramV3, and GPT Image&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI audio generation&lt;/strong&gt; (text-to-speech, sound effects) via ElevenLabs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI text generation&lt;/strong&gt; (copywriting, translation) via Anthropic Claude&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Background removal&lt;/strong&gt; — client-side, powered by WebAssembly/WebGPU&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MP4 export&lt;/strong&gt; directly from the browser&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The entire editor is a single React component with roughly 180 lines of JavaScript and 100 lines of CSS.&lt;/p&gt;
&lt;h2 id=&quot;architecture-overview&quot;&gt;Architecture Overview&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&quot;App architecture&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 2000px) 2000px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;2000&quot; height=&quot;1969&quot; src=&quot;https://img.ly/_astro/Gemini_Generated_Image_6celpb6celpb6cel_4npMe.webp&quot; srcset=&quot;/_astro/Gemini_Generated_Image_6celpb6celpb6cel_Z2pUzxd.webp 640w, /_astro/Gemini_Generated_Image_6celpb6celpb6cel_1I72rW.webp 750w, /_astro/Gemini_Generated_Image_6celpb6celpb6cel_1YwWvd.webp 828w, /_astro/Gemini_Generated_Image_6celpb6celpb6cel_cWEce.webp 1080w, /_astro/Gemini_Generated_Image_6celpb6celpb6cel_22mCvu.webp 1280w, /_astro/Gemini_Generated_Image_6celpb6celpb6cel_Z1OLGCT.webp 1668w, /_astro/Gemini_Generated_Image_6celpb6celpb6cel_4npMe.webp 2000w&quot;&gt;&lt;/p&gt;
&lt;p&gt;CE.SDK has two main layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CreativeEngine:&lt;/strong&gt; The headless core that manages scenes, blocks, assets, and rendering. It handles the video timeline, playback, and export entirely client-side.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CreativeEditor UI:&lt;/strong&gt; A pre-built, customizable UI layer that wraps the engine with a dock, inspector, timeline, canvas, and navigation bar.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Plugins extend both layers. The &lt;code&gt;AiApps&lt;/code&gt; plugin, for example, registers AI providers with the engine and injects UI components (dock buttons, canvas menu items, generation panels) into the editor.&lt;/p&gt;
&lt;h2 id=&quot;step-1-project-setup&quot;&gt;Step 1: Project Setup&lt;/h2&gt;
&lt;p&gt;We scaffolded a React project with Vite and installed CE.SDK alongside the AI plugin packages:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; vite@latest&lt;/span&gt;&lt;span&gt; capcut-like-editor&lt;/span&gt;&lt;span&gt; --&lt;/span&gt;&lt;span&gt; --template&lt;/span&gt;&lt;span&gt; react&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; capcut-like-editor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Core SDK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @cesdk/cesdk-js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# AI plugins&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @imgly/plugin-ai-apps-web&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @imgly/plugin-ai-video-generation-web&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @imgly/plugin-ai-image-generation-web&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @imgly/plugin-ai-audio-generation-web&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @imgly/plugin-ai-text-generation-web&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Background removal (runs locally via WASM/WebGPU)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @imgly/plugin-background-removal-web&lt;/span&gt;&lt;span&gt; onnxruntime-web@1.21.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;why-so-many-packages&quot;&gt;Why so many packages?&lt;/h3&gt;
&lt;p&gt;CE.SDK follows a modular plugin architecture. Each AI capability is a separate package with its own provider modules. This means you only bundle what you use if you don’t need audio generation, don’t install &lt;code&gt;@imgly/plugin-ai-audio-generation-web&lt;/code&gt;. The &lt;code&gt;@imgly/plugin-ai-apps-web&lt;/code&gt; package is the unifying layer that brings them all together into a single dock panel.&lt;/p&gt;
&lt;h2 id=&quot;step-2-the-react-component&quot;&gt;Step 2: The React Component&lt;/h2&gt;
&lt;p&gt;CE.SDK provides a first-class React wrapper via &lt;code&gt;@cesdk/cesdk-js/react&lt;/code&gt;. The &lt;code&gt;&amp;#x3C;CreativeEditor&gt;&lt;/code&gt; component handles mounting, initialization, and cleanup:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEditor &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@cesdk/cesdk-js/react&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // license: &apos;YOUR_CESDK_LICENSE_KEY&apos;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; init&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;cesdk&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // All setup happens here — theme, assets, plugins, UI customization&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; VideoEditor&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;CreativeEditor&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{config} &lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{init} &lt;/span&gt;&lt;span&gt;width&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;100vw&quot;&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;100vh&quot;&lt;/span&gt;&lt;span&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;config&lt;/code&gt; object is passed to the engine at creation time. The &lt;code&gt;init&lt;/code&gt; callback fires once the &lt;code&gt;cesdk&lt;/code&gt; instance is ready. This is where all our customization lives.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pitfall: Silent init errors.&lt;/strong&gt; The &lt;code&gt;&amp;#x3C;CreativeEditor&gt;&lt;/code&gt; component swallows errors thrown inside &lt;code&gt;init&lt;/code&gt;. If something fails, the editor loads but appears broken with no console output. Always wrap &lt;code&gt;init&lt;/code&gt; in a &lt;code&gt;try/catch&lt;/code&gt;:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;step-3-creating-the-video-scene&quot;&gt;Step 3: Creating the Video Scene&lt;/h2&gt;
&lt;p&gt;A video editor needs three things at startup: asset sources, a video scene, and a timeline.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Load built-in asset libraries (stickers, shapes, filters, typefaces, etc.)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; cesdk.&lt;/span&gt;&lt;span&gt;addDefaultAssetSources&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Load demo content (sample videos, images, audio) + enable upload slots&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; cesdk.&lt;/span&gt;&lt;span&gt;addDemoAssetSources&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  sceneMode: &lt;/span&gt;&lt;span&gt;&apos;Video&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  withUploadAssetSources: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Create a video scene with timeline&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; cesdk.&lt;/span&gt;&lt;span&gt;createVideoScene&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;createVideoScene()&lt;/code&gt; sets up the scene hierarchy that powers the timeline:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; └── Page (represents the video canvas — 1920x1080 by default)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ├── Track (video track — holds video clips in sequence)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ├── Track (overlay track — text, stickers, images)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ├── CaptionTrack (subtitles synced to playback)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      └── Audio (background music, voiceover, sound effects)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each element on the timeline is a &lt;strong&gt;block&lt;/strong&gt; with timing properties: &lt;code&gt;timeOffset&lt;/code&gt; (when it appears) and &lt;code&gt;duration&lt;/code&gt; (how long it plays). The engine handles rendering each frame, compositing layers, and synchronizing audio.&lt;/p&gt;
&lt;h3 id=&quot;browser-support&quot;&gt;Browser support&lt;/h3&gt;
&lt;p&gt;Video editing relies on modern web codecs (WebCodecs API), which are available in Chromium-based browsers (Chrome, Edge, Brave). Safari and Firefox support is limited.&lt;/p&gt;
&lt;h2 id=&quot;step-4-the-capcut-dark-theme&quot;&gt;Step 4: The CapCut Dark Theme&lt;/h2&gt;
&lt;p&gt;CapCut’s visual identity is defined by its deep charcoal backgrounds, teal accent colors, and subtle elevation layers. CE.SDK’s theming system maps perfectly to this through CSS custom properties.&lt;/p&gt;
&lt;h3 id=&quot;setting-the-base-theme&quot;&gt;Setting the base theme&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cesdk.ui.&lt;/span&gt;&lt;span&gt;setTheme&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;dark&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This activates CE.SDK’s built-in dark theme. But we want to go further. We need CapCut’s specific color palette.&lt;/p&gt;
&lt;h3 id=&quot;custom-css-overrides&quot;&gt;Custom CSS overrides&lt;/h3&gt;
&lt;p&gt;CE.SDK scopes all its UI under &lt;code&gt;.ubq-public&lt;/code&gt; with &lt;code&gt;data-ubq-theme&lt;/code&gt; and &lt;code&gt;data-ubq-scale&lt;/code&gt; attributes. We override the CSS custom properties to inject our palette:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.ubq-public&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;data-ubq-theme&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;dark&apos;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;data-ubq-scale&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;normal&apos;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.ubq-public&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;data-ubq-theme&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;dark&apos;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;data-ubq-scale&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;modern&apos;&lt;/span&gt;&lt;span&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  /* Deep charcoal backgrounds — darker than CE.SDK&apos;s default dark */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-canvas&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;220&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;15&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-elevation-1&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;220&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;13&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;12&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-elevation-2&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;220&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;12&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;15&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-elevation-3&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;220&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;18&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  /* High-contrast white text */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-foreground-default&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsla&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0.92&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-foreground-light&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsla&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0.55&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  /* CapCut&apos;s signature teal/cyan accent */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-interactive-accent-default&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;190&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;85&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;48&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-interactive-accent-hover&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;190&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;85&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-interactive-accent-pressed&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;190&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;85&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;36&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  /* Subtle borders — barely visible, like CapCut */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --ubq-border-default&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;hsla&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0.08&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The key design decisions:&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Property&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;th&gt;Why&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--ubq-canvas&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;hsl(220, 15%, 8%)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Near-black with a slight blue tint — matches CapCut’s canvas area&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--ubq-elevation-1/2/3&lt;/code&gt;&lt;/td&gt;&lt;td&gt;12% → 15% → 18% lightness&lt;/td&gt;&lt;td&gt;Subtle elevation steps create depth without harsh contrast&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--ubq-interactive-accent-*&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;hsl(190, 85%, 48%)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;CapCut’s teal — used for buttons, selections, and progress bars&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--ubq-border-default&lt;/code&gt;&lt;/td&gt;&lt;td&gt;8% opacity white&lt;/td&gt;&lt;td&gt;Nearly invisible borders that only appear on close inspection&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;responsive-scale&quot;&gt;Responsive scale&lt;/h3&gt;
&lt;p&gt;We also configure responsive scaling so the editor adapts to touch devices:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cesdk.ui.&lt;/span&gt;&lt;span&gt;setScale&lt;/span&gt;&lt;span&gt;(({ &lt;/span&gt;&lt;span&gt;containerWidth&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;isTouch&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; ((containerWidth &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; containerWidth &lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt; 768&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; isTouch) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; &apos;large&apos;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;// Bigger touch targets on small/touch screens&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; &apos;normal&apos;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;// Standard desktop sizing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-5-ai-plugin-integration&quot;&gt;Step 5: AI Plugin Integration&lt;/h2&gt;
&lt;p&gt;This is where the editor transforms from a basic video tool into something that feels like CapCut’s AI-powered experience. CE.SDK’s plugin system lets us add all AI capabilities through a single unified &lt;code&gt;AiApps&lt;/code&gt; plugin.&lt;/p&gt;
&lt;h3 id=&quot;the-unified-aiapps-approach&quot;&gt;The unified AiApps approach&lt;/h3&gt;
&lt;p&gt;Instead of registering each AI plugin separately, &lt;code&gt;@imgly/plugin-ai-apps-web&lt;/code&gt; provides a single entry point:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; AiApps &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-ai-apps-web&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; FalAiVideo &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-ai-video-generation-web/fal-ai&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; FalAiImage &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-ai-image-generation-web/fal-ai&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; OpenAiImage &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-ai-image-generation-web/open-ai&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Elevenlabs &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-ai-audio-generation-web/elevenlabs&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Anthropic &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-ai-text-generation-web/anthropic&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; cesdk.&lt;/span&gt;&lt;span&gt;addPlugin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  AiApps&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    dryRun: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// Simulate for development — no API calls&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    providers: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      text2text: Anthropic.&lt;/span&gt;&lt;span&gt;AnthropicProvider&lt;/span&gt;&lt;span&gt;({ proxyUrl: &lt;/span&gt;&lt;span&gt;PROXY_URL&lt;/span&gt;&lt;span&gt; }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      text2image: [FalAiImage.&lt;/span&gt;&lt;span&gt;RecraftV3&lt;/span&gt;&lt;span&gt;({ proxyUrl }) &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      image2image: [FalAiImage.&lt;/span&gt;&lt;span&gt;GeminiFlashEdit&lt;/span&gt;&lt;span&gt;({ proxyUrl }) &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      text2video: [FalAiVideo.&lt;/span&gt;&lt;span&gt;MinimaxVideo01Live&lt;/span&gt;&lt;span&gt;({ proxyUrl }) &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      image2video: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        FalAiVideo.&lt;/span&gt;&lt;span&gt;MinimaxVideo01LiveImageToVideo&lt;/span&gt;&lt;span&gt;({ proxyUrl }) &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      text2speech: Elevenlabs.&lt;/span&gt;&lt;span&gt;ElevenMultilingualV2&lt;/span&gt;&lt;span&gt;({ proxyUrl }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      text2sound: Elevenlabs.&lt;/span&gt;&lt;span&gt;ElevenSoundEffects&lt;/span&gt;&lt;span&gt;({ proxyUrl }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;provider-categories-explained&quot;&gt;Provider categories explained&lt;/h3&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Category&lt;/th&gt;&lt;th&gt;What it does&lt;/th&gt;&lt;th&gt;Models we configured&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;text2text&lt;/code&gt;&lt;/td&gt;&lt;td&gt;AI copywriting — improve text, translate, change tone&lt;/td&gt;&lt;td&gt;Anthropic Claude&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;text2image&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Generate images from text prompts&lt;/td&gt;&lt;td&gt;RecraftV3, IdeogramV3, GPT Image&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;image2image&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Transform existing images with AI&lt;/td&gt;&lt;td&gt;Gemini Flash Edit, GPT Image&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;text2video&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Generate video clips from text descriptions&lt;/td&gt;&lt;td&gt;Minimax Video, Kling Video, Pixverse&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;image2video&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Animate a static image into video&lt;/td&gt;&lt;td&gt;Minimax Video, Kling Video&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;text2speech&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Convert text to spoken audio with voice selection&lt;/td&gt;&lt;td&gt;ElevenLabs Multilingual V2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;text2sound&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Generate sound effects from text&lt;/td&gt;&lt;td&gt;ElevenLabs Sound Effects&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;When multiple providers are configured in an array (like &lt;code&gt;text2image&lt;/code&gt;), the UI automatically shows a provider/model selection dropdown so users can choose which AI model to use.&lt;/p&gt;
&lt;h3 id=&quot;the-proxy-server-requirement&quot;&gt;The proxy server requirement&lt;/h3&gt;
&lt;p&gt;Every provider takes a &lt;code&gt;proxyUrl&lt;/code&gt; parameter. This is critical for production:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Browser  →  Your Proxy Server  →  AI Provider (fal.ai, ElevenLabs, etc.)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                ↑&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          Injects API keys&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          server-side&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your API keys should never be in client-side code. The proxy server receives requests from CE.SDK, attaches your API key, and forwards to the AI provider. During development, &lt;code&gt;dryRun: true&lt;/code&gt; simulates generation without any API calls.&lt;/p&gt;
&lt;h3 id=&quot;background-removal&quot;&gt;Background removal&lt;/h3&gt;
&lt;p&gt;Background removal is a separate plugin because it runs entirely client-side, no proxy needed:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; BackgroundRemovalPlugin &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@imgly/plugin-background-removal-web&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; cesdk.&lt;/span&gt;&lt;span&gt;addPlugin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  BackgroundRemovalPlugin&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ui: { locations: [&lt;/span&gt;&lt;span&gt;&apos;canvasMenu&apos;&lt;/span&gt;&lt;span&gt;] },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This uses ONNX Runtime (WebAssembly + WebGPU) to run an AI segmentation model directly in the browser. The first run downloads ~40MB of model weights, which are then cached. Select any image on the canvas and click “Remove Background” in the context menu.&lt;/p&gt;
&lt;h2 id=&quot;step-6-ui-customization-with-the-component-order-api&quot;&gt;Step 6: UI Customization with the Component Order API&lt;/h2&gt;
&lt;p&gt;CE.SDK’s UI is built from five customizable areas: &lt;strong&gt;Dock&lt;/strong&gt;, &lt;strong&gt;Inspector Bar&lt;/strong&gt;, &lt;strong&gt;Canvas Menu&lt;/strong&gt;, &lt;strong&gt;Navigation Bar&lt;/strong&gt;, and &lt;strong&gt;Canvas Bar&lt;/strong&gt;. The Component Order API lets us insert, remove, and reorder components in each area.&lt;/p&gt;
&lt;h3 id=&quot;adding-the-ai-button-to-the-dock&quot;&gt;Adding the AI button to the dock&lt;/h3&gt;
&lt;p&gt;We want the AI Apps button to be the first thing users see in the dock:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cesdk.ui.&lt;/span&gt;&lt;span&gt;insertOrderComponent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  { in: &lt;/span&gt;&lt;span&gt;&apos;ly.img.dock&apos;&lt;/span&gt;&lt;span&gt;, position: &lt;/span&gt;&lt;span&gt;&apos;start&apos;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;ly.img.ai.apps.dock&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;insertOrderComponent&lt;/code&gt; takes a location specifier and the component(s) to insert. &lt;code&gt;position: &apos;start&apos;&lt;/code&gt; puts it at the top of the dock. Alternative positions include &lt;code&gt;&apos;end&apos;&lt;/code&gt;, a numeric index, or relative placement with &lt;code&gt;before&lt;/code&gt;/&lt;code&gt;after&lt;/code&gt; matchers.&lt;/p&gt;
&lt;h3 id=&quot;ai-options-in-the-canvas-context-menu&quot;&gt;AI options in the canvas context menu&lt;/h3&gt;
&lt;p&gt;When a user selects a text or image block and right-clicks, we want AI options available:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cesdk.ui.&lt;/span&gt;&lt;span&gt;insertOrderComponent&lt;/span&gt;&lt;span&gt;({ in: &lt;/span&gt;&lt;span&gt;&apos;ly.img.canvas.menu&apos;&lt;/span&gt;&lt;span&gt;, position: &lt;/span&gt;&lt;span&gt;&apos;start&apos;&lt;/span&gt;&lt;span&gt; }, [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;ly.img.ai.text.canvasMenu&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;ly.img.ai.image.canvasMenu&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Passing an array inserts multiple components at once.&lt;/p&gt;
&lt;h3 id=&quot;custom-export-button-in-the-navigation-bar&quot;&gt;Custom export button in the navigation bar&lt;/h3&gt;
&lt;p&gt;We add an Export button with a real click handler that triggers MP4 export:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cesdk.ui.&lt;/span&gt;&lt;span&gt;insertOrderComponent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  { in: &lt;/span&gt;&lt;span&gt;&apos;ly.img.navigation.bar&apos;&lt;/span&gt;&lt;span&gt;, position: &lt;/span&gt;&lt;span&gt;&apos;end&apos;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    id: &lt;/span&gt;&lt;span&gt;&apos;ly.img.action.navigationBar&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    key: &lt;/span&gt;&lt;span&gt;&apos;export&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    label: &lt;/span&gt;&lt;span&gt;&apos;Export&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    icon: &lt;/span&gt;&lt;span&gt;&apos;@imgly/Download&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    onClick&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      const&lt;/span&gt;&lt;span&gt; engine&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; cesdk.engine;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      const&lt;/span&gt;&lt;span&gt; page&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;findByType&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;page&apos;&lt;/span&gt;&lt;span&gt;)[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (page) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        const&lt;/span&gt;&lt;span&gt; blob&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;exportVideo&lt;/span&gt;&lt;span&gt;(page, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          mimeType: &lt;/span&gt;&lt;span&gt;&apos;video/mp4&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        const&lt;/span&gt;&lt;span&gt; url&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; URL&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createObjectURL&lt;/span&gt;&lt;span&gt;(blob);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        const&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;a&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        a.href &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; url;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        a.download &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;video.mp4&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        a.&lt;/span&gt;&lt;span&gt;click&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        URL&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;revokeObjectURL&lt;/span&gt;&lt;span&gt;(url);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;exportVideo&lt;/code&gt; method renders every frame of the timeline (compositing video tracks, overlays, text, captions, and audio) into an MP4 blob entirely in the browser.&lt;/p&gt;
&lt;h2 id=&quot;step-7-wiring-generated-audio-into-the-asset-library&quot;&gt;Step 7: Wiring Generated Audio into the Asset Library&lt;/h2&gt;
&lt;p&gt;AI-generated audio (speech and sound effects) is stored in provider-specific history sources. To make this audio browsable alongside regular audio assets, we inject the history source into the audio asset library entry:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; audioEntry&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; cesdk.ui.&lt;/span&gt;&lt;span&gt;getAssetLibraryEntry&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;ly.img.audio&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (audioEntry &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; existingSourceIds&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; Array.&lt;/span&gt;&lt;span&gt;isArray&lt;/span&gt;&lt;span&gt;(audioEntry.sourceIds)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ?&lt;/span&gt;&lt;span&gt; audioEntry.sourceIds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    :&lt;/span&gt;&lt;span&gt; audioEntry.&lt;/span&gt;&lt;span&gt;sourceIds&lt;/span&gt;&lt;span&gt;({});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  cesdk.ui.&lt;/span&gt;&lt;span&gt;updateAssetLibraryEntry&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;ly.img.audio&apos;&lt;/span&gt;&lt;span&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    sourceIds: [&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;existingSourceIds, &lt;/span&gt;&lt;span&gt;&apos;ly.img.ai.audio-generation.history&apos;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when users open the Audio panel in the dock, they’ll see their AI-generated audio alongside the sample library.&lt;/p&gt;
&lt;h2 id=&quot;step-8-custom-labels-with-i18n&quot;&gt;Step 8: Custom Labels with i18n&lt;/h2&gt;
&lt;p&gt;CE.SDK’s i18n system lets us customize any UI string. We used it to make the AI prompt fields more inviting:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cesdk.i18n.&lt;/span&gt;&lt;span&gt;setTranslations&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  en: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &apos;ly.img.plugin-ai-video-generation-web.fal-ai/minimax/video-01-live.property.prompt&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &apos;Describe your video...&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &apos;ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.property.prompt&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &apos;Describe your image...&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Translation keys follow the pattern &lt;code&gt;{plugin-id}.{provider-id}.property.{field}&lt;/code&gt;. You can also add multi-language support by including keys for &lt;code&gt;de&lt;/code&gt;, &lt;code&gt;fr&lt;/code&gt;, &lt;code&gt;es&lt;/code&gt;, etc.&lt;/p&gt;
&lt;h2 id=&quot;the-complete-file-structure&quot;&gt;The Complete File Structure&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;capcut-like-editor/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── src/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── App.jsx              # Root — imports VideoEditor + theme CSS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── VideoEditor.jsx      # The entire editor (single component, ~180 lines)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── capcut-theme.css     # CapCut dark theme overrides (~100 lines)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── index.css            # Global reset (margin/padding/overflow)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── main.jsx             # React entry point&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── index.html&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── package.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└── vite.config.js&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it. The entire CapCut-like editor is three files: one React component, one CSS file, and a thin App wrapper.&lt;/p&gt;
&lt;h2 id=&quot;what-we-get-out-of-the-box&quot;&gt;What We Get Out of the Box&lt;/h2&gt;
&lt;p&gt;Because CE.SDK’s video UI is pre-built, we didn’t write any code for these features. They come from &lt;code&gt;createVideoScene()&lt;/code&gt; and the default UI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multi-track timeline&lt;/strong&gt; with drag-to-reorder, drag-to-resize&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trim and split&lt;/strong&gt; — drag clip edges or use the split tool&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Join and arrange&lt;/strong&gt; — drag clips between tracks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transform&lt;/strong&gt; — crop, flip, rotate via the inspector&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Playback controls&lt;/strong&gt; — play, pause, seek, scrub&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text overlays&lt;/strong&gt; — add styled text with the text tool&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stickers and graphics&lt;/strong&gt; — from the asset library&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filters and effects&lt;/strong&gt; — LUT-based color grading&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Undo/redo&lt;/strong&gt; — full history stack&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zoom and pan&lt;/strong&gt; — standard canvas navigation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The AI plugins add their own UI components (dock buttons, generation panels, context menu items) through the plugin system. We just positioned them where we wanted.&lt;/p&gt;
&lt;h2 id=&quot;going-to-production&quot;&gt;Going to Production&lt;/h2&gt;
&lt;p&gt;To take this from a prototype to production, you need three things:&lt;/p&gt;
&lt;h3 id=&quot;1-license-key&quot;&gt;1. License key&lt;/h3&gt;
&lt;p&gt;Get a free trial key at &lt;a href=&quot;https://img.ly/forms/contact-sales/&quot;&gt;https://img.ly/forms/contact-sales/&lt;/a&gt; and set it in the config (yes, if you want to ship to production you’ll have to talk to our lovely colleagues in sales):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  license: &lt;/span&gt;&lt;span&gt;&apos;YOUR_CESDK_LICENSE_KEY&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-proxy-server&quot;&gt;2. Proxy server&lt;/h3&gt;
&lt;p&gt;Set up a server that forwards AI requests with your API keys:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; PROXY_URL&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &apos;https://your-server.com/api/ai-proxy&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See the &lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/ai-integration/proxy-server-61f901/&quot;&gt;CE.SDK Proxy Server guide&lt;/a&gt; for Express.js and other server examples.&lt;/p&gt;
&lt;h3 id=&quot;3-disable-dry-run&quot;&gt;3. Disable dry run&lt;/h3&gt;
&lt;p&gt;Remove &lt;code&gt;dryRun: true&lt;/code&gt; from the AiApps configuration to enable real AI generation.&lt;/p&gt;
&lt;h2 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CE.SDK does the heavy lifting.&lt;/strong&gt; The timeline, playback, rendering, and export are all handled by the engine. We wrote zero video processing code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The plugin system is powerful.&lt;/strong&gt; Six AI capabilities were added with a single &lt;code&gt;addPlugin(AiApps({ ... }))&lt;/code&gt; call. Background removal was one more call.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSS custom properties make theming painless.&lt;/strong&gt; We matched CapCut’s aesthetic by overriding ~25 CSS variables. No forking, no patching.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Component Order API is the customization backbone.&lt;/strong&gt; &lt;code&gt;insertOrderComponent&lt;/code&gt; with position-based placement is the cleanest pattern for adding UI elements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wrap &lt;code&gt;init&lt;/code&gt; in try/catch.&lt;/strong&gt; CE.SDK’s &lt;code&gt;&amp;#x3C;CreativeEditor&gt;&lt;/code&gt; swallows errors silently. This is the single most important debugging tip.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pin your package versions.&lt;/strong&gt; All &lt;code&gt;@imgly/*&lt;/code&gt; plugins must match the &lt;code&gt;@cesdk/cesdk-js&lt;/code&gt; version exactly. A version mismatch (like 1.68 vs 1.69) will cause peer dependency conflicts.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/react/starterkits/video-editor-e1nlor/&quot;&gt;CE.SDK Video Editor Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/ai-integration/integrate-8e906c/&quot;&gt;AI Integration Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/appearance/theming-4b0938/&quot;&gt;Theming Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/customization/quick-start/reorder-components-f6g7h8/&quot;&gt;Rearrange Buttons (Component Order API)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/demos/video-ui/web/&quot;&gt;Video Editor Web Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/imgly/cesdk-web-examples&quot;&gt;GitHub Examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><dc:creator>Jan</dc:creator><media:content url="https://blog.img.ly/2026/02/blogcover.png" medium="image"/><category>React</category><category>Video Editor</category><category>CE.SDK</category></item><item><title>Introducing IMG.LY Agent Skills</title><link>https://img.ly/blog/img-ly-agent-skills-web/</link><guid isPermaLink="true">https://img.ly/blog/img-ly-agent-skills-web/</guid><description>Inject CE.SDK expertise into your IDE with Agent Skills, turning AI assistants into autonomous implementation partners, building editors in minutes.</description><pubDate>Mon, 16 Feb 2026 18:54:06 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;
We are moving beyond static documentation. &lt;em&gt;IMG.LY Agent Skills&lt;/em&gt; is a specialized intelligence layer that transforms AI coding assistants (Claude Code, Cursor, Windsurf) into CE.SDK implementation experts. Instead of mapping APIs manually, you now inject our full SDK expertise directly into your IDE and coding agent.&lt;/p&gt;
&lt;p&gt;→ &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/agent-skills-f7g8h9/&quot;&gt;Explore Agent Skill Documentation&lt;/a&gt;&lt;br&gt;
→ &lt;a href=&quot;https://github.com/imgly/agent-skills&quot;&gt;Access Agent Skills GitHub Repository&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-quick-start-paradox&quot;&gt;The “Quick Start” Paradox&lt;/h2&gt;
&lt;p&gt;In our recent analysis of client integrations, a consistent pattern emerged: even with a high-performance SDK, the “Time to First Edit” is often delayed by research. Developers spend a significant portion of their initial integration time context-switching between their IDE and documentation, manually mapping complex API hierarchies to their specific framework.&lt;/p&gt;
&lt;p&gt;We figured: You don’t just need better documentation; you need an &lt;strong&gt;expert partner&lt;/strong&gt; who is already inside your codebase.&lt;/p&gt;
&lt;h2 id=&quot;the-solution-imgly-agent-skills-for-web&quot;&gt;The Solution: IMG.LY Agent Skills for Web&lt;/h2&gt;
&lt;p&gt;We are moving beyond static documentation. Today, we are launching &lt;strong&gt;IMG.LY Agent Skills&lt;/strong&gt;, a specialized intelligence layer that transforms AI coding assistants like Claude Code, Cursor, and Gemini into CE.SDK implementation experts.&lt;/p&gt;
&lt;p&gt;Instead of searching for answers, you now give your agent our complete SDK knowledge with a single command.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works-your-autonomous-implementation-partner&quot;&gt;How It Works: Your Autonomous Implementation Partner&lt;/h2&gt;
&lt;p&gt;By injecting versioned, live documentation and framework-specific starter kits directly into your agent’s context window, we’ve created three adaptive paths to launch:&lt;/p&gt;
&lt;h3 id=&quot;1-the-explain-path&quot;&gt;1. The Explain Path&lt;/h3&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/0-explain-skill.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Architecture is complex. The Explain Skill acts as a digital implementation partner that adapts to you. It can provide a technical deep-dive on the export pipeline for a Senior Dev or a high-level summary for a Product Manager, in any language and at any level of detail.&lt;/p&gt;
&lt;h3 id=&quot;2-the-build-path&quot;&gt;&lt;strong&gt;2. The Build Path&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;video src=&quot;https://blog.img.ly/2026/02/1-build-skill.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Command your agent to “Add a photo editor to my React app.” The agent autonomously detects your environment, pulls the correct starter kit, and handles the boilerplate. It doesn’t just show you code; it builds the foundation for you.&lt;/p&gt;
&lt;h3 id=&quot;3-the-docs-path&quot;&gt;&lt;strong&gt;3. The Docs Path&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Stop the tab-switching. Your agent retrieves versioned API references offline, keeping your focus entirely within the terminal or IDE.&lt;/p&gt;
&lt;h2 id=&quot;the-shift-to-autonomous-engineering&quot;&gt;The Shift to Autonomous Engineering&lt;/h2&gt;
&lt;p&gt;This release marks a strategic shift for IMG.LY. We believe the next era of software development isn’t about “better documentation,” but about &lt;strong&gt;Portable Expertise&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;By providing that AI with a “skill” rather than a manual, we are empowering teams to move from a multi-month build cycle to a 30-second scaffold.&lt;/p&gt;
&lt;h2 id=&quot;supported-frameworks&quot;&gt;Supported Frameworks&lt;/h2&gt;
&lt;p&gt;The initial Web release supports 10 frameworks out of the box:&lt;br&gt;
&lt;strong&gt;React · Vue.js · Svelte · Angular · Next.js · Nuxt.js · SvelteKit · Electron · Node.js · Vanilla JS&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;get-started&quot;&gt;Get Started&lt;/h2&gt;
&lt;p&gt;Run the command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npx&lt;/span&gt;&lt;span&gt; skills&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span&gt; imgly/agent-skills&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;For example&lt;/em&gt;, &lt;strong&gt;Claude Code&lt;/strong&gt; users, can run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;claude&lt;/span&gt;&lt;span&gt; plugin&lt;/span&gt;&lt;span&gt; marketplace&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span&gt; imgly/agent-skills&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;claude&lt;/span&gt;&lt;span&gt; plugin&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; cesdk@imgly&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;→ &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/agent-skills-f7g8h9/&quot;&gt;Explore the full Agent Skill Documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The “editor of your dreams” is now a conversation away.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Join 3,000+ creative professionals who get early access to new features and updates.&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;Subscribe&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2026/02/Build-Design-Video-Photo-Editor-With-AI-Agent-sdk-imgly-2.jpg" medium="image"/><category>AI</category><category>CE.SDK</category></item><item><title>From Prompt to Editor: Running CE.SDK Inside ChatGPT with the Apps SDK</title><link>https://img.ly/blog/from-prompt-to-editor-running-ce-sdk-inside-chatgpt-with-the-apps-sdk/</link><guid isPermaLink="true">https://img.ly/blog/from-prompt-to-editor-running-ce-sdk-inside-chatgpt-with-the-apps-sdk/</guid><description>We built a technical demo running CE.SDK directly inside ChatGPT using MCP, showing how AI chats can open real, interactive editors. It highlights strict MCP contracts, visual-first UX, and how chat becomes a coordination layer for doing creative work.</description><pubDate>Fri, 19 Dec 2025 15:43:16 GMT</pubDate><content:encoded>&lt;p&gt;With the new ChatGPT Apps SDK and Model Context Protocol (MCP), chat interfaces are starting to look less like Q&amp;#x26;A tools and more like places where work actually happens. To explore what that means for creative workflows, we built a small technical demo: &lt;a href=&quot;https://github.com/imgly/cesdk-web-examples/tree/main/cookbooks-chatgpt-app&quot;&gt;&lt;strong&gt;CE.SDK running directly inside ChatGPT&lt;/strong&gt;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From a user’s perspective, the flow is almost trivial. You ask ChatGPT for something like an ecommerce template. ChatGPT searches our template catalog, selects a matching design, and opens it instantly in a fully interactive CE.SDK editor, right inside the chat interface. What looks like a preview is, in fact, a real editor loaded with a real template scene.&lt;/p&gt;
&lt;p&gt;This isn’t meant as a product announcement. It’s a technical proof of concept showing how creative SDKs can plug directly into AI-native interfaces.&lt;/p&gt;
&lt;h2 id=&quot;cesdk-as-a-chatgpt-app&quot;&gt;CE.SDK as a ChatGPT App&lt;/h2&gt;
&lt;figure class=&quot;kg-embed-card&quot;&gt;
&lt;iframe src=&quot;https://www.youtube.com/embed/AoDqUNVLLJ4?feature=oembed&quot; title=&quot;ChatGPT Opens a Real Design Editor: CE.SDK Inside MCP App (Tech Demo)&quot; loading=&quot;lazy&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/figure&gt;
&lt;p&gt;The integration is built around a custom MCP server that exposes CE.SDK to ChatGPT as a tool. The server speaks OpenAI’s JSON-RPC–style MCP and implements the standard lifecycle methods (&lt;code&gt;initialize&lt;/code&gt;, &lt;code&gt;tools.list&lt;/code&gt;, &lt;code&gt;tools.call&lt;/code&gt;, &lt;code&gt;resources.read&lt;/code&gt;). It knows about our premium template catalog and emits structured payloads that the frontend understands.&lt;/p&gt;
&lt;p&gt;On the client side, a Next.js app listens to tool output events streamed from ChatGPT, renders CE.SDK widgets, and hydrates them with the payloads returned by the tool, such as a scene URL, placeholder values, or export permissions. Templates are loaded via CE.SDK’s Template API, either from a URL or from a serialized scene string.&lt;/p&gt;
&lt;p&gt;Under the hood, the stack is fairly conventional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js 15 (App Router)&lt;/li&gt;
&lt;li&gt;CE.SDK Web / CreativeEngine&lt;/li&gt;
&lt;li&gt;A custom MCP handler to normalize JSON-RPC&lt;/li&gt;
&lt;li&gt;Vercel for hosting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What’s new is not the technology itself, but the context in which it runs.&lt;/p&gt;
&lt;h2 id=&quot;working-with-mcp-in-practice&quot;&gt;Working with MCP in Practice&lt;/h2&gt;
&lt;p&gt;The hardest part of the demo wasn’t CE.SDK. It was MCP.&lt;/p&gt;
&lt;p&gt;OpenAI’s MCP implementation is extremely strict. Even the smallest schema mismatch can trigger the infamous “TaskGroup 424” error, usually without any hint as to what went wrong. In many cases, the HTTP response is technically successful, but the JSON structure doesn’t match the expected schema closely enough.&lt;/p&gt;
&lt;p&gt;The key lesson here is to treat MCP responses as hard contracts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Validate every response against a schema (for example with zod).&lt;/li&gt;
&lt;li&gt;Mirror OpenAI’s field names exactly, even for empty or optional capabilities.&lt;/li&gt;
&lt;li&gt;Assume that a 424 almost always means “your JSON shape is wrong”.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another important insight was how critical visual context is in chat-based tools. If your MCP responses don’t include thumbnails or preview images, ChatGPT will often fall back to rendering links. For creative tools, that immediately breaks the experience. In a chat UI, visuals aren’t an enhancement. They &lt;em&gt;are&lt;/em&gt; the interface.&lt;/p&gt;
&lt;p&gt;State handling also requires a shift in mindset. ChatGPT can replay tool calls, and each prompt effectively creates a new widget instance. You can’t rely on mutating an existing editor. The frontend needs to be idempotent: load scenes from serialized state first, then apply changes. Every tool call should be treated as a fresh render.&lt;/p&gt;
&lt;h2 id=&quot;why-this-pattern-matters&quot;&gt;Why This Pattern Matters&lt;/h2&gt;
&lt;p&gt;This demo points to a broader change in how creative software may be accessed. Chat becomes a coordination layer, not just a conversational one. Instead of explaining how something could be designed, the AI opens the actual editor and lets the user continue from there.&lt;/p&gt;
&lt;p&gt;For CE.SDK, this fits naturally. Editors become embeddable capabilities rather than standalone applications, and AI systems become the entry point into creative workflows. Prompting turns into doing.&lt;/p&gt;
&lt;h2 id=&quot;beyond-openai-the-mcp-ui-standard&quot;&gt;Beyond OpenAI: The MCP UI Standard&lt;/h2&gt;
&lt;p&gt;Although this demo uses OpenAI’s MCP, the architecture maps cleanly to the new MCP UI standard recently introduced by Anthropic. That standard aims to make tool definitions and UI rendering more consistent across models and platforms.&lt;/p&gt;
&lt;p&gt;Because this integration already separates tool logic from UI rendering and relies on structured, explicit payloads, transferring it to Anthropic’s MCP UI model is conceptually straightforward. CE.SDK can act as a reusable creative surface across ChatGPT, Claude, and future AI app ecosystems.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.modelcontextprotocol.io/posts/2025-11-21-mcp-apps/&quot;&gt;You can read more about Anthropic’s MCP UI direction here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This demo is intentionally small and technical, but it highlights a meaningful shift: AI systems that don’t just describe creative outcomes, but open the tools to actually create them.&lt;/p&gt;</content:encoded><dc:creator>Jan</dc:creator><dc:creator>Sven</dc:creator><media:content url="https://blog.img.ly/2025/12/chatgpt-open-design-editor-tempalte.jpg" medium="image"/><category>AI</category><category>MCP</category><category>CE.SDK</category></item><item><title>What is Visual Prompting?</title><link>https://img.ly/blog/what-is-visual-prompting/</link><guid isPermaLink="true">https://img.ly/blog/what-is-visual-prompting/</guid><description>Visual Prompting is a new way to guide AI using visual input instead of just text. By composing layouts with images, annotations, and design cues directly on the canvas, creators can prompt AI more intuitively. Learn how IMG.LY’s CE.SDK brings this paradigm to life.</description><pubDate>Tue, 29 Jul 2025 13:06:11 GMT</pubDate><content:encoded>&lt;h2 id=&quot;a-new-paradigm-for-creative-ai-built-by-imgly&quot;&gt;A New Paradigm for Creative AI, Built by IMG.LY&lt;/h2&gt;
&lt;p&gt;To say it’s trite to refer to the impact of AI in this or that domain as disruptive or groundbreaking would be an understatement. Yet, few areas have been as profoundly affected as the creative process. With just a text prompt, anyone can produce stunning images, remix visual styles, and explore design possibilities at a scale and speed never seen before. AI has inserted itself so quickly into this process that its gone from curious novelty to an essential part of the creator toolchain.&lt;/p&gt;
&lt;p&gt;The more serious adoption we see, however, the more key limitations of today’s AI tooling come into focus: &lt;strong&gt;the prompt itself&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Text alone, for all its expressive power, struggles to capture the essence of visual intent. Most creative work doesn’t begin with a sentence it begins with a sketch, a layout, a mood board, or an arrangement of elements. Visual ideas are shared by pointing, placing, showing.&lt;/p&gt;
&lt;p&gt;At &lt;strong&gt;IMG.LY&lt;/strong&gt;, we have begun to think about better ways to direct AI for visual generation, the term we use is Visual Prompting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Visual Prompting: the practice of composing a visual scene or layout as input for a generative model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead of describing what you want with paragraphs of text, you show it directly using a canvas of images, text, spatial cues, and annotations. This visual composition then becomes the prompt for the AI to generate new content in return. It’s a more natural, intuitive, and powerful way to collaborate with AI, especially when integrated directly into the creative process.&lt;/p&gt;
&lt;h2 id=&quot;problem-the-chat-disconnect&quot;&gt;Problem: the Chat Disconnect&lt;/h2&gt;
&lt;p&gt;The current generation of AI tools has largely been shaped by language-first interfaces. Whether it’s ChatGPT for writing or Midjourney for image generation, the assumption is the same: the user will type a descriptive prompt, and the AI will generate a result based on it.&lt;/p&gt;
&lt;p&gt;But when it comes to &lt;strong&gt;design&lt;/strong&gt;, this workflow quickly runs into friction. Visual ideas are inherently spatial and non-linear. Trying to express layout, balance, mood, or specific spatial relationships through text can feel like trying to describe a painting over the phone. It’s possible but unnecessarily cumbersome.&lt;/p&gt;
&lt;p&gt;A designer might want to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Indicate that a certain area in the image should be blue.&lt;/li&gt;
&lt;li&gt;Replace a background with a texture sample.&lt;/li&gt;
&lt;li&gt;Position a character precisely in a composition.&lt;/li&gt;
&lt;li&gt;Annotate which parts of a scene to preserve or modify.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these are difficult to express fluently in text. But they’re &lt;strong&gt;effortless&lt;/strong&gt; in a visual interface. The truth is: &lt;strong&gt;an image is worth more than a thousand words when prompting an image.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-is-visual-prompting&quot;&gt;What Is Visual Prompting?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Visual Prompting&lt;/strong&gt; is a multimodal approach to generative AI, where the &lt;strong&gt;input to the model is not just text, but a full visual composition&lt;/strong&gt;: images, text, annotations, and layout.&lt;/p&gt;
&lt;p&gt;Rather than prompting AI in isolation, the user builds their intent on a canvas. This might include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reference images that communicate mood or style.&lt;/li&gt;
&lt;li&gt;Text blocks indicating desired copy or instructions.&lt;/li&gt;
&lt;li&gt;Annotations pointing to specific areas with notes like “make this glow” or “replace this object.”&lt;/li&gt;
&lt;li&gt;Spatial composition: where elements are arranged meaningfully to convey intent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The visual prompt is then interpreted by a multimodal model such as OpenAI’s &lt;code&gt;gpt-image-1&lt;/code&gt; to generate new visual content that reflects not only the textual description, but also the visual context.&lt;/p&gt;
&lt;h2 id=&quot;how-visual-prompting-works-in-cesdk&quot;&gt;How Visual Prompting Works in CE.SDK&lt;/h2&gt;
&lt;p&gt;About time for an example. As part of our recent AI released &lt;a href=&quot;https://img.ly/demos/ai-editor/web/&quot;&gt;we demoed how to use OpenAIs &lt;code&gt;gpt-image-1&lt;/code&gt; model&lt;/a&gt; to build visual prompting into &lt;strong&gt;CreativeEditor SDK (CE.SDK)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Here’s what the process looks like inside CE.SDK:&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/imgly-ai/visualprompt_05.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Compose Visually:&lt;/strong&gt; The user creates a layout with reference content, uploaded images, icons, color schemes, design elements, placeholder text, and annotations. This composition represents the “prompt” in visual form.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add AI Layers:&lt;/strong&gt; With a single click, the user can trigger image generation using CE.SDK’s built-in AI plugin. The plugin sends the visual context (alongside any optional text input) to a multimodal model capable of interpreting both.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refine and Iterate:&lt;/strong&gt; Users can adjust the layout, reposition elements, change annotations, or layer in new references, then prompt again. Because the canvas is interactive and editable, the feedback loop is tight.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build Up Complexity:&lt;/strong&gt; Over time, users can layer generated images with manually designed components or other generated outputs, creating rich compositions that blend AI creativity with human direction.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This workflow turns the traditional prompt/response cycle into a &lt;strong&gt;conversation between the designer and the model&lt;/strong&gt;, with the canvas acting as the shared language.&lt;/p&gt;
&lt;h2 id=&quot;who-is-visual-prompting-for&quot;&gt;Who Is Visual Prompting For?&lt;/h2&gt;
&lt;p&gt;The use cases for Visual Prompting extend across industries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creative teams&lt;/strong&gt; can go from reference to generation in seconds, iterating visually instead of wrangling prompts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Marketing teams&lt;/strong&gt; can generate regionalized or personalized creative variants from a shared layout.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Product designers&lt;/strong&gt; can prototype in context, turning layouts into realistic screens without leaving the editor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storytellers and content creators&lt;/strong&gt; can use annotated sketches to generate detailed illustrations or scene variations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;E-commerce platforms&lt;/strong&gt; can give sellers the power to visually customize their brand materials with AI assistance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In every case, Visual Prompting replaces friction with flow and text-based prompting with something more expressive, more reliable, and more fun.&lt;/p&gt;
&lt;h2 id=&quot;built-for-this-multimodal-models-and-cesdks-plugin-system&quot;&gt;Built for This: Multimodal Models and CE.SDK’s Plugin System&lt;/h2&gt;
&lt;p&gt;Visual Prompting is only possible because of two parallel advancements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Multimodal AI models&lt;/strong&gt;, such as OpenAI’s &lt;code&gt;gpt-image-1&lt;/code&gt;, that can interpret both images and text, understand spatial relationships, and respond to annotated cues.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A flexible, composable editor SDK&lt;/strong&gt; like CE.SDK, which enables the construction of visual prompts on a live canvas, and makes it easy to integrate AI models directly into the design flow.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Our SDK was built from the ground up to support &lt;strong&gt;AI-first creative workflows&lt;/strong&gt;. Its plugin architecture allows you to add any model or API, image generation, video generation, captioning, text rewriting and use it natively inside the editor without the need to switch tools or copy/paste.&lt;/p&gt;
&lt;p&gt;Generative AI’s full potential is only unlocked when it is embedded directly into the tools creatives use not siloed in chatbots or separate interfaces. Visual Prompting allows that embedding to go even deeper, aligning the &lt;strong&gt;mode of input (visual)&lt;/strong&gt; with the &lt;strong&gt;desired output (visual)&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;explore-it-yourself&quot;&gt;Explore It Yourself&lt;/h3&gt;
&lt;p&gt;🎨 Try out Visual Prompting in our &lt;a href=&quot;https://img.ly/demos/ai-editor/web/&quot;&gt;AI Editor demo&lt;/a&gt;&lt;br&gt;
📘 &lt;a href=&quot;https://img.ly/docs/cesdk/js/user-interface/ai-integration/integrate-8e906c/&quot;&gt;Learn How to Integrate AI into CE.SDK&lt;/a&gt;&lt;br&gt;
💬 &lt;a href=&quot;https://img.ly/forms/contact-sales/&quot;&gt;Contact Us&lt;/a&gt; to Bring Visual Prompting to Your Product&lt;/p&gt;</content:encoded><dc:creator>Jan</dc:creator><media:content url="https://blog.img.ly/2025/07/cesdk-2025-07-25T12_20_58.735Z--1-.png" medium="image"/><category>AI</category><category>CE.SDK</category><category>Creativity</category><category>Creative Workflows</category></item><item><title>Build vs. Buy: Is Fabric.js Right for You</title><link>https://img.ly/blog/build-vs-buy-is-fabric-js-right-for-you/</link><guid isPermaLink="true">https://img.ly/blog/build-vs-buy-is-fabric-js-right-for-you/</guid><description>This blog article provides a detailed comparison between Fabric.js and IMG.LY’s CreativeEditor SDK (CE.SDK) for teams building in-product design editors. It outlines the strengths of Fabric.js as a low-level canvas library, but focuses on the growing limitations teams face as they scale.</description><pubDate>Thu, 15 May 2025 09:31:43 GMT</pubDate><content:encoded>&lt;p&gt;When you’re building a design editor into your product whether for social content, marketing assets, video, or design workflows choosing the right foundation matters. Many teams start with Fabric.js, an open-source canvas library, attracted by its flexibility and permissive license. But as the project scope grows, so do the limitations.&lt;/p&gt;
&lt;p&gt;This article explores the advantages, but also the pitfalls of building a creative tool with Fabric.js and why many product teams ultimately decide to switch or start with a commercial SDK like &lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt;’s CreativeEditor SDK (CE.SDK).&lt;/p&gt;
&lt;p&gt;Consult our &lt;a href=&quot;https://img.ly/fabricjs-alternative/&quot;&gt;comparison page of Fabric.js and IMG.LY&lt;/a&gt; for a feature by feature breakdown of the differences between our SDKs and Fabric.js.&lt;/p&gt;
&lt;h2 id=&quot;why-teams-switch-from-fabricjs&quot;&gt;&lt;strong&gt;Why Teams Switch from Fabric.js&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;We’ve spoken with dozens of companies, from startups to enterprise clients, who evaluated Fabric.js and in many cases opted for IMG.LY instead. Here’s what we consistently hear:&lt;/p&gt;
&lt;h3 id=&quot;1-time-to-market-vs-reinventing-the-wheel&quot;&gt;&lt;strong&gt;1. Time-to-Market vs. Reinventing the Wheel&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Open-source is attractive at first. But once the excitement of building wears off, teams often face a sobering reality: stitching together a decent editing experience from Fabric.js is a months-long effort.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We used Fabric.js before, but if IMG.LY’s SDK is cost-effective, we’d rather not reinvent the wheel.”&lt;/p&gt;
&lt;p&gt;— B2B SaaS Prospect&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They want a modern editor UI, fast iteration cycles, and a stable base not to spend their next quarter building the basics like zoom, text editing, object grouping, layer management, or responsive templates.&lt;/p&gt;
&lt;h3 id=&quot;2-lack-of-advanced-features&quot;&gt;&lt;strong&gt;2. Lack of Advanced Features&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fabric.js excels at low-level canvas manipulation&lt;/strong&gt;, offering a robust API for working directly with objects on the HTML5 canvas - shapes, images, text, and transformations. It’s a great starting point for developers who want fine-grained control over rendering and interactivity. &lt;strong&gt;However, it falls short when it comes to modern editing paradigms&lt;/strong&gt;. Fabric.js provides no native concept of reusable templates, lacks support for layout and design constraints like alignment guides or snapping behavior, and does not include higher-level abstractions for content-aware or AI-powered editing. &lt;strong&gt;In short, Fabric.js gives you a raw toolkit, not a polished, plug-and-play editing solution.&lt;/strong&gt; If you’re building a sophisticated design application, you’ll need to layer these capabilities yourself or integrate additional frameworks to bridge the gap.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We needed a template system and advanced photo editing. Open-source libraries couldn’t do it out of the box.”&lt;/p&gt;
&lt;p&gt;— Marketplace Platform Prospect&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Teams chasing parity with Canva or Adobe tools quickly hit walls. What starts as a proof-of-concept becomes a rebuild of the tables stakes of design editing.&lt;/p&gt;
&lt;h2 id=&quot;real-world-use-cases--vertical-specific-challenges&quot;&gt;&lt;strong&gt;Real-World Use Cases &amp;#x26; Vertical-Specific Challenges&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;We’ve seen teams from various industries reach the same conclusion: Fabric.js doesn’t scale to meet their creative, technical, or business needs. A few common themes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;E-commerce &amp;#x26; Web-to-Print&lt;/strong&gt;: Retailers building product customization flows need template constraints, consistent output quality, and export formats that go beyond canvas. They can’t afford rendering inconsistencies or unpredictable export fidelity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MarTech &amp;#x26; Social Media Tools&lt;/strong&gt;: Marketers need batch generation, AI-assisted creative workflow, brand constraints and consistent creative output across devices. Fabric.js lacks built-in support for these workflows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mobile-first Apps&lt;/strong&gt;: Teams building hybrid apps or web apps that need to be functional on mobile struggle with Fabric.js’ &lt;a href=&quot;https://github.com/fabricjs/fabric.js/issues/6980&quot;&gt;lacklustre mobile support&lt;/a&gt;. The inability to deliver a consistent UX across iOS, Android, and Web leads to dropped features or split tech stacks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Video and Multimedia Platforms&lt;/strong&gt;: Fabric.js has no native video support, track-based editing, or multi-frame logic. Prospects in this space frequently abandon their Fabric.js POCs once real constraints emerge.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A major pain point across all verticals is &lt;strong&gt;rendering consistency&lt;/strong&gt;. CE.SDK renders identically across browser, server, and mobile thanks to a shared rendering core (&lt;a href=&quot;https://img.ly/docs/cesdk/node/get-started/overview-e18f40/&quot;&gt;CreativeEngine&lt;/a&gt;). This is critical for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Workflows that begin on web and finish on mobile&lt;/li&gt;
&lt;li&gt;Server-side generation (e.g., previews, PDFs, batch exports)&lt;/li&gt;
&lt;li&gt;Feature parity and UX reliability across platforms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check out our &lt;a href=&quot;https://img.ly/demos/&quot;&gt;demo page&lt;/a&gt; to explore these use cases.&lt;/p&gt;
&lt;h2 id=&quot;technical-debt-the-hidden-cost-of-fabricjs&quot;&gt;&lt;strong&gt;Technical Debt: The Hidden Cost of Fabric.js&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;On paper, Fabric.js seems like a fast way to get started. But its real cost emerges over time in performance bottlenecks, missing architecture, and maintenance drag.&lt;/p&gt;
&lt;h3 id=&quot;aging-codebase-and-patchy-maintenance&quot;&gt;&lt;strong&gt;Aging Codebase and Patchy Maintenance&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;As of 2025, Fabric.js has over 400 open issues on GitHub, some dating back years. Many feature requests such as better performance for large object sets, async rendering, or text-on-path improvements are either unresolved or uncertainly prioritized.&lt;/p&gt;
&lt;p&gt;The core maintainers do their best, but progress is slow. You’re relying on volunteer effort for critical infrastructure.&lt;/p&gt;
&lt;h3 id=&quot;slow-issue-resolution&quot;&gt;&lt;strong&gt;Slow Issue Resolution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Many of the GitHub issues (e.g., &lt;a href=&quot;https://github.com/fabricjs/fabric.js/issues/5885&quot;&gt;#5885&lt;/a&gt;, &lt;a href=&quot;https://github.com/fabricjs/fabric.js/issues/6582&quot;&gt;#6582&lt;/a&gt;) highlight long-standing rendering bugs and performance problems. These are hard to fix, and updates can break your own hacks or workarounds.&lt;/p&gt;
&lt;p&gt;Unlike a commercial SDK, Fabric.js doesn’t guarantee backward compatibility. No SLAs. Little roadmap visibility.&lt;/p&gt;
&lt;h2 id=&quot;customer-feedback-why-they-walked-away&quot;&gt;&lt;strong&gt;Customer Feedback: Why They Walked Away&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Here are some soundbites from our customers and prospects on why they decided against building with Fabric.js:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“The quality and UX didn’t meet our standards.”&lt;/em&gt;&lt;br&gt;
Product Customizer&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“Developer experience was poor. We spent more time debugging than building features.”&lt;/em&gt;&lt;br&gt;
B2B SaaS Ad Design&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“We needed enterprise support, scalability, and documentation. Open source didn’t cut it.”&lt;/em&gt;&lt;br&gt;
Web to print Customer&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“Cross-platform support and minimum SDK version constraints were a major blocker.”&lt;/em&gt;&lt;br&gt;
Claim Management Application&lt;/p&gt;
&lt;h2 id=&quot;voice-of-the-dev&quot;&gt;&lt;strong&gt;Voice of the Dev&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Beyond enterprise evaluations, developers working with Fabric.js often share their struggles publicly on GitHub, Stack Overflow, and developer forums. Their commentary offers real-world insight into day-to-day frustrations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“FabricJS doesn’t seem to work well on Mobile.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/fabricjs/fabric.js/issues/6980&quot;&gt;Github issue #6980&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Fabric.js object controls don’t work until after a common selection is made. Had to hack around it with extra event listeners.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/64697215/fabricjs-object-controls-not-working-until-common-selection&quot;&gt;StackOverflow&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Trying to integrate Fabric.js with Next.js + Rollup is a mess. Unexpected tokens, config rewrites — it doesn’t play well with modern bundlers.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/fabricjs/fabric.js/issues/8444&quot;&gt;GitHub Issue #8444&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We’re blocked by the use of ‘unsafe-eval’ due to our content security policy. Fabric.js needs a rewrite to be CSP-compliant.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/fabricjs/fabric.js/issues/9666&quot;&gt;GitHub Issue #9666&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Concrete takeaways from developer feedback:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Basic UI control quirks&lt;/strong&gt;: Common issues with selection handling and control behavior require manual workarounds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compatibility friction&lt;/strong&gt;: Fabric.js does not play well with modern build tools like Next.js and Rollup without additional configuration or patching.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security blockers&lt;/strong&gt;: The reliance on &lt;code&gt;unsafe-eval&lt;/code&gt; creates CSP conflicts, making it unsuitable for projects with strict security requirements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uncertain roadmap&lt;/strong&gt;: Critical features like async rendering may sit open for years, and niche features important to your use case may never land if they don’t align with community priorities.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While every open source project faces these difficulties, they do represent systemic issues with performance, extensibility, and production-readiness. For teams building long-lived, customer-facing tools, this developer feedback is often a leading indicator of future roadblocks.&lt;/p&gt;
&lt;h2 id=&quot;back-of-the-envelope-cost-of-building-with-fabricjs&quot;&gt;&lt;strong&gt;Back-of-the-Envelope Cost of Building with Fabric.js&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Many teams underestimate the cost of building a design editor from scratch. Here’s a rough breakdown of the time investment we’ve heard from teams who tried:&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;Estimated Engineering Time&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Core canvas-based editor UI (zoom, drag, resize, selection, tool switching)&lt;/td&gt;&lt;td&gt;6–8 weeks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SVG support, snapping, grouping, and layer management&lt;/td&gt;&lt;td&gt;4–6 weeks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Template constraints&lt;/td&gt;&lt;td&gt;3–5 weeks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cross-platform adaptation (ironing out issues on mobile browsers, defining fallbacks)&lt;/td&gt;&lt;td&gt;4–6 weeks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bug triage, ongoing maintenance, and refactors (first 12–18 months)&lt;/td&gt;&lt;td&gt;6–9 weeks&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Total: ~6–8 months of senior dev time&lt;/strong&gt; just to get to feature parity with what CE.SDK offers out of the box.&lt;/p&gt;
&lt;p&gt;This doesn’t include the cost of QA, product management, or future extensibility. Nor the opportunity cost of what your team could be building instead.&lt;/p&gt;
&lt;h2 id=&quot;imglys-cesdk-a-ready-made-solution-built-for-growth&quot;&gt;&lt;strong&gt;IMG.LY’s CE.SDK: A Ready-Made Solution Built for Growth&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;By contrast, IMG.LY offers a production-grade SDK built for cross-platform creative tools, backed by a dedicated engineering team and used by major apps across industries.&lt;/p&gt;
&lt;div&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;Category&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;&lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; (CE.SDK)&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;Fabric.js&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Out-of-the-box UI&lt;/td&gt;&lt;td&gt;✅ Prebuilt modern UI&lt;/td&gt;&lt;td&gt;❌ Build from scratch&lt;/td&gt;&lt;td&gt;CE.SDK ships with full UI/UX patterns&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Plugin System&lt;/td&gt;&lt;td&gt;✅ Native plugin architecture&lt;/td&gt;&lt;td&gt;⚠️ Manual code extension&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; supports formal plugin APIs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Free Drawing Tools&lt;/td&gt;&lt;td&gt;⚠️ Requires integration&lt;/td&gt;&lt;td&gt;✅ Built-in pencil + shapes&lt;/td&gt;&lt;td&gt;Fabric.js excels at shape-level control&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Advanced Editing&lt;/td&gt;&lt;td&gt;✅ Vector + raster support, layering, filters&lt;/td&gt;&lt;td&gt;⚠️ Basic vector only&lt;/td&gt;&lt;td&gt;CE.SDK includes pro-grade editing capabilities&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Templating System&lt;/td&gt;&lt;td&gt;✅ Dynamic placeholders + constraints&lt;/td&gt;&lt;td&gt;❌ Manual implementation&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; supports automation workflows&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Video Editing&lt;/td&gt;&lt;td&gt;✅ Multi-track timeline editor&lt;/td&gt;&lt;td&gt;❌ Not supported&lt;/td&gt;&lt;td&gt;No video support in Fabric.js&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cross-Platform&lt;/td&gt;&lt;td&gt;✅ Web, iOS, Android, Node, Flutter&lt;/td&gt;&lt;td&gt;⚠️ Web only&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; has native SDKs and server tools&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Asset Integrations&lt;/td&gt;&lt;td&gt;✅ Unsplash, Getty, Brandfolder&lt;/td&gt;&lt;td&gt;❌ Manual setup&lt;/td&gt;&lt;td&gt;CE.SDK integrates assets out-of-the-box&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Enterprise Support&lt;/td&gt;&lt;td&gt;✅ SLAs, onboarding, deployment help&lt;/td&gt;&lt;td&gt;❌ Community support only&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; offers dedicated engineering help&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Design File Import Support&lt;/td&gt;&lt;td&gt;✅ PSD, AI, INDD&lt;/td&gt;&lt;td&gt;⚠️ None&lt;/td&gt;&lt;td&gt;CE.SDK supports importing common design file formats&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;AI Editing&lt;/td&gt;&lt;td&gt;✅ Background removal, integrate any AI model for image/video/text/audio gen&lt;/td&gt;&lt;td&gt;❌ Not supported&lt;/td&gt;&lt;td&gt;AI-native editing pipeline available&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Rendering Consistency&lt;/td&gt;&lt;td&gt;✅ Unified engine across platforms&lt;/td&gt;&lt;td&gt;⚠️ Browser dependent&lt;/td&gt;&lt;td&gt;CE.SDK ensures pixel-parity on all targets&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id=&quot;when-does-fabricjs-still-make-sense&quot;&gt;&lt;strong&gt;When Does Fabric.js Still Make Sense?&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This article might read like a put-down, but it’s not supposed to be that. Until now we were simply evaluating Fabric.js with respect to building fully-featured design editing tools. There are, however, a number of well-scoped use cases where Fabric.js excels. These include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Building an &lt;strong&gt;internal tool&lt;/strong&gt;, proof of concept, or educational app&lt;/li&gt;
&lt;li&gt;Creating a &lt;strong&gt;custom, single-platform sketching or annotation layer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Developing a &lt;strong&gt;low-fidelity prototype&lt;/strong&gt; with full code-level control&lt;/li&gt;
&lt;li&gt;Building canvas collaboration tools such as &lt;strong&gt;drag and drop editors&lt;/strong&gt; or interactive canvases, such as Miro.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An example of where Fabric.js worked well is a tool such as &lt;a href=&quot;https://mockola.com/&quot;&gt;Mockola&lt;/a&gt;, a drag-and-drop diagram editor, where shape manipulation, lightweight rendering, and canvas-level control are more important than cross-platform design fidelity. Mockola’s is a good use case, because its emphasis on real-time collaboration and planning rather than high-fidelity design. This means that features like free drawing, drag-and-drop, and JSON-based serialization are a great fit, all of which Fabric.js supports out of the box.&lt;/p&gt;
&lt;p&gt;For teams willing to invest in building and maintaining their own editor infrastructure and whose use case does not require cross-platform parity, advanced media editing, or enterprise scaling Fabric.js continues to be a compelling foundation.&lt;/p&gt;
&lt;p&gt;However, for products that need to ship quickly, scale reliably, and support modern creative workflows across platforms, IMG.LY’s CE.SDK offers the infrastructure and polish that customers now expect.&lt;/p&gt;
&lt;h2 id=&quot;the-bottom-line&quot;&gt;&lt;strong&gt;The Bottom Line&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;As &lt;a href=&quot;https://www.youtube.com/watch?v=TBOazhxtq5s&quot;&gt;MIT CIO Symposium speaker&lt;/a&gt; Mark Holst-Knudsen put it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“You shouldn’t build anything that’s available off the shelf because it’s not a source of competitive advantage if everybody else can avail themselves of it.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For most companies, building an editor from scratch is not a competitive edge, it’s a distraction from shipping and scaling. And Fabric.js, while capable in the hands of specialists, isn’t a shortcut to the finish line.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt;’s CE.SDK gives you a head start with advanced editing features, AI automation, template support, plugin extensibility, rendering consistency, and battle-tested scalability across platforms. We put together a &lt;a href=&quot;https://img.ly/blog/imgly-impact-report/&quot;&gt;data report based on 600+ customers, 28 structured customer interviews, and a self-reported customer survey&lt;/a&gt; that speaks for itself when it comes to real-life outcomes.&lt;/p&gt;
&lt;p&gt;So before you dive into Fabric.js and start reinventing core functionality, ask yourself: What competitive advantage are you going to build &lt;strong&gt;on top&lt;/strong&gt; of a design editor and which functionality are you better served buying from a trusted vendor?&lt;/p&gt;</content:encoded><dc:creator>Jan</dc:creator><media:content url="https://blog.img.ly/2025/05/build-vs-buy-imgly-fabricjs-sdk.jpg" medium="image"/><category>Fabric.js</category><category>CE.SDK</category><category>OpenSource</category></item><item><title>CE.SDK v1.49 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-49-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-49-0-release-notes/</guid><description>Bring more motion and emotion to your designs with GIF Support, Ken Burns Animation!</description><pubDate>Thu, 17 Apr 2025 12:55:42 GMT</pubDate><content:encoded>&lt;p&gt;Get ready to add more motion and emotion to your designs! From fully integrated GIF Support to the cinematic Ken Burns animation and polished text background on iOS, this update packs features that elevate storytelling and enhance visual impact. Let’s dive in!&lt;/p&gt;
&lt;h2 id=&quot;use-gifs-in-your-designs-on-web-and-mobile&quot;&gt;Use GIFs in Your Designs on Web and Mobile&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-49/gif-design-video-editor-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;GIFs are now fully integrated into the CE.SDK UI. Add and manage animated images like any other media asset. Drop a GIF into your timeline to play it &lt;strong&gt;once&lt;/strong&gt;, or create a &lt;strong&gt;loop&lt;/strong&gt; by extending its duration. You’re in control.&lt;/p&gt;
&lt;p&gt;This update delivers a consistent experience across Web and Mobile, empowering dynamic content creation for social media, marketing, and beyond.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Getting Started:&lt;/strong&gt;&lt;br&gt;
GIF support itself is built-in; no setup required.
However, to add looping, enable the &lt;strong&gt;&lt;code&gt;looping&lt;/code&gt;&lt;/strong&gt; option in your assets. Find platform-specific guidance in our docs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/js/import-media/from-remote-source/unsplash-8f31f0/&quot;&gt;Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/ios/import-media/from-remote-source/unsplash-8f31f0/&quot;&gt;iOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/android/import-media/from-remote-source/unsplash-8f31f0/&quot;&gt;Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;add-a-cinematic-ken-burns-animation&quot;&gt;Add A Cinematic Ken Burns Animation&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-49/ken-burns-effect-editor-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Give your images a cinematic touch with the new crop-zoom animation in CE.SDK. Inspired by the &lt;strong&gt;Ken Burns effect&lt;/strong&gt;, this feature lets you smoothly pan and zoom across images, creating dynamic storytelling without complex editing.&lt;/p&gt;
&lt;p&gt;Apply the Ken Burns animation directly from the CE.SDK animation library on the web. Learn &lt;a href=&quot;https://img.ly/docs/cesdk/js/animation/overview-6a2ef2/&quot;&gt;how to use animations&lt;/a&gt; and &lt;a href=&quot;https://img.ly/docs/cesdk/js/animation/types-4e5f41/&quot;&gt;their properties&lt;/a&gt; with our documentation.&lt;/p&gt;
&lt;h2 id=&quot;add-text-backgrounds-on-ios&quot;&gt;Add Text Backgrounds on iOS&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-49/ios-text-bg.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Make your text pop! Apply solid color backgrounds to text on iOS. Additionally, adjust the padding and rounded corners of your text background.&lt;/p&gt;
&lt;p&gt;This feature ensures readability and adds a polished, professional touch to your designs. By elevating text design, your app helps users create visually compelling content that stands out. Available for Web and iOS, soon on Android!&lt;/p&gt;
&lt;p&gt;Get started with our &lt;a href=&quot;https://img.ly/docs/cesdk/ios/text/styling-269c48/#text-background&quot;&gt;text background documentation&lt;/a&gt; for iOS.&lt;/p&gt;
&lt;h2 id=&quot;improvements&quot;&gt;Improvements&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Speed Up Your HDR Video Editing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1480px) 1480px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1480&quot; height=&quot;643&quot; src=&quot;https://img.ly/_astro/ios-HDR-SDR-convert_Zq5WyL.webp&quot; srcset=&quot;/_astro/ios-HDR-SDR-convert_2tqu0Y.webp 640w, /_astro/ios-HDR-SDR-convert_2uF7sv.webp 750w, /_astro/ios-HDR-SDR-convert_1o3sOb.webp 828w, /_astro/ios-HDR-SDR-convert_13CpHq.webp 1080w, /_astro/ios-HDR-SDR-convert_Z2dOPkD.webp 1280w, /_astro/ios-HDR-SDR-convert_Zq5WyL.webp 1480w&quot;&gt;&lt;/p&gt;
&lt;p&gt;We’ve dramatically accelerated HDR-to-SDR video conversion in CE.SDK on &lt;strong&gt;iOS&lt;/strong&gt;. While HDR videos previously required lengthy processing, especially for 4K content, they now convert to SDR with minimal delay, letting users start editing their footage faster than ever before.&lt;/p&gt;
&lt;p&gt;Stay tuned: Smooth HDR-to-SDR conversion will also be available for Web with CE.SDK v1.50.&lt;/p&gt;
&lt;h2 id=&quot;upcoming&quot;&gt;Upcoming&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Boost Engagement and Accessibility with Captions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1480px) 1480px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1480&quot; height=&quot;643&quot; src=&quot;https://img.ly/_astro/captions-preview-1_2ii2eI.webp&quot; srcset=&quot;/_astro/captions-preview-1_1SH7Ay.webp 640w, /_astro/captions-preview-1_ZOmtgo.webp 750w, /_astro/captions-preview-1_Zq1tKN.webp 828w, /_astro/captions-preview-1_JbO7P.webp 1080w, /_astro/captions-preview-1_1vJqbh.webp 1280w, /_astro/captions-preview-1_2ii2eI.webp 1480w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Captions are essential in today’s social media landscape, where videos often autoplay on mute and clear messaging is key. Our upcoming &lt;strong&gt;Captions for Web&lt;/strong&gt; feature will allow you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Manually add subtitles to videos&lt;/strong&gt; or upload an &lt;strong&gt;SRT file&lt;/strong&gt; for seamless integration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adjust timing and formatting&lt;/strong&gt; in an intuitive interface to match your brand’s style.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embed captions directly&lt;/strong&gt; into videos, ensuring they remain visible across all platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for reading! View all bug fixes and changes in the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/#v1490--april-16th-2025&quot;&gt;Changelog&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;3,000+ creative professionals gain early access to new features and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2025/04/creative-editor-sdk-1-49-2.jpg" medium="image"/><category>Release Notes</category><category>CE.SDK</category><category>GIF</category><category>Animation</category></item><item><title>CE.SDK v1.48 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-48-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-48-0-release-notes/</guid><description>We’re expanding UI customization for CE.SDK on Android: now you can tailor the navigation bar to match your brand and streamline your design workflows.</description><pubDate>Tue, 08 Apr 2025 12:13:35 GMT</pubDate><content:encoded>&lt;p&gt;This release makes it easier than ever to tailor the Android editing experience to your brand. Customize the navigation bar to guide your users seamlessly and create an interface that feels uniquely yours.&lt;/p&gt;
&lt;p&gt;Let’s jump in:&lt;/p&gt;
&lt;h2 id=&quot;match-your-navigation-bar-with-your-design--logic&quot;&gt;Match Your Navigation Bar With Your Design &amp;#x26; Logic&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&quot;Customize your Navigation Bar in your Editor for Android.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 2000px) 2000px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;2000&quot; height=&quot;2000&quot; src=&quot;https://img.ly/_astro/navigation-bar-customize-android-ce_SDK_Z2f3aLB.webp&quot; srcset=&quot;/_astro/navigation-bar-customize-android-ce_SDK_Z1Vu1gn.webp 640w, /_astro/navigation-bar-customize-android-ce_SDK_JbBRy.webp 750w, /_astro/navigation-bar-customize-android-ce_SDK_Woj1G.webp 828w, /_astro/navigation-bar-customize-android-ce_SDK_Z1QFLwj.webp 1080w, /_astro/navigation-bar-customize-android-ce_SDK_Z1jmYoO.webp 1280w, /_astro/navigation-bar-customize-android-ce_SDK_2pEAG7.webp 1668w, /_astro/navigation-bar-customize-android-ce_SDK_Z2f3aLB.webp 2000w&quot;&gt;&lt;/p&gt;
&lt;p&gt;You now have more control over customizing the navigation bar on &lt;strong&gt;Android&lt;/strong&gt;, ensuring that it reflects your brand and optimizes user flows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Add Custom Buttons&lt;/strong&gt;: You can add custom buttons to the navigation bar, to give users quick access to frequently used actions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rearrange Buttons:&lt;/strong&gt; Arrange buttons in your navigation bar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integrate Custom Components&lt;/strong&gt;: Customize the navigation bar by integrating unique elements that fit your app’s design and functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These updates allow you to fully tailor the mobile editing experience to your specific needs.&lt;/p&gt;
&lt;p&gt;💡 Did you know? In our previous update, we introduced customizability for the &lt;a href=&quot;https://img.ly/docs/cesdk/android/user-interface/customization/dock-cb916c/&quot;&gt;dock&lt;/a&gt; and &lt;a href=&quot;https://img.ly/docs/cesdk/android/user-interface/customization/inspector-bar-8ca1cd/&quot;&gt;inspector&lt;/a&gt; bar on Android, laying the foundation for more UI personalization.&lt;/p&gt;
&lt;p&gt;We’re continuing that momentum by giving you full control over the navigation bar, ensuring that every part of your mobile editing experience can align with your product’s workflow.&lt;/p&gt;
&lt;p&gt;Start customizing your navigation bar with our &lt;a href=&quot;https://img.ly/docs/cesdk/android/user-interface/customization/navigation-bar-4e5d39/&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;upcoming&quot;&gt;Upcoming&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Enjoy Vibrant HDR Videos&lt;/strong&gt;&lt;br&gt;
CE.SDK will support loading HDR videos on iOS, converting them to SDR on the fly for accurate and vibrant color representation, without the need for time-consuming transcoding.&lt;/p&gt;
&lt;p&gt;Previously, HDR videos needed to be transcoded with delays, especially with large 4K videos. Soon, HDR content is processed &lt;em&gt;instantly&lt;/em&gt;. Videos appear with correct color fidelity right away, making the editing experience more fluid and visually accurate for users.&lt;/p&gt;
&lt;p&gt;This enhancement will remove friction in the editing workflow and lets your users start working with their content immediately. By offering a smoother, higher-quality experience, your app can boost user engagement and retention.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;View all bug fixes and changes in the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/#v1480--april-1st-2025&quot;&gt;Changelog&lt;/a&gt;. Thanks for reading!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3,000+ creative professionals gain early access to new features and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2025/04/creative-editor-sdk-1-48.jpg" medium="image"/><category>Release Notes</category><category>CE.SDK</category><category>Android App Development</category><category>HDR</category></item><item><title>CE.SDK v1.46 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-46-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-46-0-release-notes/</guid><description>This release gives you full control over the iOS dock and inspector bar, letting you customize actions and buttons for a faster, more intuitive editing experience.</description><pubDate>Tue, 11 Mar 2025 15:58:30 GMT</pubDate><content:encoded>&lt;p&gt;Welcome to a new release! CE.SDK v1.46 introduces a more flexible and intuitive user interface for iOS, allowing you to optimize your workflow with a customizable dock and inspector. Read on for upcoming features.&lt;/p&gt;
&lt;h2 id=&quot;shape-your-ios-interface-around-your-workflow&quot;&gt;Shape Your iOS Interface Around Your Workflow&lt;/h2&gt;
&lt;p&gt;We unlock full &lt;strong&gt;dock and inspector bar customization&lt;/strong&gt;, giving you the flexibility to optimize your workflow. With an open API, you can now tailor these UI elements to better suit your editing needs, whether by reordering actions, adding custom functionality, or simplifying the interface.&lt;/p&gt;
&lt;p&gt;Take control of your interface by modifying both the &lt;strong&gt;dock&lt;/strong&gt; and &lt;strong&gt;inspector bar&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rearrange &amp;#x26; Customize Actions&lt;/strong&gt; – Prioritize your most-used tools by reordering or removing actions to create a cleaner, more efficient workspace.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add Custom Buttons &amp;#x26; Views&lt;/strong&gt; – Extend functionality by integrating &lt;strong&gt;custom buttons or views&lt;/strong&gt; that trigger specific actions, such as opening an asset library or displaying additional information.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These enhancements provide a seamless, intuitive editing experience that adapts to your unique workflow needs.&lt;/p&gt;
&lt;p&gt;Start customizing your &lt;a href=&quot;https://img.ly/docs/cesdk/ios/user-interface/customization/dock-cb916c/&quot;&gt;dock&lt;/a&gt; and &lt;a href=&quot;https://img.ly/docs/cesdk/ios/user-interface/customization/inspector-bar-8ca1cd/&quot;&gt;inspector bar&lt;/a&gt; today with our documentation.&lt;/p&gt;
&lt;h2 id=&quot;upcoming&quot;&gt;Upcoming&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Boost Engagement and Accessibility with Video Captions&lt;/strong&gt;&lt;br&gt;
Captions are essential in today’s social media landscape, where videos often autoplay on mute and clear messaging is key. Our upcoming &lt;strong&gt;Video&lt;/strong&gt; &lt;strong&gt;Captions&lt;/strong&gt; for Web will allow you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Manually add subtitles to videos&lt;/strong&gt; or upload an &lt;strong&gt;SRT file&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adjust timing and formatting&lt;/strong&gt; in an intuitive interface to match your brand’s style.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embed captions directly&lt;/strong&gt; into videos, ensuring they remain visible across all platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stay tuned. Captions are coming soon!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;View all bug fixes and changes in the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/#v1461--march-5th-2025&quot;&gt;Changelog&lt;/a&gt;. Thanks for reading!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3,000+ creative professionals gain early access to new features and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2025/03/creative-editor-sdk-1-46-imgly.jpg" medium="image"/><category>Release Notes</category><category>CE.SDK</category><category>iOS App Development</category></item><item><title>How to Build a Short Video Generator Using CE.SDK</title><link>https://img.ly/blog/how-to-build-a-short-video-generator-using-ce-sdk-2/</link><guid isPermaLink="true">https://img.ly/blog/how-to-build-a-short-video-generator-using-ce-sdk-2/</guid><description>Build an AI-powered video generator that creates editable, high-quality videos in the browser: no server-side processing needed.</description><pubDate>Tue, 04 Mar 2025 12:57:47 GMT</pubDate><content:encoded>&lt;p&gt;In the following, I’m presenting a simple cookbook for building an AI-based video generator app, as described in &lt;a href=&quot;https://img.ly/blog/how-to-build-short-video-generator-ai-creative-sdk/&quot;&gt;my previous blog post&lt;/a&gt;. We’re using a combination of different APIs to generate text, audio, and images and will compose &amp;#x26; render the final video using the headless &lt;a href=&quot;https://img.ly/products/creative-sdk/&quot;&gt;CreativeEditor SDK&lt;/a&gt;. We also call it the Creative Engine.&lt;/p&gt;
&lt;p&gt;This cookbook showcases the powerful capabilities of our client-side Creative Engine. The engine enables real-time video generation directly in the browser, eliminating the need for server-side processing. What sets this approach apart is its ability to produce editable source files that can then be opened with CreativeEditor SDK.&lt;/p&gt;
&lt;p&gt;This approach is giving users complete control over every aspect of your video–from text and images to animations and overall composition. This means your users can refine and perfect your content even after the initial generation.&lt;/p&gt;
&lt;p&gt;Get the &lt;a href=&quot;https://github.com/imgly/ai-video-creator&quot;&gt;complete code on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;scope&quot;&gt;Scope&lt;/h2&gt;
&lt;p&gt;This tutorial focuses on building an app with a simple UX:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Input your keywords/topics&lt;/li&gt;
&lt;li&gt;Choose between landscape or portrait format&lt;/li&gt;
&lt;li&gt;Generate and preview your video&lt;/li&gt;
&lt;li&gt;Edit the video in the CE.SDK video editor&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The app flow we will create:&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/how-to/er-ai2/workflow.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;The post-editing we will get with CE.SDK:&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/how-to/er-ai2/editing-with-ce-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;h2 id=&quot;technical-overview&quot;&gt;Technical Overview&lt;/h2&gt;
&lt;p&gt;The app follows three major steps to generate the video.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A script is generated based on User input, the output is a structured XML file.&lt;/li&gt;
&lt;li&gt;The XML script is parsed to extract text and image information. The extracted data will then be used to generate audio &amp;#x26; image files through third-party APIs&lt;/li&gt;
&lt;li&gt;All assets are loaded into the creative engine. This is where the composition, including animation and effects, takes place. The Creative Engine then exports a video and scene file, which can be edited with the Creative Editor.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;
&lt;p&gt;We’ll use a boilerplate with Next.js, React, Typescript &amp;#x26; Tailwind. Make sure you retrieve all necessary keys:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anthropic.com/&quot;&gt;Anthropic&lt;/a&gt; (LLM)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://elevenlabs.io/&quot;&gt;ElevenLabs&lt;/a&gt; (text to speech)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fal.ai/&quot;&gt;fal.ai&lt;/a&gt; (text to image)&lt;/li&gt;
&lt;li&gt;IMG.LY CE.SDK – Retrieve a &lt;a href=&quot;https://img.ly/docs/cesdk/&quot;&gt;free trial key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Required environment variables&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;NEXT_PUBLIC_ANTHROPIC_API_KEY&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; your_claude_api_key;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;NEXT_PUBLIC_FAL_API_KEY&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; your_fal_ai_key;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;NEXT_PUBLIC_ELEVEN_LABS_KEY&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; your_eleven_labs_key;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;NEXT_PUBLIC_IMG_LY_KEY&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; your_img_ly_key;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;
&lt;h3 id=&quot;1-generate-the-script&quot;&gt;1. Generate The Script&lt;/h3&gt;
&lt;p&gt;In this step, we’ll focus on generating the initial prompt and then passing it to the Anthropic API.&lt;/p&gt;
&lt;p&gt;As with many things with LLM, there are many different strategies for structuring the initial prompt. From experience, the best result comes from providing examples of the desired output. We’ve decided to use an XML document; this can be easily parsed later on and is less error-prone compared to a JSON.&lt;/p&gt;
&lt;p&gt;We now define the structure of how information should be saved in the XML.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;video&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt; part&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;intro&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; voiceId&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;50YSQEDPA2vlOxhCseP4&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;0.2&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Did you know these fascinating facts about pyramids?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;/&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;Ancient Egyptian pyramid at sunset&amp;#x3C;/&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt; part&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;content&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; voiceId&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;50YSQEDPA2vlOxhCseP4&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;0.2&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        The Great Pyramid was the tallest structure for over 3,800 years!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;/&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;Great Pyramid comparison to modern buildings&amp;#x3C;/&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt; part&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;outro&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; voiceId&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;50YSQEDPA2vlOxhCseP4&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        The pyramids continue to reveal their secrets to this day...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;/&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;A giant 3D question mark hovering over the pyramids&amp;#x3C;/&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; voiceId&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;50YSQEDPA2vlOxhCseP4&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Stay curious - there&apos;s always more to discover!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;/&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;Pyramids under starry night sky&amp;#x3C;/&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;video&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this tutorial, we’ll focus on the format trivia only as shown in this example. For later iterations, however, I’m planning to implement different content formats (e.g., trivia, quiz, recipe, etc.). Each of these formats will have its example XML. Therefore, I’m nesting the XML in a simple format object to scale this up easily later.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; Format&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  example&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; formats&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Record&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Format&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  trivia: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    name: &lt;/span&gt;&lt;span&gt;&apos;Trivia&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    example: &lt;/span&gt;&lt;span&gt;`&amp;#x3C;video&gt;&amp;#x3C;group&gt;...&amp;#x3C;/group&gt;&amp;#x3C;/video&gt;`&lt;/span&gt;&lt;span&gt; // Add example from above&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using this format object with the example, we can now generate the prompt.&lt;/p&gt;
&lt;p&gt;What do we need for this prompt?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Description of the task&lt;/li&gt;
&lt;li&gt;Description of the desired output, incl. an example for the specified format&lt;/li&gt;
&lt;li&gt;Topic as provided by the user&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The topic provided by the user is passed to the function as a string.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; createVideoScriptPrompt&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  topic&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  formatName&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &apos;trivia&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; format&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; formats[formatName];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;format) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Format ${&lt;/span&gt;&lt;span&gt;formatName&lt;/span&gt;&lt;span&gt;} not found`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Format: ${&lt;/span&gt;&lt;span&gt;format&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Topic: ${&lt;/span&gt;&lt;span&gt;topic&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Please write a detailed script for this short video, considering the specified format and topic.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Include an introduction, main content sections, and an outro. Each section should have an image.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Structure the script as an XML Document with clear sections, descriptions for the images.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;The image description should be written as a prompt. This prompt will be used to generate an image.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Put the description between the image tags. The video shouldn&apos;t be longer than 30 seconds.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Example format:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;format&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;example&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-generate-all-assets&quot;&gt;2. Generate All Assets&lt;/h3&gt;
&lt;p&gt;In the second step, we’ll parse through the LLM response, which should be the XML. We’ll create a simple parsing function to extract all text information that should be sent to text-to-speech and text-to-image AIs.&lt;/p&gt;
&lt;p&gt;Please note that all these steps can be easily streamlined by using AI-assisted coding. Just provide the example XML as input and your desired output.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API Calls&lt;/strong&gt;&lt;br&gt;
When finding text &amp;#x26; image tags in the XML, we’ll call API functions for text-to-speech and text-to-image. For this example, I’m using ElevenLabs &amp;#x26; fal APIs. You will find all API calls in the api.ts.&lt;/p&gt;
&lt;p&gt;Since the LLM generated a script that includes image prompts, make sure to pass them to the API.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; async&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; generateImage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; null&lt;/span&gt;&lt;span&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    console.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Generating image for prompt:&apos;&lt;/span&gt;&lt;span&gt;, prompt);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    const&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; fal.&lt;/span&gt;&lt;span&gt;subscribe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;fal-ai/flux/dev&apos;&lt;/span&gt;&lt;span&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      input: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        prompt: prompt,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        size: &lt;/span&gt;&lt;span&gt;&apos;portrait_16_9&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    const&lt;/span&gt;&lt;span&gt; typedResult&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt; }[] };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    console.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Image generation successful. URL:&apos;&lt;/span&gt;&lt;span&gt;, typedResult.images[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;].url);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; typedResult.images[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;].url;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  } &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (error) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    console.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Error generating image:&apos;&lt;/span&gt;&lt;span&gt;, error);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Timestamps&lt;/strong&gt;&lt;br&gt;
Last but not least, we need to come up with timestamps. What’s the duration of each segment? This is critical information for composing the video. Luckily, this is quite easy: Each scene is as long as the generated audio for each segment. This duration for the audio segments can be calculated: Most TTS like ElevenLabs provide timestamps along the audio file. These are typically character-based timestamps, so we first have to calculate the timestamps for each word and then the duration for the entire text section.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ready For The Next Steps&lt;/strong&gt;&lt;br&gt;
All Asset URLs that are generated will be saved in a &lt;code&gt;VideoBlock&lt;/code&gt; object for convenience. The duration of the VideoBlock is the duration of the audio, as calculated above.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; VideoBlock&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  text&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  imageUrl&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  audioUrl&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  startTime&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  duration&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  wordTimestamps&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Array&lt;/span&gt;&lt;span&gt;&amp;#x3C;{ &lt;/span&gt;&lt;span&gt;word&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;duration&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt; }&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3-generate-the-video&quot;&gt;3. Generate The Video&lt;/h3&gt;
&lt;p&gt;We have everything together now: The completed XML with timestamps, duration, and all assets. It’s now time to generate the video using the creative engine.&lt;/p&gt;
&lt;p&gt;Let’s first add an empty container in our HTML that will be referenced for initiating the creative engine.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  /* Add container for Creative Engine */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;cesdk_container&quot;&lt;/span&gt;&lt;span&gt; className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;invisible mt-8 rounded-lg bg-gray-100&quot;&lt;/span&gt;&lt;span&gt; /&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now initialize the engine. Use &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/overview-e18f40/&quot;&gt;this code&lt;/a&gt; snippet from our documentation.&lt;/p&gt;
&lt;p&gt;We’ll then set up a function that creates a simple composition using the provided VideoBlocks. The engine requires you to first create a scene, append a page to the scene, and then create tracks within the page. The tracks are basically the layers in the timeline. I recommend setting one track as a background track using the following snippet:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Set video track as a background track by connecting the page duration to the video track&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setAlwaysOnBottom&lt;/span&gt;&lt;span&gt;(videotrack, &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setPageDurationSource&lt;/span&gt;&lt;span&gt;(page, videotrack);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Creative Engine provides powerful API calls to style &amp;#x26; manipulate blocks in many ways. Here is an example of how we can animate the images with a slow zoom effect:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; imageZoomAnimation&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;createAnimation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;crop_zoom&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setInAnimation&lt;/span&gt;&lt;span&gt;(image, imageZoomAnimation);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setDuration&lt;/span&gt;&lt;span&gt;(imageZoomAnimation, block.duration);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setBool&lt;/span&gt;&lt;span&gt;(imageZoomAnimation, &lt;/span&gt;&lt;span&gt;&apos;animation/crop_zoom/fade&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Export The Video &amp;#x26; Scene&lt;/strong&gt;&lt;br&gt;
Exporting the video is easy. Just pass the page to the export function. In our example, we’re also saving the scene file so we can edit the video later.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Export video&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; progressCallback&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  renderedFrames&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  encodedFrames&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  totalFrames&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  console.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Progress: ${&lt;/span&gt;&lt;span&gt;Math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;round&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;encodedFrames&lt;/span&gt;&lt;span&gt; /&lt;/span&gt;&lt;span&gt; totalFrames&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;}%`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; blob&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;exportVideo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  page,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;video/mp4&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  progressCallback,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Save scene to string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; sceneData&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; engine.scene.&lt;/span&gt;&lt;span&gt;saveToString&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Create scene blob&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; sceneBlob&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Blob&lt;/span&gt;&lt;span&gt;([sceneData], {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  type: &lt;/span&gt;&lt;span&gt;&apos;text/plain&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;4-add-a-video-editor&quot;&gt;4. Add A Video Editor&lt;/h3&gt;
&lt;p&gt;The last step is to add the video editor for post editing and pass the scene file. With CE.SDK, this effort is reduced to adding a few lines of code. In the &lt;code&gt;init&lt;/code&gt; function, we’re configuring the editor and adding callbacks for the export:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; initEditor&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        const&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          license: &lt;/span&gt;&lt;span&gt;&apos;A-O53TWXK5bfyconUx7e53S5YU7DzjuGpMAH5vvKjLd0zBa6IhsoF7zChy1uCVbj&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          userId: &lt;/span&gt;&lt;span&gt;&apos;guides-user&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          theme: &lt;/span&gt;&lt;span&gt;&apos;dark&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          baseURL: &lt;/span&gt;&lt;span&gt;&apos;&amp;#x3C;https://cdn.img.ly/packages/imgly/cesdk-js/1.44.0/assets&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          role: &lt;/span&gt;&lt;span&gt;&apos;Creator&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          ui: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            elements: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              view: &lt;/span&gt;&lt;span&gt;&apos;default&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              panels: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              navigation: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                position: &lt;/span&gt;&lt;span&gt;&apos;top&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                action: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  save: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  load: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  close: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  download: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  export: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              dock: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                iconSize: &lt;/span&gt;&lt;span&gt;&apos;normal&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// &apos;large&apos; or &apos;normal&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                hideLabels: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; // false or true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          callbacks: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            onUpload: &lt;/span&gt;&lt;span&gt;&apos;local&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            onSave&lt;/span&gt;&lt;span&gt;: (&lt;/span&gt;&lt;span&gt;scene&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              const&lt;/span&gt;&lt;span&gt; element&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;a&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              const&lt;/span&gt;&lt;span&gt; base64Data&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; btoa&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unescape&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;encodeURIComponent&lt;/span&gt;&lt;span&gt;(scene)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              element.&lt;/span&gt;&lt;span&gt;setAttribute&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &apos;href&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                `data:application/octet-stream;base64,${&lt;/span&gt;&lt;span&gt;base64Data&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              element.&lt;/span&gt;&lt;span&gt;setAttribute&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &apos;download&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                `video-${&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; Date&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;toISOString&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;}.scene`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              element.style.display &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;none&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              document.body.&lt;/span&gt;&lt;span&gt;appendChild&lt;/span&gt;&lt;span&gt;(element)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              element.&lt;/span&gt;&lt;span&gt;click&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              document.body.&lt;/span&gt;&lt;span&gt;removeChild&lt;/span&gt;&lt;span&gt;(element)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            onClose&lt;/span&gt;&lt;span&gt;: () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              onClose&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            onLoad: &lt;/span&gt;&lt;span&gt;&apos;upload&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            onDownload: &lt;/span&gt;&lt;span&gt;&apos;download&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            onExport: &lt;/span&gt;&lt;span&gt;&apos;download&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;By following this cookbook, you can streamline the process of AI-generated video creation, making it fast and efficient. This method is especially useful for content creators, educators, and marketers looking to automate video production while maintaining creative control.&lt;br&gt;
Next, try experimenting with video styles, refining AI scripts, or exploring advanced editing.&lt;br&gt;
Feel free to &lt;a href=&quot;https://github.com/imgly/ai-video-creator&quot;&gt;GitHub&lt;/a&gt; repo and share your creations &lt;a href=&quot;https://x.com/imgly&quot;&gt;with us on X&lt;/a&gt;. Happy creating!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3,000+ creative professionals gain early access to new features and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Eray</dc:creator><media:content url="https://blog.img.ly/2025/03/AI-video-generator-tutorial-1.jpg" medium="image"/><category>AI</category><category>CE.SDK</category><category>How-To</category></item><item><title>CE.SDK v1.45 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-45-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-45-0-release-notes/</guid><description>Create, Engage &amp; Build Seamlessly! This release brings Reactions to Android. Record authentic responses to a video. </description><pubDate>Tue, 25 Feb 2025 14:11:57 GMT</pubDate><content:encoded>&lt;p&gt;Welcome to &lt;strong&gt;CE.SDK v1.45!&lt;/strong&gt; We’re expanding creative possibilities and refining the editing experience. &lt;strong&gt;Reactions&lt;/strong&gt; are now available on Android, enabling users to record, edit, and personalize real-time responses.&lt;/p&gt;
&lt;p&gt;We also introduce improvements like smoother development with TypeScript and better text rendering across languages.&lt;/p&gt;
&lt;p&gt;These solutions help creators and developers work smarter, engage better, and deliver high-quality content.&lt;/p&gt;
&lt;h2 id=&quot;record-reactions-to-videos-on-android&quot;&gt;Record Reactions to Videos on Android&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-45/reactions-video-sdk-imgly-ce-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Now available on &lt;strong&gt;Android&lt;/strong&gt;, the popular &lt;strong&gt;Reactions&lt;/strong&gt; feature lets users record and add their real-time responses to videos.&lt;/p&gt;
&lt;p&gt;This is a must-have for engagement-driven content, mirroring interactions on platforms like TikTok and Instagram. Reactions have become a key element of personal branding and connecting with other creators on social media. With Reactions, users can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Connect with their audience&lt;/strong&gt;, duet, respond to trends, or join conversations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add a personal touch&lt;/strong&gt;, react to fan art, viral moments, or inspiring videos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Show thought leadership&lt;/strong&gt;, comment on user questions, industry news, or niche topics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Increase reach&lt;/strong&gt;, boost visibility and interaction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monetize content&lt;/strong&gt;, sell products and showcase collaborations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reactions make content creation fast, easy, and personal.&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-45/timeline-video-editor-sdk-android.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;With our shipped UI, users can select a &lt;strong&gt;vertical or horizontal layout&lt;/strong&gt; to record their reaction video, then &lt;strong&gt;customize&lt;/strong&gt; it with text, filters, adjustments, and more.&lt;/p&gt;
&lt;p&gt;It’s easy to crop, trim, and further adjust your video clip, providing a flexible starting point for seamless editing.&lt;/p&gt;
&lt;p&gt;Try the &lt;a href=&quot;https://play.google.com/store/apps/details?id=ly.img.cesdk.catalog&amp;#x26;hl=gsw&quot;&gt;live demo&lt;/a&gt; and enable Reactions for Android with our &lt;a href=&quot;https://img.ly/docs/cesdk/android/import-media/capture-from-camera/camera-configuration-46afd0/&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;improvements&quot;&gt;Improvements&lt;/h2&gt;
&lt;h3 id=&quot;ensure-text-rendering-across-languages&quot;&gt;Ensure Text Rendering Across Languages&lt;/h3&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-45/font-fallback-sdk.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;When a glyph is unavailable in the selected font, CE.SDK automatically falls back to a configurable default font. This prevents localization issues and ensures seamless text rendering, perfect for your global projects.&lt;/p&gt;
&lt;h3 id=&quot;simplify-development-with-complete-typescript-support&quot;&gt;Simplify Development with Complete TypeScript Support&lt;/h3&gt;
&lt;p&gt;We’ve improved TypeScript support by exposing previously missing types used in our UI APIs. This enhancement, based on user feedback, reduces complexity and ensures smoother development workflows.&lt;/p&gt;
&lt;p&gt;View the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/#v1450--february-19th-2025&quot;&gt;Changelog&lt;/a&gt;. Thanks for reading!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3,000+ creative professionals gain early access to new features and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2025/02/creative-editor-sdk-1-45-imgly.jpg" medium="image"/><category>Release Notes</category><category>Android App Development</category><category>Reactions</category><category>CE.SDK</category></item><item><title>CE.SDK v1.44 Release Notes</title><link>https://img.ly/blog/creative-editor-sdk-v-1-44-0-release-notes/</link><guid isPermaLink="true">https://img.ly/blog/creative-editor-sdk-v-1-44-0-release-notes/</guid><description>Create dynamic content with ease – with multiple clips per track for video editing. Customize your Android Editor with Canvas UI to match your workflow. </description><pubDate>Thu, 06 Feb 2025 07:31:00 GMT</pubDate><content:encoded>&lt;p&gt;Welcome to &lt;strong&gt;CE.SDK v1.44&lt;/strong&gt;! This release brings a range of updates designed to enhance your editing workflow across platforms. Enjoy more vibrant and true-to-life visuals with expanded P3 color support on iOS and Android. On the web, streamline your editing process with the new ability to add multiple clips per track, making timeline management more efficient.&lt;/p&gt;
&lt;p&gt;Let’s dive into the updates!&lt;/p&gt;
&lt;h2 id=&quot;simplify-your-video-editing-workflow&quot;&gt;&lt;strong&gt;Simplify Your Video Editing Workflow&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/1-44/multiple-clips.mp4&quot; controls autoplay muted loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Add &lt;strong&gt;multiple clips to a single track&lt;/strong&gt; on your video timeline! With CE.SDK video editing for the &lt;strong&gt;web&lt;/strong&gt;, you can insert video clips, text, overlays, and more on one track, resulting in a more organized and efficient workspace.&lt;/p&gt;
&lt;p&gt;This update empowers you to create richer, more dynamic sequences while keeping your timeline neat and easy to navigate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maximize Efficiency&lt;/strong&gt;&lt;br&gt;
Simplicity and speed are key. By reducing the need for multiple tracks, this feature helps users to work smarter and faster, allowing them to focus on creative storytelling and deliver engaging content.&lt;/p&gt;
&lt;p&gt;Get started with our Video Editing for Web &lt;a href=&quot;https://img.ly/docs/cesdk/js/starterkits/video-editor-e1nlor/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=releasenotes&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;get-vibrant-colors-with-p3wide-gamut-support&quot;&gt;&lt;strong&gt;Get Vibrant Colors with P3/Wide Gamut Support&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1480px) 1480px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1480&quot; height=&quot;643&quot; src=&quot;https://img.ly/_astro/p3-color-support_Z1lwYnI.webp&quot; srcset=&quot;/_astro/p3-color-support_Z1UYWQz.webp 640w, /_astro/p3-color-support_SraO1.webp 750w, /_astro/p3-color-support_1laDNQ.webp 828w, /_astro/p3-color-support_8xB8z.webp 1080w, /_astro/p3-color-support_ZAYG7z.webp 1280w, /_astro/p3-color-support_Z1lwYnI.webp 1480w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Unlock a broader color range with &lt;strong&gt;P3 color space&lt;/strong&gt; support on &lt;strong&gt;iOS&lt;/strong&gt; and &lt;strong&gt;Android&lt;/strong&gt; devices. This enhancement ensures your designs and content are more vibrant, accurate, and true to life, giving you richer color options for all your projects.&lt;/p&gt;
&lt;p&gt;Set up color spaces with our documentation for &lt;a href=&quot;https://img.ly/docs/cesdk/ios/open-the-editor/uri-resolver-36b624/?language=swift&amp;#x26;platform=ios&amp;#x26;ref=img.ly#editorapicheckp3support/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=releasenotes&quot;&gt;iOS&lt;/a&gt; and &lt;a href=&quot;https://img.ly/docs/cesdk/android/open-the-editor/uri-resolver-36b624/?language=kotlin&amp;#x26;platform=android&amp;#x26;ref=img.ly#working-in-different-color-spaceshttps://img.ly/docs/cesdk/engine/api/editor-utils?language=swift&amp;#x26;platform=ios#editorapicheckp3support/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=releasenotes&quot;&gt;Android&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;tailor-the-android-canvas-menu-to-your-workflows&quot;&gt;Tailor the Android Canvas Menu to Your Workflows&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&quot;Customize the Canvas menu in your Android Editor.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1080px) 1080px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1080&quot; height=&quot;1080&quot; src=&quot;https://img.ly/_astro/canvas-menu-android_1bC5tU.webp&quot; srcset=&quot;/_astro/canvas-menu-android_4f9BT.webp 640w, /_astro/canvas-menu-android_Z24XVRN.webp 750w, /_astro/canvas-menu-android_2unuuF.webp 828w, /_astro/canvas-menu-android_1bC5tU.webp 1080w&quot;&gt;&lt;/p&gt;
&lt;p&gt;💡 The Canvas menu appears when you select a design block, letting you edit its settings, like duplicating a selected image.&lt;/p&gt;
&lt;p&gt;Building on mobile configuration introduced in our &lt;a href=&quot;https://img.ly/blog/creative-editor-sdk-v-1-43-0-release-notes/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=releasenotes&quot;&gt;last release&lt;/a&gt;, we’ve extended customization to the editor Canvas Menu for Android. This update gives you full control over how the menu and its items appear and behave in the editor:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Customization&lt;/strong&gt;: Configure visibility, transition effects, and decoration. Adjust the style of the divider between buttons.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Item List Control&lt;/strong&gt;: Modify, add, reorder, or hide menu items.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flexible Button and Divider Configuration&lt;/strong&gt;: Adjust button appearance, functionality, and divider styles to match your design requirements.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More customizations will be available soon, including for iOS.&lt;br&gt;
Explore the &lt;a href=&quot;https://img.ly/docs/cesdk/android/user-interface/customization/canvas-menu-0d2b5b/&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;improvements&quot;&gt;Improvements&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Switch the Editor Language without Restarting&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1480px) 1480px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1480&quot; height=&quot;643&quot; src=&quot;https://img.ly/_astro/switch-language-sdk_Z2aCc2O.webp&quot; srcset=&quot;/_astro/switch-language-sdk_2pYR9S.webp 640w, /_astro/switch-language-sdk_2reuBp.webp 750w, /_astro/switch-language-sdk_1kBPX5.webp 828w, /_astro/switch-language-sdk_ZFSNKC.webp 1080w, /_astro/switch-language-sdk_16P40f.webp 1280w, /_astro/switch-language-sdk_Z2aCc2O.webp 1480w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Easily switch languages in our web editor without restarting it. This update lets you update the UI language instantly via API, streamlining localization. Check our &lt;a href=&quot;https://img.ly/docs/cesdk/js/user-interface/localization-508e20/?ref=img.ly#i18n-apihttps://img.ly/docs/cesdk/engine/api/editor-utils?language=kotlin&amp;#x26;platform=android#working-in-different-color-spaceshttps://img.ly/docs/cesdk/engine/api/editor-utils?language=swift&amp;#x26;platform=ios#editorapicheckp3support/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=releasenotes&quot;&gt;documentation&lt;/a&gt;, and translate right away!&lt;/p&gt;
&lt;h2 id=&quot;upcoming&quot;&gt;Upcoming&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Record Reactions to Videos on Android&lt;/strong&gt;&lt;br&gt;
We’re excited to announce that Reactions will soon be available on Android. Already live in CE.SDK on iOS, this feature (popularized by platforms like TikTok and Instagram) allows users to capture and share their real-time responses to videos. Enhance engagement and provide content creators with immediate, interactive feedback, making your video content even more dynamic.&lt;/p&gt;
&lt;p&gt;View the &lt;a href=&quot;https://img.ly/docs/cesdk/changelog/#v1440--february-6th-2025&quot;&gt;Changelog&lt;/a&gt;. Thanks for reading!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3,000+ creative professionals gain early access to new features and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Neslihan</dc:creator><media:content url="https://blog.img.ly/2025/02/creative-editor-sdk-1-44.jpg" medium="image"/><category>Release Notes</category><category>CE.SDK</category><category>Creative Editing</category><category>App Development</category><category>Android App Development</category></item><item><title>How To: Video Generation With Javascript</title><link>https://img.ly/blog/how-to-video-generation-with-javascript/</link><guid isPermaLink="true">https://img.ly/blog/how-to-video-generation-with-javascript/</guid><description>Learn how to programmatically create videos at scale with Javascript and CreativeEditor SDK.</description><pubDate>Wed, 22 Jan 2025 09:53:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Follow this tutorial to learn how to programmatically create videos in JavaScript directly in the browser.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In 2025 video is firmly established as powerhouse for engagement, gaining even more traction with the rise of short-form videos. After all, as humans, we naturally resonate with video content more than any other type of media.&lt;/p&gt;
&lt;p&gt;The problem is that video generation is challenging, and doing it within the browser through JavaScript makes things even more complex. Fortunately, production-grade solutions like &lt;a href=&quot;https://img.ly/docs/cesdk/js/starterkits/video-editor-e1nlor/&quot;&gt;CreativeEditor SDK (CE.SDK)&lt;/a&gt; make the process not only possible but also easy to implement.&lt;/p&gt;
&lt;p&gt;In this guide, you will learn how to programmatically generate videos in the browser via JavaScript using CreativeEditor SDK. We will cover various applications, including merging videos, adding audio tracks, and even integrating AI features.&lt;/p&gt;
&lt;p&gt;Let’s dive in!&lt;/p&gt;
&lt;h2 id=&quot;why-programmatic-video-generation-matters&quot;&gt;Why Programmatic Video Generation Matters&lt;/h2&gt;
&lt;p&gt;Videos are dominating social media, marketing, and online platforms such as e-commerce platforms (e.g., to showcase products). Numerous studies have proven that &lt;a href=&quot;https://thesocialshepherd.com/blog/video-marketing-statistics&quot;&gt;video is the most effective form of media&lt;/a&gt; for marketing, as it resonates deeply with us.&lt;/p&gt;
&lt;p&gt;As the demand for personalized and dynamic content increases, traditional video production methods are becoming inefficient. The proliferation of channels with different demands on size and video quality as well as the need to create personalized videos at scale means that automated video creation is becoming indispensable. Most existing solutions run batch processing of videos on the server after gathering input data from various source. However, while server-side processing quickly becomes costly and introduces significant communication overhead client devices have become more powerful than ever.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img.ly/products/creative-sdk/&quot;&gt;CreativeEditor SDK&lt;/a&gt; bridges that gap by simplifying programmatic video generation in JavaScript within modern browsers. With CE.SDK, you can automate repetitive tasks and define scalable, personalized, and engaging video creation workflows, ensuring each generated video resonates with its target audience.&lt;/p&gt;
&lt;h2 id=&quot;get-started-with-cesdk-for-javascript&quot;&gt;Get Started with CE.SDK for JavaScript&lt;/h2&gt;
&lt;p&gt;Now that we established why programmatic video generation is important, you are ready to get started with the tool designed for it: CreativeEditor SDK.&lt;/p&gt;
&lt;p&gt;Learn how to integrate CE.SDK for video editing into a vanilla JavaScript application!&lt;/p&gt;
&lt;p&gt;You can access the code for this tutorial on &lt;a href=&quot;https://github.com/imgly/video-generation-js&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;/h3&gt;
&lt;p&gt;The only prerequisites to follow this tutorial are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A modern browser&lt;/strong&gt;: CreativeEditor SDK runs directly in your browser’s JavaScript engine, so no additional setup is required. Any &lt;a href=&quot;https://caniuse.com/wasm&quot;&gt;browser supporting WASM&lt;/a&gt; is enough.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A CreativeEditor SDK license&lt;/strong&gt;: If you do not have one yet, &lt;a href=&quot;https://img.ly/docs/cesdk/&quot;&gt;sign up for a free trial&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your web application uses Node.js, ensure you have the &lt;a href=&quot;https://nodejs.org/en/download&quot;&gt;latest stable versions of both Node.js and NPM installed&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;import-the-library&quot;&gt;Import the library&lt;/h3&gt;
&lt;p&gt;In a vanilla JavaScript application, create a JavaScript module file (e.g., video-editor.js) and import the CreativeEditor SDK engine library inside it:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEngine &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;&amp;#x3C;https://cdn.img.ly/packages/imgly/cesdk-engine/1.42.0/index.js&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In this example, the SDK is served from our CDN for convenience. In a production environment, it is recommended to host all &lt;a href=&quot;https://img.ly/docs/cesdk/js/serve-assets-b0827c/&quot;&gt;assets and libraries on your own servers&lt;/a&gt; for improved control and performance.&lt;/p&gt;
&lt;p&gt;To use the video-editor.js module in an HTML page, import it with this line:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;module&quot;&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;video-editor.js&quot;&lt;/span&gt;&lt;span&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules&quot;&gt;type=“module”&lt;/a&gt; attribute tells the browser to treat the script as an ES6 module, so that you can use import and export statements.&lt;/p&gt;
&lt;p&gt;Alternatively, if you are using a module bundler like Webpack, Rollup, Parcel, or Vite, add the &lt;a href=&quot;https://www.npmjs.com/package/@cesdk/engine&quot;&gt;@cesdk/engine&lt;/a&gt; npm package to your project’s dependencies:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @cesdk/cesdk-js&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, you can then import the headless SDK into your JavaScript code as follows:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEngine &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@cesdk/engine&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Well done!&lt;/p&gt;
&lt;h2 id=&quot;setting-up-your-environment&quot;&gt;&lt;strong&gt;Setting Up Your Environment&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In your JavaScript module, right below the library import, initialize the &lt;a href=&quot;https://img.ly/docs/cesdk/node/get-started/overview-e18f40/&quot;&gt;CreativeEditor SDK headless engine&lt;/a&gt; using the following code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// src/video-editor.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEngine &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;&amp;#x3C;https://cdn.img.ly/packages/imgly/cesdk-engine/1.42.0/index.js&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// your CE.SDK license and user configs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  license: &lt;/span&gt;&lt;span&gt;&apos;&amp;#x3C;YOUR_LICENSE&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;CreativeEngine.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(config).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;engine&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // attach the engine canvas to the DOM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  document.&lt;/span&gt;&lt;span&gt;getElementById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;cesdk_container&apos;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(engine.element);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // do something with your instance of CreativeEditor SDK...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // detach the engine and clean up its resource&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  engine.element.&lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  engine.&lt;/span&gt;&lt;span&gt;dispose&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;#x3C;YOUR_LICENSE&gt;&lt;/code&gt; with the license key provided in your CreativeEditor SDK subscription.&lt;/p&gt;
&lt;p&gt;Ensure that the HTML page importing &lt;code&gt;video-editor.js&lt;/code&gt; contains the following &lt;code&gt;&amp;#x3C;div&gt;&lt;/code&gt; element with the &lt;code&gt;cesdk_container&lt;/code&gt; ID:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;cesdk_container&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;width: 100%; height: 100vh;&quot;&lt;/span&gt;&lt;span&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/overview-e18f40/&quot;&gt;&lt;code&gt;CreativeEngine.init()&lt;/code&gt;&lt;/a&gt; method will mount the editor engine component within this div.&lt;/p&gt;
&lt;p&gt;Congratulations! You have successfully integrated the video editing engine.&lt;/p&gt;
&lt;h2 id=&quot;load-a-video&quot;&gt;&lt;strong&gt;Load a Video&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Use the logic below inside the body of the CreativeEndine.init() callback function to load a video in CE.SDK:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// initialize a new video scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; scene&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.scene.&lt;/span&gt;&lt;span&gt;createVideo&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a page block and attach it to the scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; page&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;page&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;appendChild&lt;/span&gt;&lt;span&gt;(scene, page);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the dimensions of the video page&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setWidth&lt;/span&gt;&lt;span&gt;(page, &lt;/span&gt;&lt;span&gt;720&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setHeight&lt;/span&gt;&lt;span&gt;(page, &lt;/span&gt;&lt;span&gt;1280&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a graphic block to hold the video content&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// and set its shape to a rectangle&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; video&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;graphic&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setShape&lt;/span&gt;&lt;span&gt;(video, engine.block.&lt;/span&gt;&lt;span&gt;createShape&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;rect&apos;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a fill type for the video and set the video file URI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; videoFill&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;createFill&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;video&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  videoFill,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;fill/video/fileURI&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;&amp;#x3C;https://cdn.img.ly/assets/demo/v2/ly.img.video/videos/pexels-drone-footage-of-a-surfer-barrelling-a-wave-12715991.mp4&gt;&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// apply the video fill to the video graphic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setFill&lt;/span&gt;&lt;span&gt;(video, videoFill);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a track block to manage the video timeline&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// and attache the track to the page and the video graphic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// to the track&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; track&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;track&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;appendChild&lt;/span&gt;&lt;span&gt;(page, track);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;appendChild&lt;/span&gt;&lt;span&gt;(track, video);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// make the track cover the parent block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;fillParent&lt;/span&gt;&lt;span&gt;(track);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This initializes a video scene using &lt;a href=&quot;https://img.ly/docs/cesdk/js/concepts/scenes-e8596d/&quot;&gt;&lt;code&gt;createVideo()&lt;/code&gt;&lt;/a&gt; and creates a &lt;code&gt;&quot;graphic&quot;&lt;/code&gt; block to display the video in a rectangle, adding it to the page. Next, it loads a video from a remote resource and appends it as a track to the parent block.&lt;/p&gt;
&lt;p&gt;For a complete explanation of how the above code works, &lt;a href=&quot;https://img.ly/docs/cesdk/js/create-video-c41a08/&quot;&gt;refer to the documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you comment out the cleanup part, this is what you should see in your browser application:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 608px) 608px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;608&quot; height=&quot;697&quot; src=&quot;https://img.ly/_astro/JS-video-generation-video-fill_Z2oN5x6.webp&quot; srcset=&quot;/_astro/JS-video-generation-video-fill_Z2oN5x6.webp 608w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Notice how the video from the remote URI has been loaded into the &lt;/p&gt;&lt;div&gt; element where CreativeEditor SDK is attached to the page’s DOM.Time to explore more programmatic video generation features!&lt;p&gt;&lt;/p&gt;
&lt;h2 id=&quot;programmatic-video-generation-features&quot;&gt;Programmatic Video Generation Features&lt;/h2&gt;
&lt;p&gt;Follow the use cases below to see how CE.SDK makes automated video generation in JavaScript easier.&lt;strong&gt;Generate Video in Different Formats&lt;/strong&gt; CE.SDK supports video export in &lt;a href=&quot;https://img.ly/docs/cesdk/js/file-format-support-3c4b2a/&quot;&gt;MP4 format&lt;/a&gt; &lt;a href=&quot;https://img.ly/docs/cesdk/faq/video-support/?platform=node&quot;&gt;&lt;/a&gt;(with MP3 audio) with different resolutions and aspect ratios.To export a video with a specific aspect ratio, first adjust the width and height of the parent block to which the video block is attached:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// specify an aspect ratio of 9:16 (ideal for vertical videos)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setWidth&lt;/span&gt;&lt;span&gt;(page, &lt;/span&gt;&lt;span&gt;720&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setHeight&lt;/span&gt;&lt;span&gt;(page, &lt;/span&gt;&lt;span&gt;1280&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the video will be automatically adjusted to fit the specified dimensions. Horizontal videos will be cropped to match the defined vertical outline of the block, while vertical videos will be rendered as they are within the specified block.&lt;/p&gt;
&lt;p&gt;Next, you can export the video with the configured 9:16 aspect ratio and a given resolution with:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// define the MIME type for the video export (MP4 format)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; mimeType&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &apos;video/mp4&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// define a callback function to track the progress of video rendering and encoding&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; progressCallback&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;renderedFrames&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;encodedFrames&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;totalFrames&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  console.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &apos;Rendered&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// log the number of rendered frames&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    renderedFrames,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &apos;frames and encoded&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// log the number of encoded frames&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    encodedFrames,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &apos;frames out of&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// log the total frames to be processed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    totalFrames&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// define the video export options&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; videoOptions&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  duration: &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// video duration in seconds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  framerate: &lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// video framerate (frames per second)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  targetWidth: &lt;/span&gt;&lt;span&gt;480&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// target video width in pixels (for the resolution)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  targetHeight: &lt;/span&gt;&lt;span&gt;852&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// target video height in pixels (for the resolution)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// export the page as an MP4 video&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; blob&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;exportVideo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  page, &lt;/span&gt;&lt;span&gt;// the page containing the design video block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  mimeType, &lt;/span&gt;&lt;span&gt;// the MIME type for the video (MP4)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  progressCallback, &lt;/span&gt;&lt;span&gt;// the callback to track video rendering progress&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  videoOptions &lt;/span&gt;&lt;span&gt;// the options for the video export&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create an anchor element to trigger the video download&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; anchor&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;a&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;anchor.href &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; URL&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createObjectURL&lt;/span&gt;&lt;span&gt;(blob);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;anchor.download &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;video.mp4&apos;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;// output video name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;anchor.&lt;/span&gt;&lt;span&gt;click&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href=&quot;https://img.ly/docs/cesdk/js/export-save-publish/export/overview-9ed3a8/&quot;&gt;&lt;code&gt;exportVideo()&lt;/code&gt;&lt;/a&gt; function produces a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Blob&quot;&gt;&lt;code&gt;blob video file&lt;/code&gt;&lt;/a&gt; of the specified MIME type. Note that the export occurs over multiple iterations of the update loop, with a frame being encoded in each iteration. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;targetWidth&lt;/code&gt; and &lt;code&gt;targetHeight&lt;/code&gt; options are optional. If used, the video will be resized to fit the target dimensions while maintaining its aspect ratio. This is useful for setting a specific resolution for the output video while preserving the parent block’s width and height on the output video. If omitted, the produced video will match the resolution of the width and height specified with &lt;code&gt;setWidth()&lt;/code&gt; and &lt;code&gt;setHeight()&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;progressCallback()&lt;/code&gt; function will track and display the video generation progress in the browser’s console:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1066px) 1066px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1066&quot; height=&quot;295&quot; src=&quot;https://img.ly/_astro/video-generation-output_Z2wCvPW.webp&quot; srcset=&quot;/_astro/video-generation-output_Z1WN1Sx.webp 640w, /_astro/video-generation-output_Z16737N.webp 750w, /_astro/video-generation-output_Z2wIbfk.webp 828w, /_astro/video-generation-output_Z2wCvPW.webp 1066w&quot;&gt;&lt;/p&gt;
&lt;p&gt;The final lines of the above code snippet trigger the download operation, mimicking the action of clicking a link to download a resource. This is a common JavaScript technique to programmatically trigger a file download.&lt;/p&gt;
&lt;p&gt;Once the export process completes, the output video file (video.mp4) will be automatically downloaded to the browser’s download directory.  Open its properties and this is what you will see:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 404px) 404px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;404&quot; height=&quot;512&quot; src=&quot;https://img.ly/_astro/js-video-generation-file_2s55xB.webp&quot; srcset=&quot;/_astro/js-video-generation-file_2s55xB.webp 404w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Note the video file’s resolution and the fact that its duration is set to 5 seconds, as defined by the &lt;code&gt;duration&lt;/code&gt; attribute.&lt;/p&gt;
&lt;p&gt;These options enable you to easily create clips with different lengths, aspect ratios, and resolutions, optimized for various audiences and &lt;a href=&quot;https://img.ly/industries/social-media/&quot;&gt;social media platforms like LinkedIn, Instagram, Facebook, X, TikTok, YouTube, and more&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;add-audio-tracks&quot;&gt;Add Audio Tracks&lt;/h3&gt;
&lt;p&gt;Adding an audio track for narration or background music to your clip is straightforward. First, create an &lt;a href=&quot;https://img.ly/docs/cesdk/js/create-video-c41a08/&quot;&gt;“audio” block&lt;/a&gt; and add your audio resource to it:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; audio&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;audio&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;appendChild&lt;/span&gt;&lt;span&gt;(page, audio);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  audio,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;audio/fileURI&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;https://cdn.img.ly/assets/demo/v1/ly.img.audio/audios/far_from_home.m4a&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, you can easily adjust the volume, and apply fade-in and fade-out effects as follows:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the volume level to 80%&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setVolume&lt;/span&gt;&lt;span&gt;(audio, &lt;/span&gt;&lt;span&gt;0.8&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// start the audio after 1 second of playback&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setTimeOffset&lt;/span&gt;&lt;span&gt;(audio, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the audio block&apos;s duration to 5 seconds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setDuration&lt;/span&gt;&lt;span&gt;(audio, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is breakdown of the functions used above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/js/create-video/control-daba54/&quot;&gt;&lt;strong&gt;&lt;code&gt;setVolume()&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;: Adjusts the audio volume of the block, with a range from 0 (0%) to 1 (100%).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;setTimeOffset()&lt;/code&gt;&lt;/strong&gt;: Sets the time offset of the block relative to its parent. This determines when the block starts playing in the timeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;setDuration()&lt;/code&gt;&lt;/strong&gt;: Sets the playback duration of the audio block in seconds, defining how long the block will play during the scene.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this example, the audio starts at the 1-second mark and plays for 5 seconds (from 1s to 6s), with the volume set to 80% of the original.&lt;/p&gt;
&lt;h3 id=&quot;merge-videos&quot;&gt;&lt;strong&gt;Merge Videos&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;To stitch multiple video clips together in CE.SDK, you first need to import and create separate video blocks:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create the first video block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; video1&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;graphic&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setShape&lt;/span&gt;&lt;span&gt;(video1, engine.block.&lt;/span&gt;&lt;span&gt;createShape&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;rect&apos;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; videoFill1&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;createFill&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;video&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  videoFill1,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;fill/video/fileURI&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;https://cdn.img.ly/assets/demo/v2/ly.img.video/videos/pexels-drone-footage-of-a-surfer-barrelling-a-wave-12715991.mp4&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setFill&lt;/span&gt;&lt;span&gt;(video1, videoFill1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create the second video block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; video2&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;graphic&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setShape&lt;/span&gt;&lt;span&gt;(video2, engine.block.&lt;/span&gt;&lt;span&gt;createShape&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;rect&apos;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; videoFill2&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; engine.block.&lt;/span&gt;&lt;span&gt;createFill&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;video&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  videoFill2,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;fill/video/fileURI&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;https://cdn.img.ly/assets/demo/v2/ly.img.video/videos/pexels-kampus-production-8154913.mp4&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setFill&lt;/span&gt;&lt;span&gt;(video2, videoFill2);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, you have two different video clips loaded from separate video files.&lt;/p&gt;
&lt;p&gt;Now, assume you want to produce a 10-second video that includes both clips. Start by setting the duration of the page block to 10 seconds with the &lt;a href=&quot;https://img.ly/docs/cesdk/js/create-video/control-daba54/&quot;&gt;&lt;code&gt;setDuration()&lt;/code&gt;&lt;/a&gt; method:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.&lt;/span&gt;&lt;span&gt;setDuration&lt;/span&gt;&lt;span&gt;(page, &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, suppose you want the first clip (video1) to play for 7 seconds, and the second clip (video2) to fade in after that and play for 3 seconds (from second 1 to second 4 of the original second clip). This is how you can set that up:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the duration of the first and second video clips&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setDuration(video1, 7); // video1 plays for 7 seconds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setDuration(video2, 3); // video2 plays for 3 seconds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// wait for the second video to be fully loaded before applying the trim options&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;await engine.block.forceLoadAVResource(videoFill2);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// trim the second video to start at 1 second and play up to second 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setTrimOffset(videoFill2, 1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setTrimLength(videoFill2, 4);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// add a fade-in animation to the second video&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const fadeInAnimation = engine.block.createAnimation(&quot;fade&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setInAnimation(video2, fadeInAnimation);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are the methods used above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;setDuration()&lt;/code&gt;&lt;/strong&gt;: Defines the duration (in seconds) that a video block will be active during playback.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;**forceLoadAVResource()**&lt;/code&gt;: Ensures that the audio or video resource (in this case, &lt;code&gt;video2&lt;/code&gt;) is fully loaded before applying trim operations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;setTrimOffset()&lt;/code&gt;&lt;/strong&gt;: Sets the start point (in seconds) within the video where playback begins.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;setTrimLength()&lt;/code&gt;&lt;/strong&gt;: Defines the length of the video to be played from the trim offset.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/js/animation/overview-6a2ef2/&quot;&gt;&lt;strong&gt;&lt;code&gt;createAnimation()&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;: Creates a fade-in animation for the second video (&lt;code&gt;video2&lt;/code&gt;) to smoothly transition into the clip.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, add both video blocks to the track block for playback:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const track = engine.block.create(&quot;track&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.appendChild(page, track);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.appendChild(track, video1); // add the first video to the track&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.appendChild(track, video2); // add the second video to the track&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.fillParent(track);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result will be:&lt;/p&gt;
&lt;figure class=&quot;kg-card kg-embed-card&quot;&gt;&lt;iframe width=&quot;225&quot; height=&quot;400&quot; src=&quot;https://blog.img.ly/2025/01/video-1.mp4&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/figure&gt;
&lt;p&gt;Note how the second clip fades in after 7 seconds of the first clip, lasting for 3 seconds as specified.&lt;/p&gt;
&lt;h3 id=&quot;incorporate-text-variables&quot;&gt;&lt;a href=&quot;https://img.ly/blog/how-to-video-generation-with-javascript//#Incorporate-Text-Variables&quot;&gt;&lt;/a&gt;Incorporate Text Variables&lt;/h3&gt;
&lt;p&gt;Now, suppose you want to display cool words or messages in your videos. You can easily achieve this by adding a &lt;a href=&quot;https://img.ly/docs/cesdk/js/text/edit-c5106b/&quot;&gt;&lt;code&gt;&quot;text&quot;&lt;/code&gt; block&lt;/a&gt; to your page, as shown below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const text = engine.block.create(&quot;text&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the vluae of the text variable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.replaceText(text, &quot;Surfing\nis\nCOOL!&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the text color to white and semi-transparent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setTextColor(text, { r: 255.0, g: 255.0, b: 255.0, a: 0.8 });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set the font size for the text&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setTextFontSize(text, 30);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// positioning the text on an absolute position on the video&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setWidthMode(text, &quot;Auto&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setHeightMode(text, &quot;Auto&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setPositionX(text, 130);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.setPositionY(text, 800);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// append the text block to the page&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;engine.block.appendChild(page, text);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The video canvas will now display a white “Surfing is COOL!” message as follows:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 514px) 514px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;514&quot; height=&quot;812&quot; src=&quot;https://img.ly/_astro/js-video-generation-surfing_1WpaM3.webp&quot; srcset=&quot;/_astro/js-video-generation-surfing_1WpaM3.webp 514w&quot;&gt;&lt;/p&gt;
&lt;p&gt;In this example, the content of the text block is static. However, it can easily be retrieved from a database or any other source for programmatic video generation with different messages, including personalized ones for tailored outreach (e.g., for custom greetings or offers).&lt;/p&gt;
&lt;h2 id=&quot;advanced-use-case-prompt-based-video-generation-using-ai&quot;&gt;&lt;a href=&quot;https://img.ly/blog/how-to-video-generation-with-javascript//#Advanced-Use-Case-Prompt-Based-Video-Generation-Using-AI&quot;&gt;&lt;/a&gt;Advanced Use Case: Prompt-Based Video Generation Using AI&lt;/h2&gt;
&lt;p&gt;As highlighted in our &lt;a href=&quot;https://www.linkedin.com/posts/eray-basar-57684711_imagine-building-a-full-video-app-in-a-single-activity-7262806525797089280-S_L8?utm_source=share&amp;#x26;utm_medium=member_desktop&quot;&gt;recent LinkedIn post&lt;/a&gt;, &lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; has just experimented with an MVP that turns keywords into fully edited short videos, complete with a script, voiceover, and visuals, all automated.&lt;/p&gt;
&lt;p&gt;That is made possible by integrating CE.SDK with an LLM for coding and scriptwriting, &lt;a href=&quot;https://elevenlabs.io/&quot;&gt;ElevenLabs&lt;/a&gt; for voice synthesis, and Flux (via &lt;a href=&quot;https://fal.ai/&quot;&gt;fal.ai&lt;/a&gt;) for visuals. Specifically, the LLM uses CE.SDK for video composition, animation, and rendering.&lt;/p&gt;
&lt;p&gt;This is just the beginning, showing how AI can be combined with CE.SDK to programmatically generate video scripts, or even templates. A possible scenario would be to use the &lt;a href=&quot;https://img.ly/docs/cesdk/js/user-interface/ui-extensions-d194d1/&quot;&gt;Creative Editor SDK plugin API&lt;/a&gt; to extend CE.SDK with custom plugins that adds AI directly to the design editor engine.&lt;/p&gt;
&lt;p&gt;For example, you could develop a plugin with an LLM integration that allows users to input a prompt like: &lt;em&gt;“Create a 15-second video with the text ‘Welcome to our App!’ and upbeat background music.”&lt;/em&gt; The LLM will process the request, using Creative Editor SDK to automate video creation by leveraging its powerful features.&lt;/p&gt;
&lt;p&gt;Alternatively, the AI could produce a video that you can then automatically edit and enhance using CE.SDK capabilities. One thing is certain: the possibilities are endless with CE.SDK + AI!&lt;/p&gt;
&lt;h2 id=&quot;conclusion-the-future-of-programmatic-video-generation&quot;&gt;&lt;a href=&quot;https://img.ly/blog/how-to-video-generation-with-javascript//#Conclusion-The-Future-of-Programmatic-Video-Generation&quot;&gt;&lt;/a&gt;Conclusion: The Future of Programmatic Video Generation&lt;/h2&gt;
&lt;p&gt;CE.SDK for JavaScript offers exceptional versatility in automating video workflows, allowing you to easily generate, edit, and render videos with just a few lines of code. You can stitch multiple video files, add background audio tracks, and incorporate dynamic text variables to finally produce videos in the browser, all thanks to the CE.SDK headless engine.&lt;/p&gt;
&lt;p&gt;Looking ahead, AI integration with CE.SDK is unlocking even more powerful possibilities, such as prompt-based video content creation and automatic editing directly in the browser.&lt;/p&gt;
&lt;p&gt;With the headless engine provided by CreativeEditor SDK, programmatic video generation in JavaScript can be implemented in just a few minutes. Explore the video capabilities of CE.SDK and &lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/overview-e18f40/&quot;&gt;dive into the docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stay tuned for more updates, and please &lt;a href=&quot;https://img.ly/forms/contact-sales/&quot;&gt;reach out&lt;/a&gt; if you have any questions. Thank you for reading.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Over 3,000 creative professionals gain early access to our new features, demos, and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;</content:encoded><dc:creator>Antonello</dc:creator><dc:creator>Jan</dc:creator><media:content url="https://blog.img.ly/2025/01/javascript-generate-video.jpg" medium="image"/><category>Video Editing</category><category>Creative Automation</category><category>CE.SDK</category></item><item><title>A Modern JavaScript Video Editor: Integration Guide</title><link>https://img.ly/blog/a-modern-javascript-video-editor-integration-guide/</link><guid isPermaLink="true">https://img.ly/blog/a-modern-javascript-video-editor-integration-guide/</guid><description>Learn how to integrate IMG.LY&apos;s Javascript video editor into your web app and how to best leverage its capabilities.</description><pubDate>Thu, 16 Jan 2025 15:29:04 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Discover how to integrate&lt;/em&gt; &lt;a href=&quot;https://img.ly/docs/cesdk/js/starterkits/video-editor-e1nlor/&quot;&gt;&lt;em&gt;IMG.LY’s JavaScript video editor&lt;/em&gt;&lt;/a&gt; &lt;em&gt;into your web application and unlock its full range of features.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Video content has always been a powerhouse for engagement, becoming even more impactful with the rise of short-form videos. Platforms like YouTube and TikTok have built their empires on video content, as that remains the preferred medium for both creating and consuming information.&lt;/p&gt;
&lt;p&gt;Not only have those platforms changed how we consume information, but they have also transformed user behavior. We do not just want to watch videos. We want to create them, expecting the process to be both simple and professional.&lt;/p&gt;
&lt;p&gt;Here is why embedding video creation and editing capabilities directly into your website, web or mobile application can significantly boost user engagement and satisfaction.&lt;/p&gt;
&lt;p&gt;In this guide, you will learn how to integrate a JavaScript video editor using CreativeEditor SDK (CE.SDK). We will explore when it is most useful and what customizations it supports to suit your unique needs.&lt;/p&gt;
&lt;p&gt;Want to jump into the code? For a quick start, visit our &lt;a href=&quot;https://github.com/imgly/cesdk-web-examples/tree/showcases/integrate-with-vanilla-js&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s dive in!&lt;/p&gt;
&lt;h2 id=&quot;why-does-your-javascript-web-app-need-a-video-editor&quot;&gt;Why Does Your JavaScript Web App Need a Video Editor?&lt;/h2&gt;
&lt;p&gt;The world of content is constantly evolving, from text to images, from static visuals to long-form videos, and now from long videos to bite-sized clips. What stays consistent is that &lt;a href=&quot;https://www.idomoo.com/blog/surprising-video-engagement-statistics/&quot;&gt;video content resonates deeply with us as humans&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;No wonder, &lt;a href=&quot;https://www.statista.com/statistics/1285960/top-downloaded-mobile-apps-worldwide/&quot;&gt;TikTok tops global app download charts&lt;/a&gt;, while &lt;a href=&quot;https://www.similarweb.com/top-websites/&quot;&gt;YouTube, Facebook, and Instagram rank among the most visited sites&lt;/a&gt; right after Google. These platforms have not just built their empires on video. They have revolutionized how we think about video production.&lt;/p&gt;
&lt;p&gt;They set the gold standard by enabling anyone to create professional-looking videos with minimal effort, offering tools for adding filters, overlays, audio, and text in just a few clicks. This ease of use has made intuitive video editing a must-have for web applications featuring social media integration, marketing ambitions, or content management capabilities.&lt;/p&gt;
&lt;p&gt;By embedding a user-friendly JavaScript video editor in your application, you can ride this trend, providing a feature billions of users are already familiar with. The payoff? Lower barriers to user-generated content, enhanced engagement, and wider content distribution.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img.ly/products/creative-sdk/&quot;&gt;CreativeEditor SDK&lt;/a&gt; from &lt;a href=&quot;https://IMG.LY&quot;&gt;IMG.LY&lt;/a&gt; delivers a seamless, high-performance, and feature-rich JavaScript solution for in-browser design, video, and photo editing, ready to meet your users’ expectations.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-adding-a-video-editor-in-javascript&quot;&gt;Getting Started: Adding a Video Editor in JavaScript&lt;/h2&gt;
&lt;p&gt;Follow this step-by-step guide to learn how to integrate a JavaScript video editor into your site using CreativeEditor SDK.&lt;/p&gt;
&lt;p&gt;Get started with integrating CE.SDK in a vanilla JavaScript application!&lt;/p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;/h3&gt;
&lt;p&gt;CreativeEditor SDK runs directly in your browser’s JavaScript engine, so no specific prerequisites are needed.&lt;/p&gt;
&lt;p&gt;If your web application relies on Node.js, ensure that you have the &lt;a href=&quot;https://nodejs.org/en/download&quot;&gt;latest stable versions of Node.js and NPM installed&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;installation-and-library-import&quot;&gt;Installation and Library Import&lt;/h3&gt;
&lt;p&gt;In a vanilla JavaScript application, create a JavaScript module file (e.g., video-editor.js) and import the CreativeEditorSDK library:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEditorSDK &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;&amp;#x3C;https://cdn.img.ly/packages/imgly/cesdk-js/1.42.0/index.js&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In this example, the SDK is served from our CDN for convenience. In a production environment, you should &lt;a href=&quot;https://img.ly/docs/cesdk/js/serve-assets-b0827c/&quot;&gt;host assets on your own servers&lt;/a&gt; for improved control and performance.&lt;/p&gt;
&lt;p&gt;Alternatively, if you are using a bundler like Webpack, Rollup, Parcel, or Vite, and you want to integrate the CreativeEditor module within your existing project, simply add the &lt;a href=&quot;https://www.npmjs.com/package/@cesdk/cesdk-js&quot;&gt;@cesdk/cesdk-js&lt;/a&gt; npm package as a dependency to your project:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; [@cesdk/cesdk-js](&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;https://www.npmjs.com/package/@cesdk/cesdk-js&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then import it as below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEditorSDK&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; &quot;@cesdk/cesdk-js&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Well done!&lt;/p&gt;
&lt;h3 id=&quot;initialize-the-video-editor&quot;&gt;Initialize the Video Editor&lt;/h3&gt;
&lt;p&gt;In your JavaScript module, right below the library import, initialize CreativeEditor SDK with the following logic:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// src/video-editor.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEditorSDK &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;&amp;#x3C;https://cdn.img.ly/packages/imgly/cesdk-js/1.42.0/index.js&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// your CE.SDK license and user configs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  license: &lt;/span&gt;&lt;span&gt;&apos;&amp;#x3C;YOUR_LICENSE&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  userId: &lt;/span&gt;&lt;span&gt;&apos;&amp;#x3C;YOUR_USER_ID&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;CreativeEditorSDK.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;#cesdk_container&apos;&lt;/span&gt;&lt;span&gt;, config).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;editor&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // do something with your instance of CreativeEditor SDK...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // when done, clean up and free up resources&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  editor.&lt;/span&gt;&lt;span&gt;dispose&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;#x3C;YOUR_LICENSE&gt;&lt;/code&gt; with the license key you get from CreativeEditor SDK and &lt;code&gt;&amp;#x3C;YOUR_USER_ID&gt;&lt;/code&gt; with your user ID. The user ID is optional and helps track MAUs (Monthly Active Users) across different devices.&lt;/p&gt;
&lt;p&gt;To integrate the video-editor.js file, import it into your HTML page like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;module&quot;&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;video-editor.js&quot;&lt;/span&gt;&lt;span&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules&quot;&gt;type=“module”&lt;/a&gt; attribute. This tells the browser to treat the script as an ES6 module, so that you can use import and export statements within your JavaScript code.&lt;/p&gt;
&lt;p&gt;Make sure the same HTML page includes the following div element where the video editor will be embedded:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;cesdk_container&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;width: 100%; height: 100vh;&quot;&lt;/span&gt;&lt;span&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will load the video editor with the default video preset, giving users the ability to trim, cut, apply filters, add text overlays, include music, and more to enhance their videos.&lt;/p&gt;
&lt;p&gt;Congratulations, you have successfully integrated the video editor!&lt;/p&gt;
&lt;h2 id=&quot;creativeeditor-sdk-javascript-video-editing-api-for-web-desktop-and-mobile&quot;&gt;CreativeEditor SDK: JavaScript Video Editing API for Web, Desktop, and Mobile&lt;/h2&gt;
&lt;p&gt;You just saw how to integrate the CE.SDK into a browser application. Yet, do not forget that the SDK supports a wide variety of frameworks and libraries, including mobile and web applications.&lt;/p&gt;
&lt;h3 id=&quot;web-framework-support&quot;&gt;Web Framework Support&lt;/h3&gt;
&lt;p&gt;CE.SDK is designed to work with several popular JavaScript frameworks and libraries. For more detailed integration instructions, take a look at the official page on the documentation for each framework:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/react/get-started/overview-e18f40/&quot;&gt;React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/angular/get-started/overview-e18f40/&quot;&gt;Angular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/vue/get-started/overview-e18f40/&quot;&gt;Vue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/svelte/get-started/overview-e18f40/&quot;&gt;Svelte&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/js/get-started/overview-e18f40/&quot;&gt;JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, the SDK is available for headless mode and works well in a &lt;a href=&quot;https://img.ly/docs/cesdk/node/get-started/overview-e18f40/&quot;&gt;Node.js environment&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;cross-platform-support&quot;&gt;Cross-Platform Support&lt;/h3&gt;
&lt;p&gt;One of the standout features of CreativeEditor SDK is its cross-platform philosophy. This extends beyond JavaScript ecosystems for the web, and includes mobile (iOS and Android) and desktop, thanks to support for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/react-native/get-started/overview-e18f40/&quot;&gt;React Native&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/docs/cesdk/electron/get-started/overview-e18f40/&quot;&gt;Electron&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is made possible through a powerful engine that powers your app via features like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unified API&lt;/strong&gt;: The same underlying API is shared across web, desktop, iOS, and Android applications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-Platform Feature Parity&lt;/strong&gt;: CE.SDK guarantees that features are available consistently across platforms. Since core functionality is implemented at the engine level, features you use on one platform will be available on others, with only slight differences in release timelines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interoperable Designs&lt;/strong&gt;: Designs created in the editor component on one platform work on all platforms supported by CE.SDK. Whether a user is designing on iOS, Android, or the web, their design files can be imported seamlessly between platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Native iOS and Android libraries, along with other frameworks, are also available. &lt;a href=&quot;https://img.ly/docs/cesdk/&quot;&gt;Learn more in our documentation!&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;javascript-video-editor-use-cases&quot;&gt;JavaScript Video Editor Use Cases&lt;/h2&gt;
&lt;p&gt;It is time to explore some key use cases. Let’s see how the unique features of the CreativeEditor SDK can cover many scenarios!&lt;/p&gt;
&lt;h3 id=&quot;social-media-publishing&quot;&gt;Social Media Publishing&lt;/h3&gt;
&lt;p&gt;CreativeEditor SDK features what users need to create engaging and easy-to-share videos optimized for popular social media platforms like Instagram, TikTok, YouTube, LinkedIn, and more. This is possible due to a large set of capabilities, which include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reusable Templates&lt;/strong&gt;: Users can either design their own templates and share them with the community or download those created by others. This variety of ready-to-use templates for different scenarios helps users skip the daunting blank canvas to bring their ideas to life. Explore various templates in our &lt;a href=&quot;https://img.ly/demos/video-ui/web/&quot;&gt;video editor demo&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Music and Audio Library&lt;/strong&gt;: In CE.SDK, adding audio to videos is simple and intuitive. Given the impact of audio, users can set the tone with music or narration in just a few clicks, creating a more immersive atmosphere for their content.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Animations&lt;/strong&gt;: The SDK includes a &lt;a href=&quot;https://img.ly/docs/cesdk/js/animation/overview-6a2ef2/&quot;&gt;wide selection of animations&lt;/a&gt; to enhance the design elements positioned within video scenes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After creating a video within your web app, users can export it directly from CE.SDK in the appropriate formats and aspect ratios for their target social media platforms.&lt;/p&gt;
&lt;h3 id=&quot;product-showcase-for-e-commerce-applications&quot;&gt;Product Showcase for E-Commerce Applications&lt;/h3&gt;
&lt;p&gt;Images have long been a simple yet powerful tool for showcasing products on e-commerce platforms, and sites like eBay, Amazon, AliExpress, and Walmart have relied on them for years (and still do!).&lt;/p&gt;
&lt;p&gt;However, in recent years, customer expectations have shifted. Today’s buyers crave more interactive and immersive ways to visualize products. They want to see how items look and perform in real-world settings.&lt;/p&gt;
&lt;p&gt;Short, dynamic product videos offer a superior presentation experience. According to &lt;a href=&quot;https://www.retaildive.com/spons/the-future-of-e-commerce-is-video-5-undeniable-consumer-stats/711062/&quot;&gt;an analysis by Firework&lt;/a&gt;, video content increases purchase likelihood by 51%, highlighting its undeniable impact on buying decisions. This is why many sellers have already embraced video to enhance product displays.&lt;/p&gt;
&lt;p&gt;With a CE.SDK-powered JavaScript video editor, producing compelling videos that deliver a seamless, multi-device shopping experience becomes effortless. Plus, reusable templates help you generate unique product videos while maintaining brand consistency.&lt;/p&gt;
&lt;h3 id=&quot;engaging-video-messages-for-sales-outreach&quot;&gt;Engaging Video Messages for Sales Outreach&lt;/h3&gt;
&lt;p&gt;Marketers and sales teams know that cold emails often come across as impersonal and boring. The solution to this challenge? Personalized video messages!&lt;/p&gt;
&lt;p&gt;Customized video messages are proving to be an effective outreach tool, with studies showing &lt;a href=&quot;https://www.tavus.io/post/video-marketing-statistics&quot;&gt;significantly higher conversion rates&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With CreativeEditor SDK, sales and marketing teams can easily create personalized videos tailored to individual clients or leads, making their outreach more engaging and impactful. Unlike traditional email campaigns, personalized videos create a sense of real, one-on-one interaction.&lt;/p&gt;
&lt;p&gt;Additionally, the SDK’s translation features help sales teams break down language barriers, allowing them to reach a global audience. This ensures that the personalized messages resonate with clients from different regions.&lt;/p&gt;
&lt;p&gt;Explore this feature in our &lt;a href=&quot;https://img.ly/demos/language/web/&quot;&gt;translation and internationalization demo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;digital-asset-management&quot;&gt;Digital Asset Management&lt;/h3&gt;
&lt;p&gt;DAM, short for &lt;a href=&quot;https://www.ibm.com/think/topics/digital-asset-management&quot;&gt;Digital Asset Management&lt;/a&gt;, is the process of organizing, storing, and managing digital assets, including video content. As your business grows, an effective DAM system becomes key to enabling multiple teams to easily access and collaborate on assets across different projects.&lt;/p&gt;
&lt;p&gt;CreativeEditor SDK backs DAM workflows by offering powerful tools to organize, edit, and repurpose video content through an embeddable, centralized interface. Its core JavaScript video editor component empowers users to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Effortlessly adapt and customize video assets.&lt;/li&gt;
&lt;li&gt;Ensure brand consistency while automating updates across various assets.&lt;/li&gt;
&lt;li&gt;Edit content efficiently within a collaborative environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although CE.SDK does not provide built-in role-based permissions, it integrates smoothly with backend systems to control user access. In particular, its flexible architecture supports the definition of custom hooks for permission checks to customize the editor’s behavior.&lt;/p&gt;
&lt;h3 id=&quot;automated-video-creation&quot;&gt;Automated Video Creation&lt;/h3&gt;
&lt;p&gt;CreativeEditor SDK streamlines the automation of asset creation by enabling users to generate on-brand video content variations for multiple channels. Thanks to adaptable templates, &lt;a href=&quot;https://img.ly/docs/cesdk/js/create-templates/add-dynamic-content/text-variables-7ecb50/&quot;&gt;dynamic text variables&lt;/a&gt;, and lockable designs, the SDK ensures consistency and brand compliance over all produced videos.&lt;/p&gt;
&lt;p&gt;Given a template, the creative engine automates the generation of countless personalized assets by populating them with resources from various data sources. That eliminates manual effort, reduces design bottlenecks, and accelerates production, making it perfect for scaling campaign-specific videos or building dedicated &lt;a href=&quot;https://img.ly/industries/marketing-tech/&quot;&gt;marketing tech&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;customizing-your-creativeeditor-sdk-instance&quot;&gt;Customizing your CreativeEditor SDK Instance&lt;/h2&gt;
&lt;p&gt;CreativeEditor SDK is not a one-size-fits-all JavaScript video editor. Instead, it is built for flexibility, offering a wide set of customization options to tailor the editor to your unique requirements and brand identity. These include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Theming Options&lt;/strong&gt;: Match the editor’s look to your app’s style with built-in themes, generate new ones using the &lt;a href=&quot;https://img.ly/docs/cesdk/js/user-interface/appearance/theming-4b0938/#using-the-theme-generator&quot;&gt;theme generator&lt;/a&gt;, or create custom themes manually. Explore theming possibilities in our &lt;a href=&quot;https://img.ly/demos/theming/web/&quot;&gt;dedicated demo&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom UI&lt;/strong&gt;: Build entirely bespoke JavaScript video editing user interfaces that align with your specific use case.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Media Library Integration&lt;/strong&gt;: Set up sortable, flexible media libraries and integrate popular third-party libraries like &lt;a href=&quot;https://img.ly/demos/unsplash-image-assets/web/&quot;&gt;Unsplash and others&lt;/a&gt;. Get easy access to external assets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Localization&lt;/strong&gt;: Adapt the editor to different languages and regions with &lt;a href=&quot;https://img.ly/docs/cesdk/js/user-interface/localization-508e20/&quot;&gt;full i18n support&lt;/a&gt;, letting you extend or overwrite any language setting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Toolbar Customization&lt;/strong&gt;: Rearrange toolbar elements, update icons, or rename tools to deliver a tailored user experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these customization options, CreativeEditor SDK ensures your video editor is as unique as your JavaScript application.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Implementing a JavaScript video editor in your web app can greatly improve the user experience and provide a powerful feature to drive higher engagement, retention, and even product distribution. This is true whether you are developing an e-commerce platform, a social media app, a tool for influencers, or a SaaS web solution.&lt;/p&gt;
&lt;p&gt;With the CreativeEditor SDK, adding a fully customizable video editing experience to your web application takes only a few minutes. Explore CE.SDK’s video capabilities and &lt;a href=&quot;https://img.ly/docs/cesdk/flutter/prebuilt-solutions/video-editor-9e533a/&quot;&gt;dive into the docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stay tuned for more updates, and please &lt;a href=&quot;https://img.ly/forms/contact-sales/&quot;&gt;reach out&lt;/a&gt; if you have any questions. Thank you for reading.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Over 3,000 creative professionals gain early access to our new features, demos, and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Antonello</dc:creator><media:content url="https://blog.img.ly/2025/01/video-editor-javascript.jpg" medium="image"/><category>JavaScript</category><category>Video Editor</category><category>CE.SDK</category></item><item><title>A Modern React Design Editor: Integration Guide</title><link>https://img.ly/blog/modern-react-design-editor/</link><guid isPermaLink="true">https://img.ly/blog/modern-react-design-editor/</guid><description>Learn how to integrate IMG.LY&apos;s design editor for React into your web app and how to best leverage its capabilities.</description><pubDate>Thu, 16 Jan 2025 14:38:04 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Learn how to integrate&lt;/em&gt; &lt;a href=&quot;https://img.ly/docs/cesdk/react/starterkits/design-editor-8unj9u/&quot;&gt;&lt;em&gt;IMG.LY’s design editor for React&lt;/em&gt;&lt;/a&gt; &lt;em&gt;into your web app and explore various use cases and customization options.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It is no surprise that content asset generation is a key for businesses in marketing and promotion, as well as for users on social media. Whether it is images or videos, these are the types of posts we engage with and relate to the most as human beings, much more than plain text.&lt;/p&gt;
&lt;p&gt;Most content that resonates with an audience is not created from scratch. Instead, it often comes from pre-designed designs that are reused, repurposed, and adapted to fit different content or goals. That is why adding a design editor to your React application is so valuable.&lt;/p&gt;
&lt;p&gt;In this guide, you will learn how to build a React design editor using the CreativeEditor SDK (also known as &lt;em&gt;CE.SDK&lt;/em&gt;). We will also cover when this is useful and the customization options the editor supports.&lt;/p&gt;
&lt;p&gt;For a quick start, check out the &lt;a href=&quot;https://github.com/imgly/cesdk-web-examples/tree/showcases/integrate-with-react&quot;&gt;GitHub repository&lt;/a&gt; with the full code integration.&lt;/p&gt;
&lt;p&gt;Let’s dive in!&lt;/p&gt;
&lt;h2 id=&quot;why-add-a-design-editor-to-your-react-app&quot;&gt;Why Add a Design Editor to Your React App?&lt;/h2&gt;
&lt;p&gt;Before answering the question, you must understand what a design is and how helpful it can be. In this context, a design can be defined as a set of predefined assets, text overlays, placeholders, and other elements arranged in a specific layout.&lt;/p&gt;
&lt;p&gt;Users can use designs to create images or videos with a particular structure and for specific use cases at scale. Thus, a &lt;a href=&quot;https://img.ly/blog/what-is-a-design-editor-sdk/&quot;&gt;design editor&lt;/a&gt; would enable your users to create personalized assets, and in the case of a React application, directly within the browser.&lt;/p&gt;
&lt;p&gt;Building such a platform is not a piece of cake. A robust design editor requires numerous features, such as intuitive drag-and-drop functionality, template management, image manipulation tools, and more. It also generally requires integrations with third-party services and dependencies to enhance its capabilities.&lt;/p&gt;
&lt;p&gt;Fortunately, an all-in-one solution like &lt;a href=&quot;https://img.ly/products/creative-sdk/&quot;&gt;CreativeEditor SDK&lt;/a&gt; from IMG.LY makes it easy to embed this powerful design editor into your application. It supports various programming languages and technologies, including React. With extensive features and customization options, CE.SDK has no limits on the types of designs users can generate.&lt;/p&gt;
&lt;p&gt;CE.SDK features adaptable design tools for &lt;a href=&quot;https://img.ly/case-studies/&quot;&gt;diverse industries and use cases&lt;/a&gt;, such as social media post creation, digital asset management, and AI-assisted content personalization. That is why it is used by &lt;a href=&quot;https://img.ly/customers/&quot;&gt;hundreds of customers&lt;/a&gt;, including governments, Fortune 500 companies, and dozens of startups.&lt;/p&gt;
&lt;p&gt;CreativeEditor SDK is trusted by companies like Swiss Post, Brother, &lt;a href=&quot;https://img.ly/case-studies/optimizely/&quot;&gt;Optimizely&lt;/a&gt;, HP, and many more.&lt;/p&gt;
&lt;h2 id=&quot;how-to-integrate-a-design-editor-in-react&quot;&gt;How to Integrate a Design Editor in React&lt;/h2&gt;
&lt;p&gt;Follow this step-by-step tutorial to see how to quickly set up a React design editor in your web app using CreativeEditor SDK. For a complete guide, read our tutorial on &lt;a href=&quot;https://img.ly/blog/how-to-build-a-canva-clone-with-ce-sdk/&quot;&gt;building a Canva alternative in React using CE.SDK&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Integrate CE.SDK into your React app using the instructions below!&lt;/p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Before getting started, ensure that you meet the following prerequisites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The latest LTS version of Node.js&lt;/strong&gt;: If you do not have it installed, &lt;a href=&quot;https://nodejs.org/en/download&quot;&gt;download it from the official site&lt;/a&gt; and follow the installation instructions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A React 18+ application&lt;/strong&gt;: If you do not have one set up, follow the instructions below to create it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A CreativeEditor SDK license&lt;/strong&gt;: In case you do not have a license, &lt;a href=&quot;https://img.ly/docs/cesdk/&quot;&gt;sign up for a free trial&lt;/a&gt; or &lt;a href=&quot;https://img.ly/pricing/&quot;&gt;buy a license&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you do not have a React project set up yet, create a new one using &lt;a href=&quot;https://vite.dev/guide/&quot;&gt;Vite&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; vite@latest&lt;/span&gt;&lt;span&gt; my-react-video-editor-app&lt;/span&gt;&lt;span&gt; --&lt;/span&gt;&lt;span&gt; --template&lt;/span&gt;&lt;span&gt; react&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Open your project in a JavaScript IDE, and you are all set to start coding!&lt;/p&gt;
&lt;h3 id=&quot;install-cesdk&quot;&gt;&lt;strong&gt;Install CE.SDK&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Install CE.SDK by adding the &lt;a href=&quot;https://www.npmjs.com/package/@cesdk/cesdk-js&quot;&gt;@cesdk/cesdk-js&lt;/a&gt; package to your project’s dependencies:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; @cesdk/cesdk-js&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your package.json file will now list it as a dependency:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &quot;@cesdk/cesdk-js&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;^1.41.1&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &quot;react&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;^18.3.1&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &quot;react-dom&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;^18.3.1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;create-the-design-editor-component&quot;&gt;&lt;strong&gt;Create the Design Editor Component&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In the src folder of your React project, create a DesignEditor.jsx file. This will house your CE.SDK-based React design editor component.&lt;/p&gt;
&lt;p&gt;Inside it, import &lt;code&gt;CreativeEditorSDK&lt;/code&gt; from &lt;code&gt;@cesdk/cesdk-js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEditorSDK &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@cesdk/cesdk-js&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, initialize your video editor React component with the following logic:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;jsx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// src/DesignEditor.jsx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; CreativeEditorSDK &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;@cesdk/cesdk-js&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { useEffect, useRef, useState } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;react&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// your CE.SDK license and user configs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  license: &lt;/span&gt;&lt;span&gt;&apos;&amp;#x3C;YOUR_LICENSE&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  userId: &lt;/span&gt;&lt;span&gt;&apos;&amp;#x3C;YOUR_USER_ID&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; DesignEditor&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; cesdk_container&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; useRef&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;cesdk&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;setCesdk&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; useState&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  useEffect&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // if the CE.SDK container has already been initialized&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;cesdk_container.current) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; cleanedUp &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // initialize a CE.SDK instance&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; instance;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    CreativeEditorSDK.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(cesdk_container.current, config).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;_instance&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        instance &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; _instance;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (cleanedUp) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          instance.&lt;/span&gt;&lt;span&gt;dispose&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        // customize the design editor behavior...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        setCesdk&lt;/span&gt;&lt;span&gt;(instance);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // clean up the CE.SDK instance&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    const&lt;/span&gt;&lt;span&gt; cleanup&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      cleanedUp &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      instance?.&lt;/span&gt;&lt;span&gt;dispose&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      setCesdk&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; cleanup;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }, [cesdk_container]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ref&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{cesdk_container}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{{ width: &lt;/span&gt;&lt;span&gt;&apos;100vw&apos;&lt;/span&gt;&lt;span&gt;, height: &lt;/span&gt;&lt;span&gt;&apos;100vh&apos;&lt;/span&gt;&lt;span&gt; }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;#x3C;YOUR_LICENSE&gt;&lt;/code&gt; with the license key from CreativeEditor SDK, and &lt;code&gt;&amp;#x3C;YOUR_USER_ID&gt;&lt;/code&gt; with your user ID to optionally track monthly active users (MAUs) across different devices.&lt;/p&gt;
&lt;p&gt;The component defined above embeds CreativeEditor SDK into an HTML &lt;code&gt;&amp;#x3C;div&gt;&lt;/code&gt; element. &lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/customization/dock-cb916c/&quot;&gt;See how to customize and use it in the docs&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;use-the-component&quot;&gt;&lt;strong&gt;Use the Component&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;You can now import the DesignEditor component as below:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import DesignEditor from &quot;./DesignEditor&quot;;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then, add it to the DOM as follows:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;#x3C;DesignEditor /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will open the design editor with the preset, enabling users to place assets, set constraints, and perform other tasks to create their final designs.&lt;/p&gt;
&lt;h2 id=&quot;react-design-editor-use-cases&quot;&gt;React Design Editor Use Cases&lt;/h2&gt;
&lt;p&gt;Now that you are familiar with integrating a React design editor into your web app. It is time to explore key use cases and see how CreativeEditorSDK can cover many scenarios.&lt;/p&gt;
&lt;h3 id=&quot;social-media-publishing&quot;&gt;&lt;strong&gt;Social Media Publishing&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;CreativeEditorSDK offers a wide suite of tools to help users easily create high-quality, personalized, on-brand social media assets in your React application.&lt;/p&gt;
&lt;p&gt;With a vast library of professionally designed templates, it streamlines the design process and ensures consistency across multiple platforms. Users can efficiently produce engaging content tailored for&lt;/p&gt;
&lt;p&gt;Key features include customizable dimensions, filters, placeholders, and text overlays. These give users what they need to craft content optimized for various social networks, such as Instagram, X, LinkedIn, and more. That is possible thanks to platform-specific export options to produce ready-to-upload assets.&lt;/p&gt;
&lt;p&gt;The SDK’s capabilities extend beyond static images, supporting the creation of dynamic &lt;a href=&quot;https://img.ly/use-cases/story-reels-short-video-creation/&quot;&gt;short videos, stories, and reels&lt;/a&gt;. Do not forget that CE.SDK can also function as a &lt;a href=&quot;https://img.ly/blog/modern-react-design-editor/&quot;&gt;modern React video editor&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;digital-asset-management&quot;&gt;&lt;strong&gt;Digital Asset Management&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;DAM, short for &lt;a href=&quot;https://business.adobe.com/blog/basics/digital-asset-management&quot;&gt;Digital Asset Management&lt;/a&gt;, is the process of organizing, storing, and efficiently retrieving a wide range of digital files.&lt;/p&gt;
&lt;p&gt;CreativeEditorSDK supports DAM by helping teams centralize asset creation and editing directly within an embeddable React design editor, eliminating the need for external tools. This is achieved through features like pre-defining and locking branding elements (including logos, fonts, and color schemes) to ensure brand consistency across all generated content.&lt;/p&gt;
&lt;p&gt;Additionally, CE.SDK offers :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://img.ly/demos/design-validation/web/&quot;&gt;Design validation tools&lt;/a&gt; to prevent the creation of misaligned assets.&lt;/li&gt;
&lt;li&gt;Automatic asset generation to streamline content variations.&lt;/li&gt;
&lt;li&gt;Robust asset management features for handling both generated content and external assets retrieved via &lt;a href=&quot;https://support.img.ly/do-you-offer-third-party-integrations-such-as-unsplash&quot;&gt;third-party APIs&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;marketing-automation&quot;&gt;&lt;strong&gt;Marketing Automation&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Businesses can use CreativeEditor SDK to scale marketing campaigns through &lt;a href=&quot;https://img.ly/templates/&quot;&gt;dynamic, unique, customizable design templates&lt;/a&gt;. In detail, this design editor allows you to generate campaign materials (like personalized flyers, ads, or banners) quickly and at scale.&lt;/p&gt;
&lt;p&gt;Key features for marketing automation include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automation&lt;/strong&gt;: Integrate with CRM or marketing tools to auto-populate templates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Templates&lt;/strong&gt;: Easily create content with placeholders or &lt;a href=&quot;https://img.ly/docs/cesdk/react/create-templates/add-dynamic-content/text-variables-7ecb50/&quot;&gt;custom text variables&lt;/a&gt; for personalized outputs and A/B testing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Brand Compliance&lt;/strong&gt;: Lock assets like logos and fonts for consistent messaging and branding.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ai-powered-applications&quot;&gt;&lt;strong&gt;AI-Powered Applications&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;AI is rapidly becoming a key component of more and more applications, with many integrating it in some form. Still, a critical step is often overlooked: manual editing and supervision.&lt;/p&gt;
&lt;p&gt;CreativeEditorSDK bridges that gap by seamlessly integrating with AI-powered workflows while guaranteeing users the ability to &lt;a href=&quot;https://img.ly/docs/cesdk/react/create-templates/add-dynamic-content/placeholders-d9ba8a/&quot;&gt;manually define constraints, placeholders, and rules&lt;/a&gt; that the AI-driven automation process must follow.&lt;/p&gt;
&lt;p&gt;Example of how a CE.SDK-powered React design editor could work with AI includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automated template suggestions based on industry or use case.&lt;/li&gt;
&lt;li&gt;Prompt-based content generation where users describe their needs, and the app delivers a draft design.&lt;/li&gt;
&lt;li&gt;Automated content optimization, where the AI evaluates design elements and suggests improvements for readability and visual appeal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI-generated content is impressive, but it is essential to find the right balance between automation and manual control in the content generation process for the best results.&lt;/p&gt;
&lt;h3 id=&quot;product-mockups&quot;&gt;&lt;strong&gt;Product Mockups&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;CreativeEditorSDK simplifies the creation of product mockups, packaging designs, and marketing materials, including &lt;a href=&quot;https://img.ly/use-cases/print-personalization/&quot;&gt;printable brochures and business cards&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;CE.SDK features powerful customization tools and flexible capabilities, including alignment guides and snap tools to ensure perfect positioning. Additionally, color pickers and vector shape editors enable you to explore and create professional design concepts.&lt;/p&gt;
&lt;h3 id=&quot;e-learning-materials&quot;&gt;&lt;strong&gt;E-Learning Materials&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Thanks to CreativeEditorSDK, you can integrate a design editor into your React e-learning application.&lt;/p&gt;
&lt;p&gt;The embeddable design editor supports the entire process of creating e-learning materials, including custom graphics like annotations, diagrams, and visual explanations, or &lt;a href=&quot;https://img.ly/products/video-sdk-mobile/&quot;&gt;videos recorded directly from the camera&lt;/a&gt; by the teachers/educators/coaches. The component also allows for the creation of unique and customized student certificates.&lt;/p&gt;
&lt;p&gt;Those features empower educators and content creators in the education sector to craft visually engaging and impactful learning materials.&lt;/p&gt;
&lt;h2 id=&quot;customization-options-with-creativeeditor-sdk&quot;&gt;Customization Options With CreativeEditor SDK&lt;/h2&gt;
&lt;p&gt;CreativeEditor SDK does not provide a static React design design experience. Instead, it offers extensive customization options to align with your application’s branding and workflow. Key customization options are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Theming&lt;/strong&gt;: Adjust the editor’s theme to match your app’s design. Choose from built-in themes, generate new ones using the &lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/appearance/theming-4b0938/&quot;&gt;theme generator&lt;/a&gt;, or create a custom theme manually. Test themes in the &lt;a href=&quot;https://img.ly/demos/theming/web/&quot;&gt;demo page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom UI Plugins&lt;/strong&gt;: Add custom UI components to fit your design style through &lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/ui-extensions-d194d1/&quot;&gt;custom plugins&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enabling/Disabling Features&lt;/strong&gt;: Tailor the editor by enabling or disabling features like specific fonts, templates, or tools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Toolbar Customization&lt;/strong&gt;: Reposition toolbar elements, change icons, or rename tools to suit your needs, creating a unique editing experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom Templates, Assets, Themes&lt;/strong&gt;: Add your own templates, assets, or themes for a more personalized user experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Media Libraries&lt;/strong&gt;: Set up customizable, sortable media libraries. CE.SDK supports integration with third-party libraries, allowing easy access to external media assets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom Integrations via Events&lt;/strong&gt;: Hook into the editor’s events to trigger workflows, save progress, or integrate with external systems.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Internationalization&lt;/strong&gt;: Adapt the design editor component for different languages and regions with &lt;a href=&quot;https://img.ly/docs/cesdk/react/user-interface/localization-508e20/&quot;&gt;full i18n support&lt;/a&gt;. Overwrite and extend text strings in any language.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;CreativeEditor SDK’s compatibility with React’s component-based architecture and large set of features ensures simple integration into any project, making it ideal for a wide range of industries, from marketing and e-learning to e-commerce and social media.&lt;/p&gt;
&lt;p&gt;A CE.SDK-based design editor offers UI customization and unique feature options to adapt to any use case. Additionally, its support for AI workflows ensures your application remains future-proof and ready to meet evolving user needs.&lt;/p&gt;
&lt;p&gt;By following the steps outlined in this blog post, you can bring professional-level design editing features to your web users. Explore CE.SDK’s capabilities and &lt;a href=&quot;https://img.ly/docs/cesdk/&quot;&gt;dive into the docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stay tuned for more updates, and please &lt;a href=&quot;https://img.ly/forms/contact-sales/&quot;&gt;reach out&lt;/a&gt; if you have any questions. Thank you for reading.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Over 3,000 creative professionals gain early access to our new features, demos, and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Antonello</dc:creator><media:content url="https://blog.img.ly/2025/01/react-web-design-editor.jpg" medium="image"/><category>React</category><category>Design Editor</category><category>CE.SDK</category></item><item><title>How I Built a Short Video Generator with AI &amp; CE.SDK in One Day</title><link>https://img.ly/blog/how-to-build-short-video-generator-ai-creative-sdk/</link><guid isPermaLink="true">https://img.ly/blog/how-to-build-short-video-generator-ai-creative-sdk/</guid><description>Can AI really accelerate product development? I built a short video generator in one day using AI and CE.SDK to find out.</description><pubDate>Thu, 09 Jan 2025 11:27:13 GMT</pubDate><content:encoded>&lt;p&gt;Here’s the crux of product development in the age of LLMs: how much can AI truly accelerate the development process?&lt;/p&gt;
&lt;p&gt;We have seen videos of solo developers building small apps entirely with AI with just a few prompts. But how does it scale to more complex development projects? As LLMs rapidly evolve, their scope and impact will only increase.&lt;/p&gt;
&lt;p&gt;That’s why I regularly challenge myself to build a small project with the help of AI. I’m a prime candidate to test the AI productivity boost: a jack-of-all-trades (and a master of none) with a background in both design and engineering, yet no hands-on experience in the past five years. My latest challenge? Build a web-based short video generator within one day.&lt;/p&gt;
&lt;p&gt;In this post, I’ll share the most intriguing takeaways from tackling this project.&lt;/p&gt;
&lt;h2 id=&quot;why-a-short-video-generator&quot;&gt;Why a Short Video Generator?&lt;/h2&gt;
&lt;p&gt;Why focus on this idea? It’s simple: to ride the wave of a new trend. A format called “&lt;strong&gt;faceless&lt;/strong&gt;” short videos is gaining traction among creators on platforms like YouTube and TikTok.&lt;/p&gt;
&lt;figure class=&quot;kg-embed-card&quot;&gt;
&lt;iframe src=&quot;https://www.youtube.com/embed/DfQ3fhqfKVc?feature=oembed&quot; title=&quot;FUNNY USA Stereotype Records! #shorts&quot; loading=&quot;lazy&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/figure&gt;
&lt;p&gt;What’s fascinating about these videos is their automation: an LLM generates a script, which is then transformed into speech, images, and text assets using various AI services. These assets are automatically assembled into a cohesive video.&lt;/p&gt;
&lt;p&gt;The general concept is compelling: It’s still generative content, but mixed with classic video composition techniques. This approach offers greater accuracy, consistency, and control over pure generative AI.&lt;/p&gt;
&lt;p&gt;The potential to automate video production at this scale is exciting. Add its relatively low complexity and high production value, and it became the perfect topic for my challenge.&lt;/p&gt;
&lt;h2 id=&quot;enter-cesdk&quot;&gt;Enter CE.SDK&lt;/h2&gt;
&lt;p&gt;Another reason I chose this challenge was its compatibility with CE.SDK, our design and video editor library. CE.SDK offers a robust editing toolkit that integrates into any product with just a few lines of code. Its features, like headless mode, are ideal for automating workflows like video generation.&lt;/p&gt;
&lt;p&gt;Most faceless video services use React-based video generation and achieve fair results. However, using CE.SDK instead of a react-based library could potentially boost the overall experience with three critical improvements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Editable Outputs:&lt;/strong&gt; This is huge. Full automation often needs human adjustments for fine-tuning. CE.SDK enables automated video generation while allowing manual refinement of the results.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Visual Quality:&lt;/strong&gt; CE.SDK has its own rendering pipeline, allowing for more nuanced visual effects and animations. When you’re competing against others in this space, it can make a huge difference if you’re able to produce higher fidelity in the visual output.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Design Workflow:&lt;/strong&gt; Create design components or even entire templates visually, and then use them via code. This authoring workflow can be extremely helpful in creating rich, interesting designs for the generated videos.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-ground-rules&quot;&gt;The Ground Rules&lt;/h2&gt;
&lt;p&gt;To keep the challenge focused, I set strict rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Time Limit:&lt;/strong&gt; Spend no more than 12 hours on the challenge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No Manual Coding:&lt;/strong&gt; Avoid writing any code yourself. Everything should be built through conversations with AI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trust the AI:&lt;/strong&gt; Do not read or analyze code generated by the AI. Rely entirely on its decisions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skip External Research:&lt;/strong&gt; Do not read or explore the APIs you intend to use. Instead, provide links to the AI and let it determine how to use them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compare AI Performance:&lt;/strong&gt; Alternate Claude Sonnet 3.5 and ChatGPT o1 for code generation to evaluate which performs better.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;the-tools--workflow&quot;&gt;The Tools &amp;#x26; Workflow&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Code Editor:&lt;/strong&gt; &lt;a href=&quot;https://www.cursor.com/&quot;&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
Built on VSCode’s foundation, Cursor stood out as the only editor offering both an integrated chat interface and the ability to switch between different LLMs. However, with GitHub’s recent significant updates to Copilot, I’ll switch to VSCode with Copilot for future challenges.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UI Prototyping:&lt;/strong&gt; &lt;a href=&quot;https://madewithclaude.com/&quot;&gt;&lt;strong&gt;Claude Artifacts&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
Rather than building the entire project in my code editor, I chose to prototype the UI directly through Claude’s web interface. The benefits were immense:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Instant results:&lt;/strong&gt; To create an artifact, Claude streamlines development by automatically writing and compiling code while leveraging essential UI libraries and components. This automation eliminates setup time and technical overhead, allowing me to focus purely on design iterations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instants Variations:&lt;/strong&gt; Claude enables rapid prototyping through parallel conversations. When a design direction didn’t quite work, I could simply start a fresh conversation with modified requirements and evaluate a new prototype. This approach helped me develop three viable concepts quickly - a pace that would have been impossible in a traditional code editor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quality of execution:&lt;/strong&gt; Claude transforms rough concepts into polished, intuitive interfaces. Its suggestions often surpassed my initial ideas, offering sophisticated solutions I hadn’t considered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep it clean:&lt;/strong&gt; By prototyping outside the code editor, I kept the main project’s codebase clean and focused. This separation prevented the accumulation of experimental code and maintained the clarity of our primary development environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/how-to/er-ai/0108.mp4&quot; controls loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Quickly prototype your interface with Claude Artifacts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;APIs&lt;/strong&gt;&lt;br&gt;
Key APIs used in the project included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Script Generation:&lt;/strong&gt; Claude Sonnet 3.5 vs various ChatGPT models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image/Video Assets:&lt;/strong&gt; &lt;a href=&quot;https://Fal.ai&quot;&gt;Fal.ai&lt;/a&gt; Flux models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Speech Synthesis:&lt;/strong&gt; &lt;a href=&quot;https://elevenlabs.io/&quot;&gt;ElevenLabs&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;building-the-app-divide-and-conquer&quot;&gt;Building the App: Divide and Conquer&lt;/h2&gt;
&lt;p&gt;After having prototyped the UI, I started to chat with the LLM inside the code editor so that it can code the app. To work with the AI efficiently, I followed a divide-and-conquer approach. Rather than simply asking it to “build me a video app,” I broke down the problem into manageable steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generate a video script&lt;/strong&gt;&lt;br&gt;
Create an AI prompt that includes user input and examples of the desired output format. Pass this prompt to the LLM API.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parse the script to generate assets (speech, images, text)&lt;/strong&gt;&lt;br&gt;
Parse the LLM’s response to extract image prompts and speech paragraphs. Send these to their respective APIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compose the final video&lt;/strong&gt;&lt;br&gt;
Load all the generated assets into a predefined template to generate the finished video through the CE.SDK library.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After completing these steps, I was finally able to generate my first fully automated videos! With a few more tweaks and additions, I had an MVP ready within twelve hours.&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;https://storage.googleapis.com/imgly-static-assets/static/blog/videos/how-to/er-ai/shortyroll.mp4&quot; controls loop playsinline&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;The final result: A Short Video Generator&lt;/p&gt;
&lt;p&gt;There are still some missing features, partly because I spent a significant amount of time refining the prompt to generate the video script. I also had to bend the rules occasionally: sometimes the LLM would hit a wall, and I had to read or write small snippets of code.&lt;/p&gt;
&lt;h2 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Engineering Knowledge Is Essential&lt;/strong&gt;&lt;br&gt;
You should have some engineering background to achieve the AI productivity boost in development.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI doesn’t solve everything for you. You are still the architect. You provide a lot of input and guidance. AI often needs to be pointed to the right strategy. Foundational knowledge of computer science is hugely advantageous for working with AI effectively.&lt;/li&gt;
&lt;li&gt;As mentioned, I had to read and write a few lines of code myself. Without coding experience, I would have probably not been able to progress, as the LLM was not able to.&lt;/li&gt;
&lt;li&gt;The getting started experience is nowhere close to novice-friendly. How do you get started with a new project in a code editor that actually requires you to do the setup manually? My workaround was to create an empty project, and then ask the LLM to instruct me to use a boilerplate for react. Again, this is engineering knowledge, any novice would have hit a wall already at this point.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Claude Outperformed ChatGPT&lt;/strong&gt;&lt;br&gt;
Claude was a clear winner in the side-by-side comparison, because of three reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude Artifacts was a game changer for UI prototyping.&lt;/li&gt;
&lt;li&gt;It was generally better at writing and understanding code. Difficult to quantify, but in some cases Claude fixed the mess ChatGPT left in the code&lt;/li&gt;
&lt;li&gt;Claude can process URLs, which makes working with APIs much smoother.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Who would have thought new LLMs would catch up to OpenAI so quickly after they released the first version of ChatGPT?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Complexity Slows AI&lt;/strong&gt;&lt;br&gt;
The more code in my project, the slower the overall progress. LLMs struggled with the growing complexity. Their context windows filled more quickly, and their responses became increasingly unreliable. At some point, it becomes extremely difficult to make architectural changes, especially if this affects multiple parts of the app. When trying to fix errors, you’ll often find yourself in a whack-a-mole game. While the AI would resolve one issue, it would inadvertently introduce new problems elsewhere, creating an endless loop of fixes and regressions.&lt;/p&gt;
&lt;p&gt;Ultimately, the time invested in this challenge was well worth it. While LLMs can’t build products end to end on their own, they can significantly streamline product development when paired with the right human collaboration. The real question is whether development teams are ready to adapt their habits and explore new workflows to boost productivity.&lt;/p&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;This challenge has inspired me to refine and expand on this project. Future iterations will focus on harnessing CE.SDK’s unique features to push the boundaries of automated video generation.&lt;/p&gt;
&lt;p&gt;Stay tuned for part two of this series. There’s much more to explore!&lt;/p&gt;
&lt;p&gt;UPDATE: Read &lt;a href=&quot;https://img.ly/blog/how-to-build-a-short-video-generator-using-ce-sdk-2/&quot;&gt;part two&lt;/a&gt; - a cookbook how to build your own short video creator!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Over 3,000 creative professionals gain early access to our new features, insights and updates. Don’t miss out, and&lt;/strong&gt; &lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;&lt;strong&gt;subscribe&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;to our newsletter.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Eray</dc:creator><media:content url="https://blog.img.ly/2025/01/build-ai-video-generator-1.jpg" medium="image"/><category>How-To</category><category>AI</category><category>CE.SDK</category><category>Artificial Intelligence</category><category>Video Editor</category></item></channel></rss>