Lottie works in Electron's renderer process exactly like it does in a browser. Here's how to integrate it properly, including file serving, IPC patterns, and performance considerations.
Why Lottie in Electron?
Desktop apps built with Electron often use simple CSS animations or static images for UI feedback. Lottie gives you After Effects-quality animations at a fraction of the file size — loading states, onboarding illustrations, success/error feedback, and empty states all benefit from it.
The key advantage in Electron: you're serving files locally, so there's no network latency. A .lottie file loads instantly from the app bundle.
Setup
npm install @lottiefiles/dotlottie-web
# or if using React in renderer:
npm install @lottiefiles/dotlottie-react
Place animation files in your renderer's public/assets directory.
Basic Integration (Vanilla JS Renderer)
In your renderer process HTML or JS:
const { DotLottie } = require('@lottiefiles/dotlottie-web');
// or if using ES modules:
import { DotLottie } from '@lottiefiles/dotlottie-web';
const canvas = document.getElementById('lottie-canvas');
const anim = new DotLottie({
canvas,
src: './assets/animations/loading.lottie',
loop: true,
autoplay: true,
});
<canvas id="lottie-canvas" width="120" height="120"></canvas>
Use relative paths for local files — Electron serves renderer files from the app directory.
React Renderer Integration
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
function LoadingState() {
return (
<DotLottieReact
src="./assets/animations/loading.lottie"
loop
autoplay
style={{ width: 120, height: 120 }}
/>
);
}
For paths in Electron + React (webpack/vite), import the file directly:
import loadingLottie from './assets/loading.lottie';
<DotLottieReact src={loadingLottie} loop autoplay />
This lets the bundler handle the path correctly across dev and production builds.
Preloading Animations
For animations that need to play immediately (like a splash screen), preload in the main process:
// main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
const fs = require('fs');
app.whenReady().then(() => {
const win = new BrowserWindow({ width: 800, height: 600 });
// Preload the animation file
const animPath = path.join(__dirname, 'renderer/assets/loading.lottie');
const animData = fs.readFileSync(animPath);
win.webContents.on('did-finish-load', () => {
// Send animation data via IPC if needed
win.webContents.send('animation-data', animData.toString('base64'));
});
win.loadFile('renderer/index.html');
});
IPC-Triggered Animations
A common pattern is triggering animations from main process events:
// renderer.js
const { ipcRenderer } = require('electron');
const { DotLottie } = require('@lottiefiles/dotlottie-web');
let anim = null;
ipcRenderer.on('show-progress', () => {
const canvas = document.getElementById('progress-canvas');
canvas.style.display = 'block';
anim = new DotLottie({ canvas, src: './assets/progress.lottie', loop: true, autoplay: true });
});
ipcRenderer.on('hide-progress', () => {
anim?.destroy();
anim = null;
document.getElementById('progress-canvas').style.display = 'none';
});
// main.js - during a long operation
win.webContents.send('show-progress');
await performLongOperation();
win.webContents.send('hide-progress');
Performance Notes
Electron apps often run on lower-powered machines. A few rules:
- Use .lottie format (75% smaller than .json) — less memory at load
- Destroy animations when windows are hidden: listen to
app.on('browser-window-blur') - Avoid running animations in hidden/background windows
- Prefer canvas renderer for complex animations, SVG for simple ones
Preparing Files
Get .lottie files from IconKing — paste your .json, edit colors to match your app's theme, and download as .lottie. No account needed, runs in the browser.
Distribution
Animation files in Electron need to be included in your build. In electron-builder:
{
"build": {
"extraResources": [
{ "from": "renderer/assets/animations/", "to": "animations/" }
]
}
}
Then access them at runtime:
const path = require('path');
const animPath = path.join(process.resourcesPath, 'animations/loading.lottie');
Top comments (0)