* Content-Aware Fill: bit-pack holes, spill frames to disk, stream outputs (#2570 phases 2-4) * Content-Aware Fill phases 2-4: bit-pack holes, spill frames, stream outputs (clippy clean) * Address CodeRabbit review: spill safety, streaming correctness, perf, memory guard (#2570) * Address the remaining CodeRabbit review findings on Content-Aware Fill (#2570) A non-streaming fill returned empty frames, progress could jump backwards between the sink and the fill, the memory guard ignored the membrane frames still resident for the flow pass (and wasm's in-RAM copies), and the GPU fill stages ran outside an error scope, so an OOM retired the shared context instead of falling back to the CPU for that frame. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com> * Content-Aware Fill: sample spilled frames without decoding them, check spill errors (#2570) Tracing sampled spilled frames by decoding whole frames under the shared cache lock, so parallel traces across neighbouring frames evicted each other and mostly paid a full-frame read while every other thread waited. Sample only the 2x2 bilinear support with positioned reads on an open handle instead, and report a failed spill read in the no-hole branch rather than streaming black frames as a successful fill. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com> * Content-Aware Fill: spill membrane/propagated frames, unquantized input, surface scratch errors (#2570) Flow and propagation now write their intermediate frames to scratch spills beside the output instead of holding the whole range as float RGBA, and the input spill uses 32-bit floats whatever the project depth so the fill sees the same values as the old in-memory path. Spill reads/writes and scratch creation report through a shared error slot that run_plan surfaces instead of masking disk failures as a cancellation. Sampling uses positioned reads; the guard models the packed masks plus per-thread scratch. * Content-Aware Fill: report a membrane-spill write failure instead of cancelling (#2570) * Content-Aware Fill: include the flow fields in the memory guard (#2570) * Content-Aware Fill: scale the memory guard with workers and check scratch space (#2570) The guard's scratch term was a fixed 8 frames, which under-counted a wide machine with Lighting Correction by several times. It now models the sequential synthesis stage plus a few frames per worker (from available parallelism) and takes Lighting Correction into account. Native fills write three f32 copies of the range to scratch beside the output, so a range that cannot fit on that volume is now refused up front with the free space in the message, before any frame is rendered. Tests cover the worker/lighting budget, the scratch formula, a shared error slot between the input and secondary spills, an uncreatable spill folder, and the engine surfacing a spill failure as an error instead of a cancellation. * Content-Aware Fill: resolve a relative output folder for the scratch check (#2570) A bare relative output name has an empty parent, so the walk-up found no existing ancestor and skipped the free-space check. Resolve it against the process directory first, and cover that in the test. * Do not reformat the GPU fill tests in the spill branch (#2570) The file was already not rustfmt-clean upstream, so the formatter only added noise to a file this PR no longer needs to touch: phase 1's call-site changes are already on the base branch. * Content-Aware Fill: measure peak RSS and correct the per-worker scratch model (#2570) The ignored measure_peak_rss_of_a_fill test fills a spilled 640x360 range and reports VmHWM. On this 18-worker machine 90 frames peak at 340-470 MB across runs (35 MB with RAYON_NUM_THREADS=1) and 600 frames at 582 MB, so the scratch slope is ~7 frames a worker, not the 2 the first guard revision assumed. Scaling the summary down showed a clean linear slope at 8 and 4 workers, and Lighting Correction stayed below the flow stage's peak. Budget 8 frames a worker (9 with Lighting Correction), just above the measured top of the range, and adjust the guard test to the real numbers. At 600 frames the measured peak is 582 MB against ~11.1 GB for the old five-copies model, a 19x reduction. * Contributors: credit Madhav Agarwal in the About window Adds the self-chosen real and display name for @gmrmad1. The generated contributors.json picks it up once the PR is merged. * Address CodeRabbit: size the guard from the rayon pool; migrate GPU tests (#2570) fill_workers used available_parallelism, but the parallel fill stages run on the rayon pool, which RAYON_NUM_THREADS can size larger. Use rayon::current_num_threads so the scratch budget follows the threads that actually run; wasm keeps rayon's single-thread fallback. The GPU inpaint tests still used the pre-spill FillInput API. The earlier 'do not reformat' revert dropped their API migration along with the formatting, leaving cargo test -p effectcraft-gpu uncompilable. Restore the Frames::Memory / HoleMask / sink migration and verify the 15 inpaint tests. * Fix gate: flatten the wasm prop lookup and keep the budget wrapper test-only (#2570) * Address CodeRabbit review: spill error check, global-pool preflight, docs (#2570) * Include RAM-backed spill in the preflight and guard streaming reads (#2570) * Resolve relative spill paths, prefer stacked mounts, guard the Edge Blend sink (#2570) * Make the fill spill anonymous and test the streaming claims (#2570) The spill was a named file in the output folder that only Drop removed, so an out-of-memory kill or a force-quit left a multi-gigabyte effectcraft-fill-* file in the user's project folder, and a failed set_len after keep() leaked it too. The spill is now an anonymous temporary file (tempfile_in), which the system reclaims when its last handle closes; every read and write is positioned on that one handle (pwrite/seek_write join the existing pread/seek_read), and the folder is kept only so the propagated frames spill beside the input. Also: - Edge Blend checks for a failed read before handing a frame to the sink, so a black fallback frame never streams. - The propagation workers stop as soon as the spill records an error. - HoleMask::get/set use get()/get_mut(), so a mask whose public words are shorter than len cannot panic. New tests cover the PR's headline claims: a spilled range fills bit-identically to the same frames in RAM (returned and streamed), the sink sees frames strictly in order, a truncated spill fails with a recorded error and streams nothing, a failure mid-stream stops before the next frame, propagation stops after a failure, the spill has no name in its folder, and HoleMask round-trips at word boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Content-Aware Fill: clean up a stopped fill and count two scratch copies (#2570) - A fill that fails or is cancelled after frames started streaming deletes the PNGs it wrote, and the output folder when the fill made it and it is left empty (OutputFiles, dropped after the spill so Windows can remove the folder). - After a successful fill, run_plan checks that every frame has a file, and apply_plan/add_fill_layer return an error on an empty range or file list (a job worker's reply) instead of indexing [0]. - scratch_need charges two f32 copies (32 B/px): flow_pairs drops the membrane spill before the propagated one is created, so the third copy never coexists. - The spill-creation error carries a stable "spill: cannot make the scratch file" marker; the panel test asserted on the OS wording, which on Windows is "Cannot create a file when that file already exists". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Content-Aware Fill: a stopped fill leaves files it didn't create (#2570) A fill into a given outputDir that already holds an earlier sequence overwrites its frames as it goes (as before). The cleanup of a failed or stopped fill deleted every path it wrote, including those earlier frames, so a layer still using that sequence lost them. It now deletes only the files the fill created (CodeRabbit on #3079). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Codebuff <noreply@codebuff.com> Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
EffectCraft
Motion graphics and visual effects; an open-source, professional motion graphics and visual effects studio, built in pure Rust.
A free, open-source compositor: compositions, layers, keyframes, 308 effects, layer styles, expressions, 3D cameras and lights, and a render queue, native on macOS, Windows and Linux, and in the browser. Young, moving fast, and already usable.
EffectCraft on getartcraft.com · ArtCraft · All Crafting Apps
Note
ArtCraft is a community of artists from all walks of life. Digital, generative, music, games — if you make things, you're one of us. Come say hi on Discord.
What it is · Animate · Effects · 3D · Export · Agents · Get started · Status · How it's made · Downloads · The Crafting Apps · License
What EffectCraft is
EffectCraft is for animated titles, motion graphics and compositing work: the kind of thing motion designers and VFX artists need. You build a composition out of layers (solids, shapes, text, footage, other compositions), animate their properties with keyframes, stack effects on them and render the result.
The interface feels natural and responsive, with dedicated panels (Project, Composition, Timeline, Layer, Footage, Effect Controls, Tools, Preview, Effects & Presets, Audio, Info, Paragraph, Character, Align, Progress, Render Queue) and standard motion graphics shortcuts, going further in a few places where it matters to us:
- Lottie import and export built in, so animations can go straight to the web and apps without a plugin.
- A project file you can read. Projects are versioned JSON (
.ecproj), so they diff cleanly in version control. - Everything is scriptable. Menu actions, timeline edits and property changes are exposed as commands. Engine commands are available through the CLI, JSON control channel and MCP; UI-only commands use the frontend dispatcher and can be invoked through the control channel or an attached MCP bridge.
- No FFmpeg. Video and audio decoding and encoding are pure Rust: FilmCraft's codecs and EffectCraft's own VP9, AV1, HEVC and Opus encoders.
Animate
The panels, menus and shortcuts follow standard motion design conventions: Project, Composition, Timeline, Effect Controls, Properties, Effects & Presets, Character, Paragraph, Align, Info, Preview, Audio and the Render Queue, docked the way you expect. Drag footage, comps and effects between them: onto the comp viewer, where they land under the pointer, or into the Timeline, between layers and at the time you point to.
- Layers of every kind: solids, shapes, text, footage, nested compositions, nulls, adjustment layers, cameras and lights; parenting, track mattes, all 38 blend modes, motion blur.
- Keyframes that behave the same: linear, Bezier, hold, auto and continuous Bezier, roving keys, Easy Ease (F9), Keyframe Velocity and Interpolation dialogs, copy and paste at the current time, and a Graph Editor with value and speed graphs and draggable handles.
- Time: time remapping, time stretch, time-reverse, freeze frame, work area, markers, exact frame-accurate timing at every frame rate including 29.97 drop-frame.
- Shapes and masks: shape layers with trim paths, repeaters, round corners, offset, zig zag, twist, wiggle, merge paths and gradient strokes; masks drawn with the pen tool, with modes, feather, expansion and vertex editing in the viewer.
- Text: point and paragraph text with real shaping in any font installed on your machine, the Character and Paragraph panels, and text animators with range selectors.
- Expressions: JavaScript with the standard motion expressions model (
wiggle,loopOut,thisComp.layer("…"), vector maths on arrays), an inline editor and the pick-whip. - Timeline like you know it: twirl layers open to Transform, masks, effects and the rest; drag rows to reorder layers; rename with Enter or a double-click; the property shortcuts (A, P, S, R, T, M, F, E, L, U and their double presses AA, PP, SS, RR, TT, MM, FF, EE, LL, UU), Shift to add properties, Alt+Shift+A/P/S/R/T to key the current time, Ctrl+` to twirl selected layers.
- Puppet tools: Position, Advanced, Bend, Starch and Overlap pins on a mesh built from the layer, real-time pin recording, rotate/scale handles, pins driven by (or carrying) nulls for rigging, and follow-through for hair and cloth.
Effects
308 built-in effects across its categories, each with its parameter names, order and defaults: blur and sharpen, channel, color correction (Curves, Levels, Hue/Saturation, a full color-grading panel…), distort (Warp, Bulge, Turbulent Displace, CC Power Pin…), generate (Fractal Noise, Gradient Ramp, Stroke, Write-on, Audio Spectrum…), keying, matte, noise and grain, perspective, simulation (CC Particle World, CC Rainfall, Shatter, Card Dance, Caustics, Wave World…), stylize (Glow, CC Glass…), time (Echo, Posterize Time, Timewarp, Time Displacement…), audio (Reverb, Parametric EQ, Delay, Stereo Mixer…), text, transitions, utility and expression controls. All nine Layer Styles (Drop Shadow, Inner/Outer Glow, Bevel and Emboss, Satin, overlays, Stroke) with Global Light. Preview plays audio in sync, with meters and waveforms.
3D
Classic 3D compositing: 3D layers with orientation and material options, one- and two-node cameras with depth of field, lights (parallel, spot, point, ambient) with soft ray-traced shadows, layers that intersect correctly, orbit, pan and dolly camera tools, and Front, Top, Left and Custom views.
Export
A dedicated Render Queue, with Render Settings and Output Modules: H.264 MP4 and ProRes MOV (Proxy to 4444 XQ with alpha) with audio, HEVC (Main / Main 10) and AV1 MP4, WebM (VP9 with inter frames and alpha, or AV1; Opus audio), PNG, JPEG, TIFF, Targa and 32-bit EXR sequences, animated GIF and WAV/AIFF. Field rendering with 3:2 pulldown, effect/solo/guide/depth overrides, crop, region of interest and resize, Render Settings and Output Module templates with defaults, post-render actions, storage overflow and render logs. The same queue runs from the command line. Every encoder is pure Rust (FilmCraft's H.264, ProRes and AAC; EffectCraft's own VP9, AV1, HEVC and Opus); there is no FFmpeg inside.
Lottie goes both ways: File ▸ Export ▸ Lottie JSON… writes a composition (precomps, shape,
solid, image, text and null layers, eased and spatial keyframes, masks, track mattes, blend
modes, time remapping, optionally expressions) as .json or .lottie, and lists anything Lottie
cannot express; File ▸ Import ▸ Lottie… opens one as a new composition.
Built for agents
Engine commands are available through the CLI, JSON control channel and MCP. UI-only commands
need the running app's frontend dispatcher: complete menu access requires the app's control
channel or an attached MCP bridge. Headless MCP sessions expose supported engine commands,
but not UI-only commands or bridge-only ui_* tools.
- MCP server:
effectcraft-cli mcpspeaks the Model Context Protocol over stdio, headless or bridged to the running app (--bridge 9877). Tools cover commands, the project and property tree, keyframes and rendered frames. This repository ships a ready.mcp.json. - Command line: one-shot calls with JSON output, for example
effectcraft-cli set Main '#1' transform/position '[100,360]' --time 0 main.ecproj --saveoreffectcraft-cli render --comp Main --out main.mp4, oreffectcraft-cli exec file.exportLottie '{"comp":"Main","path":"main.json"}' main.ecproj. - Control channel:
effectcraft --control 9877accepts JSON lines to run commands, inspect and click any widget by its automation id, and take screenshots.
See docs/agents.md and docs/control-protocol.md.
Get started
Installers for each version are on the Releases page: a universal macOS app; Windows MSIs and portable zips for x64, x86 and ARM64; Linux AppImage, Flatpak, deb, rpm and tar.gz for x86_64 and aarch64, plus a riscv64 tar.gz; a FreeBSD x86_64 tarball; and the web build. Downloads lists every file. The Windows ARM64 build runs natively on Windows on ARM, without x64 emulation. CI installs that MSI on Windows 11 ARM64 hardware, checks both programs are ARM64 and runs the command-line tool there, but it doesn't open the app's window or run the test suite natively on ARM64 yet, so please report anything that behaves differently.
On Gentoo, the community ::snakebyte overlay packages
the Linux release as media-video/effectcraft-bin (not maintained by the EffectCraft team):
eselect repository add snakebyte git https://github.com/switch87/snakebyte-overlay.git
emaint sync -r snakebyte
echo 'media-video/effectcraft-bin ~amd64' >> /etc/portage/package.accept_keywords/effectcraft
emerge --ask media-video/effectcraft-bin
To build it yourself you need Rust 1.95 or newer.
git clone https://github.com/storytold/effectcraft
cd effectcraft
cargo run --release -p effectcraft # the app (add `-- --demo` to open the demo project)
cargo run --release -p effectcraft-cli -- render --out intro.mp4 # render the demo headless
cargo xtask web --serve 8765 # the browser build on http://127.0.0.1:8765/ (docs/web.md)
New to it? docs/footage.md covers importing footage and image sequences and Interpret Footage.
To work on it: cargo test --workspace, and cargo xtask ci before every commit (format, lints,
tests, layering, asset attribution and the WebAssembly build). See CONTRIBUTING.md,
docs/architecture.md and docs/testing.md.
Where it stands
EffectCraft is young: its first commit was on 1 October 2026. A comprehensive feature set exists, including 308 effects, but breadth is not the same as full maturity across every edge case. Today it's a good place to try things and to tell us what breaks. It isn't yet recommended for production client work. In particular:
- Native project format. Projects are saved as
.ecproj, readable versioned JSON. Proprietary project formats and After Effects SDK plug-ins are not supported. - Fidelity is still being refined. Automated rendering tests currently focus on small compositions, so please report visual discrepancies or unexpected behaviour.
- macOS is the most tested platform. Linux and Windows users have hit basic interaction bugs, which we're fixing first.
- The trained models are new. Roto Brush can use MobileSAM (an optional 40 MB download in Settings ▸ Roto Brush) and face tracking can use Google's MediaPipe Face Landmarker (an optional 3.8 MB download in Settings ▸ Face Tracking). Both are actively undergoing evaluation and tuning.
EffectCraft is in alpha: about 91% of the features tracked in docs/target-app-parity.md exist, and we estimate it is about 45% of the way to being ready for full professional production work. The ROADMAP has the plan, docs/target-app-parity.md the measurement and docs/gaps.md every known shortfall. The web build (docs/web.md) runs the full app in the browser. Bug reports are the most useful thing you can send us right now.
How it's made
- Engine first. A stack of small crates with strict layering. The interface (egui) sits on top and nothing underneath depends on it.
- Clean room. We work from public documentation and observable behavior, never from proprietary files, icons, presets or code. No code is copied from GPL projects. The full rules are in AGENTS.md.
- Private by default. No telemetry, and no network access unless you ask for it.
- One family. EffectCraft shares its time model and text engine design with FilmCraft, and gets its video and audio codecs from it.
Downloads
New to EffectCraft? Download it from the EffectCraft page on getartcraft.com. That's the easiest way to install it.
Want a specific build or format? On GitHub, the latest release has every build listed below, and all releases has earlier versions and their notes. <ver> in the file names is the version number, and SHA256SUMS.txt lists a checksum for every file.
Windows
| Build | Installer | Portable |
|---|---|---|
| x64 (64-bit Intel/AMD) | effectcraft-<ver>-windows-x64.msi |
effectcraft-<ver>-windows-x64-portable.zip |
| arm64 (Snapdragon and other ARM PCs) | effectcraft-<ver>-windows-arm64.msi |
effectcraft-<ver>-windows-arm64-portable.zip |
| x86 (32-bit) | effectcraft-<ver>-windows-x86.msi |
effectcraft-<ver>-windows-x86-portable.zip |
Installers and executables are code-signed. The installer asks who to install EffectCraft for and where. By default it installs for your
account only, into %LOCALAPPDATA%\Programs\ArtCraft\EffectCraft, without an administrator prompt;
"Everyone on this computer" installs into C:\Program Files\ArtCraft\EffectCraft (Program Files (x86) for the 32-bit build). Later versions
install into the same folder. To install silently
into a folder of your choice: msiexec /i effectcraft-<ver>-windows-x64.msi /qn INSTALLFOLDER="D:\Apps\EffectCraft".
A silent install is per-user by default. INSTALLFOLDER chooses the folder, not who it is installed for;
add ALLUSERS=1, from an elevated terminal or deployment tool, for an all-users install.
macOS
| Build | File | Notes |
|---|---|---|
| App, universal (Apple silicon + Intel) | effectcraft-<ver>-macos-universal.dmg |
Signed and notarized |
| Command-line tool, universal | effectcraft-cli-<ver>-macos-universal.zip |
Signed and notarized |
Linux
| Format | x86_64 | aarch64 (ARM64) | Notes |
|---|---|---|---|
| AppImage | effectcraft-<ver>-linux-x86_64.AppImage |
effectcraft-<ver>-linux-aarch64.AppImage |
Runs anywhere; updates itself with AppImageUpdate (.zsync files) |
| Flatpak | effectcraft-<ver>-linux-x86_64.flatpak |
effectcraft-<ver>-linux-aarch64.flatpak |
Sandboxed; flatpak install --user <file> |
| Debian/Ubuntu | effectcraft-<ver>-linux-x86_64.deb |
effectcraft-<ver>-linux-aarch64.deb |
|
| Fedora/RHEL/openSUSE | effectcraft-<ver>-linux-x86_64.rpm |
effectcraft-<ver>-linux-aarch64.rpm |
|
| Tarball | effectcraft-<ver>-linux-x86_64.tar.gz |
effectcraft-<ver>-linux-aarch64.tar.gz |
Unpack anywhere |
RISC-V 64-bit: effectcraft-<ver>-linux-riscv64.tar.gz (tarball only; needs glibc 2.39+, e.g. Ubuntu 24.04+ or Debian 13+).
File drag-and-drop on Linux: The current eframe/winit 0.30 native Wayland backend does not
deliver file-hover or file-drop events. On Hyprland and other native Wayland sessions, use
File ▸ Import ▸ File… (which accepts multiple files), or start EffectCraft via XWayland if
XWayland is installed and DISPLAY is set:
env -u WAYLAND_DISPLAY effectcraft
When the backend delivers events (X11/XWayland, Windows and macOS), dropping media anywhere in the window imports it, and a drop-target hint appears while hovering. On native Wayland the app cannot detect an attempt that generates no event; it shows a startup notice with the File ▸ Import fallback instead.
FreeBSD
| Build | File |
|---|---|
| x86_64 | effectcraft-<ver>-freebsd-x86_64.tar.gz |
Web (WebAssembly)
| Build | File | Notes |
|---|---|---|
| Static site | effectcraft-web-<ver>.zip |
Runs in a modern browser; host it on any static server |
The Crafting Apps
EffectCraft is one of the Crafting Apps: free, open-source creative tools from the ArtCraft team, each written from scratch in Rust and each able to stand on its own.
| App | What it's for | Code | Learn more | |
|---|---|---|---|---|
| PhotoCraft | Image editing: layers, masks, type and real PSD files | GitHub | Website | |
| VectorCraft | Vector illustration | GitHub | Website | |
| FilmCraft | Video editing, color and sound | GitHub | Website | |
| LightCraft | Photo library and raw development | GitHub | Website | |
| PdfCraft | Reading, organizing and protecting PDFs | GitHub | Website | |
| EffectCraft | Motion graphics and visual effects | GitHub | Website | |
| DesignCraft | Page layout and publishing | GitHub | Website | |
| FigCraft | Interface design and prototyping | GitHub | Website | |
| WordCraft | Word processing and documents | GitHub | Website | |
| SoundCraft | Audio recording and editing | GitHub | Website | |
| DeckCraft | Presentations and slide decks | GitHub | Website | |
| CADCraft | Computer-aided design | GitHub | Website | |
| GridCraft | Spreadsheets and data | GitHub | Website | |
| TextureCraft | 3D texture painting | GitHub | Website | |
| Craft Anything | See how any software works, then build your own | GitHub | Website | |
| SolidCraft | Parametric 3D CAD by Tangency Labs (community app) | GitHub |
And ArtCraft itself, our AI image and video studio for artists who want real control.
Come make things with us
Our Discord is where artists of every kind hang out: people who paint, shoot, draw, cut film, set type, and people still figuring out what they like to make. Share what you're working on, ask for help, tell us what's broken, or tell us what you wish these tools could do. Whatever your medium and however long you've been at it, you're welcome here.
discord.gg/artcraft · getartcraft.com · The Crafting Apps · EffectCraft
License and credits
EffectCraft is dual-licensed under MIT or Apache-2.0, at your option. Copyright (c) 2026 ArtCraft Team and the EffectCraft contributors. Required notices are in NOTICE.
Bundled fonts, icons, images and other assets keep their own open licenses; each one is listed with its author, source and license in ATTRIBUTION.md.
The ArtCraft name, wordmark and logos in docs/brand/ are trademarks of the
ArtCraft Team and are not covered by this license. They may be used only unmodified, and only as
part of this repository and EffectCraft, under docs/brand/LICENSE-brand.txt.
Forks and modified versions must remove them.
Made by the ArtCraft team and community.




