A cross-platform GIF recording and editing application built with Tauri, SvelteKit, and Rust.
Important
Unlike all of my other repositories, this is an AI-first experiment where I will try to stay as far as away from the code as I can. The goal is improve my agent-based workflows and learn more about AI-first software engineering.
Note
The application in this repository is incomplete and under active development.
- Minimalist GIF editor with a canvas, tool bar, timeline, inspector panel
- GIF playback
- Zoom in/out, move GIF around
- Basic frame management: delete/move, dedupe, change frame duration, duplicate (all available as individual and bulk operations)
- Thoughtful various mouse/key bindings
Ctrl+Mouse wheel- Zoom in/outShift+Mouse wheel- Scroll timelineLeft/Right- Move selected frameShift+Left/Right- Expand/reduce frame selectionCtrl+A- Select all framesDelete- Remove selected frame(s)Space- Start/stop playbackTab- Select next UI elementShift+Tab- Select previous UI elementEnter- "Click" selected UI element
You can run this project in any way you like, but I have set things up to make it easy to develop using JetBrains RustRover. For this, you'll need:
direnv- Any Direnv integration plugin e.g. https://plugins.jetbrains.com/plugin/15285-direnv-integration
nix
This way, you'll just need to direnv allow in the project directory after which all prerequisites (incl. Rust, Cargo,
all Bevy dependencies, etc.) will be available to you. The JetBrains plugin will ensure that the environment is
available to your IDE and you can run the project from there (vs cargo build and cargo run in the terminal).
RustRover will always fail to sync the project when you open it because it doesn't wait for direnv. Just re-sync
immediately after the failure and it will work.
Did RustRover forget where the Rust standard library is again? Run the below and update the path in the settings:
find /nix/store -type d -name rust_lib_srccargo sweep is your friend and comes with the Flake. For example, the below will delete all build artefacts that
are older than 7 days:
cargo sweep -t 7To clean everything except for the latest build:
cargo sweep --stamp
<Insert any number of cargo build, cargo test, etc. commands>
cargo sweep --file
Upgrade the flake by running nix flake update --flake . in the repository's base directory.
Frontend unit tests using Vitest:
pnpm test:unitFull-stack end-to-end tests that exercise the Svelte UI, Tauri IPC boundary, and Rust backend together using WebDriver.
-
Build the Tauri app (E2E tests run against the release binary):
pnpm tauri build
Note: on some Linux setups the AppImage bundling step may fail — the release binary at
src-tauri/target/release/screenyis still produced and is all the E2E harness needs. -
Install
tauri-driver:cargo install tauri-driver
-
WebKitWebDriver must be available on
PATH. On most Linux distributions this is provided by thewebkit2gtkorwebkit2gtk-driverpackage. Check:which WebKitWebDriver
-
Display / session: the tests launch a real GUI window, so a running display server is required. On Wayland compositors (e.g. Hyprland) the current session works. In headless CI, use a virtual framebuffer:
# Example with weston weston --backend=headless & export WAYLAND_DISPLAY=wayland-0
-
Test fixture:
tests/fixtures/test.gifmust exist. It is checked into the repo. To regenerate:cargo test --manifest-path src-tauri/Cargo.toml --test generate_fixture -- --ignored
pnpm test:e2eThis launches tauri-driver → WebKitWebDriver → the Screeny release binary with SCREENY_E2E=1, then runs 13
scenarios covering app launch, GIF open, frame selection, frame deletion, and export.
When SCREENY_E2E=1 is set, the app exposes deterministic Tauri commands (e2e_open_fixture, e2e_save_path) that
bypass native file dialogs, using fixture/temp paths instead. This keeps tests reliable without platform dialog
automation.
Environment variable overrides:
SCREENY_E2E_FIXTURE— custom path to the input GIF fixtureSCREENY_E2E_EXPORT— custom path for export output (defaults to/tmp/screeny-e2e/export.gif)
- macOS:
tauri-driverdoes not support macOS. E2E tests are Linux and Windows only. - Windows: not yet tested or set up.
tauri-driversupports Windows via the Edge WebDriver, but the wdio config and prerequisites need adapting. - WebKitWebDriver click interactability: some elements require JavaScript-based clicks (
browser.execute(el => el.click(), element)) because WebKitWebDriver rejects standard WebDriver clicks on certain toolbar buttons despite them being visible and enabled. - wdio v9 /
@wdio/tauri-service: the official Tauri wdio service requires wdio v8 and is incompatible with v9. The harness managestauri-driverlifecycle manually viabeforeSession/afterSessionhooks.
