Skip to content

Repository files navigation

GifStudio

VersionLicensePlatformLanguageType

Browser-based GIF creation and editing studio. Create, edit, optimize, and export GIFs with frame manipulation, filters, and timing controls — 100% client-side and zero install.

Launch GifStudio

Features

Import

  • GIF Import — Extract and edit GIFs within the documented dimension, frame-count, and decoded-memory limits
  • Image Sequence — Drag-drop or select multiple JPG, PNG, or WebP files to create a new GIF
  • Frame Inspector — View decoded dimensions/timing for every source, raw block details when the JS GIF parser is used, memory estimates, and validated output summaries

Edit

  • Frame Editor — Add, remove, reorder, duplicate, and reverse frames with copy-on-write, byte-budgeted undo/redo
  • Multi-Select — Shift+click for range selection, Ctrl/Cmd+click to toggle individual frames
  • Timing Control — Edit GIF delays in centiseconds or APNG delays in milliseconds, with encoded duration and FPS diagnostics
  • Playback Modes — Normal, Ping-pong, and Boomerang playback
  • Transforms — Resize, crop, canvas expand (padding), flip horizontal/vertical, and rotate 90°
  • Resize Presets — Discord Emoji, Telegram Sticker, Twitter/X, Full HD, and more
  • Filters — Brightness, contrast, saturation, and hue-rotate with live canvas preview
  • Redaction — Pixelate, blur, or black-fill regions across selected frames
  • Background Layer — Burn a solid color or image behind all frames

Export & Optimize

  • GIF Export — gifenc PNN quantizer, quality, Floyd-Steinberg dithering, configurable color count (16–256), loop control
  • APNG Export — Millisecond timing, alpha support, and optional palette reduction through the bundled UPNG.js codec
  • GIF Optimization — Lossy LZW compression via gifsicle-wasm (O1/O2/O3 levels)
  • Split Frames — Export all frames as numbered PNGs in a ZIP archive
  • Purpose-specific fit guidance — Estimates and final bytes are checked against source-dated Discord message/emoji and X web/mobile GIF limits
  • Custom Filename — Defaults to original filename + "-edited"
  • Direct Save — File System Access API for save-to-disk on Chromium; standard download elsewhere
  • Share — Web Share API button for one-tap sharing on supported devices

Privacy & Performance

  • 100% Client-Side — Nothing is uploaded. All processing happens in your browser.
  • Zero Install — The core GIF editor runs from index.html; the repository and hosted PWA include local optional APNG/optimization assets.
  • Inline Codecs — Self-contained GIF decoder + gifenc PNN encoder with no external dependencies
  • Offline PWA — When served over HTTP(S), the service worker caches the app shell and optional codecs, reports update readiness, and falls back to the cache when offline
  • Strict Decoding — Structurally validates every GIF with the bounded JavaScript parser, then uses the browser ImageDecoder API for pixels when available
  • Lazy Thumbnails — Timeline uses IntersectionObserver + CSS content-visibility for smooth scrolling
  • Safari Memory Safety — Explicit canvas cleanup prevents memory leaks on WebKit browsers
  • Vendored Fonts — All fonts inlined as base64 woff2; zero external requests
  • Local Diagnostics — Copy app/capability/fallback, memory, export-profile, and sanitized error text without frames, filenames, URLs, user-agent data, or telemetry

Accessibility & Mobile

  • ARIA Support — Screen reader roles on canvas, timeline, modal, toast, and sidebar; keyboard-operated edit sections persist their open state, and hidden import controls become inert while a project is loaded
  • Keyboard Navigation — Focus-visible outlines, proper label associations, Escape to close modals
  • Reduced Motion — Respects prefers-reduced-motion for UI animations
  • Mobile Drawer — Sidebar slides out on small screens via hamburger toggle
  • Dark Theme — Professional dark interface with color-scheme: dark for native controls

Capabilities and Limits

