A lightweight web-based slideshow application to randomly display images from a directory. Migrated from Rust to TypeScript Node.js, specifically optimized for easier setup on Raspberry Pi.
I run it on a Raspberry pi, hooked up to a TV to have a slideshow of my favorite photos.
src/: Express backend API and file scanner.public/: Vanilla JS and HTML frontend.
- Node.js (v18+)
- PM2 (for running in background:
npm install -g pm2)
- Clone the repository:
git clone https://github.com/idc101/slideshow.git
cd slideshow- Install dependencies and build:
npm install
npm run build- Run the application:
# To run normally
PICTURES_BASE=/path/to/photos npm start
# Or to run with PM2 in the background
PICTURES_BASE=/path/to/photos npm run pm2- The application will be available at
http://localhost:8000
The application can be configured through the following environment variables:
PICTURES_BASE: Slideshow directory pathSLIDESHOW_INTERVAL: Interval in seconds to wait before changing image (default 300)PORT: Port to run the Express server on (default 8000)
This setup runs the slideshow with PM2 and launches a fullscreen Chromium browser with the slideshow URL to display on HDMI.
- Install Chromium browser:
sudo apt-get update
sudo apt-get install chromium- Install PM2 and save it to startup:
sudo npm install -g pm2
pm2 startup
# Follow the command provided by pm2 startup- Start the app:
PICTURES_BASE=/path/to/photos pm2 start dist/index.js --name "slideshow"
pm2 save- Create
~/bin/start-chromium.sh:
#!/bin/sh
set -e
CHROMIUM_TEMP=~/tmp/chromium
rm -Rf ~/.config/chromium/
rm -Rf $CHROMIUM_TEMP
mkdir -p $CHROMIUM_TEMP
chromium-browser \
--disable \
--disable-translate \
--disable-infobars \
--disable-suggestions-service \
--disable-save-password-bubble \
--disk-cache-dir=$CHROMIUM_TEMP/cache/ \
--user-data-dir=$CHROMIUM_TEMP/user_data/ \
--start-maximized \
--kiosk http://localhost:8000 &- Launch Chromium on startup:
echo "@sh $HOME/bin/start-chromium.sh" >> ~/.config/lxsession/LXDE-pi/autostartIf you have a TV connected via HDMI, you can turn it on and off with CEC Control.
The backend provides the following API endpoints:
GET /api/settings- Get interval settingsGET /api/image/<num>- Get a specific imageGET /api/image/<num>/metadata- Get metadata for a specific image