AreaVerified behavior
Processing and privacyFrames, recovery data, and exports stay in the browser. GifStudio has no backend or telemetry.
Core GIF editingWorks from a local index.html. APNG export, optimization, installability, updates, and complete offline use require the repository/hosted app so the vendored assets and service worker are present.
Offline behaviorAfter one successful HTTP(S) load, the service worker caches index.html, the manifest, icon, and all optional codecs. A local file:// page cannot register that service worker.
Decoder fallbackEvery GIF passes strict structural validation before optional native ImageDecoder pixel decoding. Both pixel paths enforce 8192×8192, 500-frame, and 256 MiB decoded-frame limits; parser input and accumulated sub-block data are capped at 128 MiB.
Memory guardImport, restore, edits, autosave, and export estimate unique resident canvases and temporary RGBA buffers before allocation. Undo/redo shares unchanged canvases and is capped at one quarter of the device-aware budget. The default peak budget is 256 MiB on devices reporting ≤2 GiB, 384 MiB at ≤4 GiB, and 512 MiB otherwise. A deliberate one-operation override is offered only below the device-aware ceiling, never above 1 GiB.
TimingGIF controls and output use centiseconds; values are rounded deterministically to 10 ms units. APNG controls and output use milliseconds. Source, edited, and encoded durations are shown separately.
Output validationGIF/APNG downloads and success messages occur only after structural, dimension, frame-control, and encoded-timing checks pass.
Platform fitEstimated and final encoded bytes are compared with purpose-specific limits reviewed on 2026-07-29: Discord uploads, Discord emoji, and X web/mobile GIFs. Limits can change; verify the destination policy before posting.
Split-frame ZIPPNG splitting uses the shared progress/cancel flow, checks serialization and CRCs, and stops before allocation above 500 entries or a 512 MiB estimated/actual ZIP. Output basenames are normalized for cross-platform filesystems.
Browser APIsDirect Save uses the File System Access API when present and downloads otherwise. Share appears only when the Web Share API accepts files.
RecoveryVersioned IndexedDB sessions are isolated per browser tab and retained for up to seven days or until dismissed. Diagnostics report usage, quota, and best-effort/persistent durability; users can request persistent storage without blocking autosave. Autosave reuses cached PNG data for unchanged canvases, quota failures retain the last committed recovery, stale tabs cannot delete active records, and abandoned sessions can be reclaimed.
DiagnosticsThe sidebar report identifies decoder/save/share/clipboard/service-worker/storage/codec fallbacks and the last sanitized error. It contains project dimensions/count but excludes media, filenames, URLs, user-agent data, and telemetry.

GIF export intentionally uses full-canvas frame descriptors. The older v0.2.0 changed-region encoder was superseded by gifenc in v0.4.0 because safe local-frame encoding needs look-ahead disposal handling for opaque-to-transparent transitions. The bundled optimizer remains the supported size-reduction path.

Usage

  1. Open GifStudio in your browser — or download index.html for core GIF editing; clone/download the repository to use optional codecs locally
  2. Drop a GIF to edit, or drop multiple images to create a new GIF
  3. Edit frames, apply filters, adjust timing
  4. Export or optimize and download

Development and Release Checks

npm ci
npx playwright install chromium firefox webkit
npm run check:vendor
npm run build:artifact
npm test
npm run test:visual:update # explicitly review and refresh screenshot baselines
npm run lint
npm run build

npm run refresh:vendor stages the exact lockfile-resolved codec payloads and upstream license files, regenerates vendor/integrity.json, updates the versioned asset references, and rebuilds index.html. Run npm run check:vendor to detect payload/license drift; it also reruns the adopted pako 3.0.1 APNG byte, round-trip, and Chromium/Firefox/WebKit gate. The UPNG.js allocation guard is recorded in the generated metadata and reapplied deterministically.

JavaScript source is maintained in three generated boundaries:

  • src/gif-decoder.js — strict GIF parser/decompressor, loaded directly by Node unit tests
  • src/gif-encoder.js — bundled gifenc core and the GifStudio encoder wrapper
  • src/history-controller.js, src/recovery-controller.js, and src/export-controller.js — dependency-injected editor lifecycle controllers with focused unit tests
  • src/app.js — editor state, storage, operations, exporters, and UI behavior

src/index.template.html owns the document/CSS shell. npm run build:artifact normalizes line endings and embeds those boundaries to generate the zero-install index.html; do not hand-edit the generated scripts. npm run check:artifact fails on any byte drift, and .gitattributes pins text files to LF so a clean checkout reproduces the same artifact across platforms.

npm test first checks artifact reproducibility, then runs deterministic parser fixtures, truncation sweeps, and bounded byte mutations directly against src/gif-decoder.js before Playwright exercises the shipped index.html in Chromium, Firefox, and WebKit. A separate Chromium project compares deterministic baselines for the empty workspace, loaded editor, recovery banner, export modal, and 390-pixel drawer; baseline changes require the explicit npm run test:visual:update command and review. Optional browser capabilities are gated explicitly while the shared import, edit, export, recovery, accessibility, and offline contracts run in every engine. The static release check parses both source and embedded scripts and also verifies version consistency, CSP, manifest/icon references, service-worker registration, vendored codec hashes/SRI, and the README badge. CI runs the same commands on every push and pull request.

License

MIT License

Bundled optional codecs retain their upstream licenses: pako 3.0.1 (MIT and Zlib), UPNG.js 2.1.0 (MIT), and gifsicle-wasm-browser 1.5.19 (MIT). Exact source hashes and license texts are under vendor/.

About

Browser-based GIF creation and editing studio with frame manipulation, effects, and export options — 100% client-side, single HTML file.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages