SkillAgentSearch skills...

Swiparr

Swipe on what to watch next.

Install / Use

/learn @m3sserstudi0s/Swiparr
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<p align="center"> <img src="https://github.com/user-attachments/assets/7803607a-e4e7-4824-81a3-8e2df132fc03" alt="Swiparr" width="300" /> </p> <h1 align="center">Swiparr 🍿</h1> <p align="center"> <strong>Discover what to watch next, by yourself or together.</strong> </p> <p align="center"> Swiparr turns the dreaded "what should we watch?" question into a fun, collaborative experience. <br> Like Tinder for movies, but smarter and works for groups. </p> <p align="center"> <img src="https://img.shields.io/github/license/m3sserstudi0s/swiparr" alt="License" /> <img src="https://img.shields.io/badge/docker-ghcr.io-blue" alt="Docker" /> <a href="https://www.buymeacoffee.com/jakobbjelver" target="_blank"> <img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=flat&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me a Coffee" /> </a> </p>

🎯 The Problem

The struggle is real: 30 minutes of "what should we watch?" that ends with watching the same show again. Swiparr fixes this by:

✨ Turning discovery into a fun, game-like experience
🤝 Finding content everyone actually wants to watch
⚡ Making group decisions in minutes, not hours
🌍 Working with your existing media libraries OR standalone


✨ Features

🎬 Content Discovery

  • Intuitive Swipe Interface - Browse movies with a familiar card-based design
  • Multi-Provider Support - Works with Jellyfin, Emby, Plex, or TMDB directly
  • Smart Matching - Automatically finds content everyone in your group will enjoy
  • Mobile-First - Optimized for phones, with desktop keyboard shortcuts
  • PWA Ready - Install as a web app for the best experience

👥 Built for Groups

  • Instant Sessions - Create or join in seconds, no complex setup
  • Flexible Match Rules - Choose "any two people" or "everyone must agree"
  • Session Controls - Limit likes, dislikes, or total matches
  • Watchlist Sync - Seamlessly save favorites back to your media server

🔧 Universal Compatibility

  • Jellyfin - Full native integration
  • Emby - Experimental support (improving)
  • Plex - Experimental support (improving)
  • TMDB - No media server required, works standalone

🚀 Quick Start

Fastest: Swiparr Global

No setup, no server, no problem.

🌐 swiparr.com - Free to use, community-supported (hopefully)

Easiest: Deploy to Vercel

One-click deployment, perfect for personal or small group use:

Deploy with Vercel

Note: The automatic deployment workflow in Vercel uses the Turso integration by default as a database service provider. Free to set up, possible to swap out [^1].

Vercel security note: AUTH_SECRET is auto-generated during the build (via scripts/ensure-auth-secret.cjs) and persisted in the database when not provided.

Full Control: Self-Host with Docker

Using Docker Compose (Recommended):

  1. Create docker-compose.yml:
services:
  swiparr:
    image: ghcr.io/m3sserstudi0s/swiparr:latest
    container_name: swiparr
    restart: unless-stopped
    environment:
      - PROVIDER=jellyfin  # or plex, emby, tmdb (or set PROVIDER_LOCK to "false")
      - JELLYFIN_URL=http://your-jellyfin:8096 # adjust to provider, none without server lock
    volumes:
      - ./swiparr-data:/app/data
    ports:
      - 4321:4321
  1. Run it:
docker compose up -d

Using Docker CLI:

docker run -d \
  --name swiparr \
  --restart unless-stopped \
  -p 4321:4321 \
  -v $(pwd)/swiparr-data:/app/data \
  -e PROVIDER=jellyfin \
  -e JELLYFIN_URL=http://your-jellyfin:8096 \
  ghcr.io/m3sserstudi0s/swiparr:latest
  1. Open http://localhost:4321

Docker security note: AUTH_SECRET is auto-generated on first boot (via scripts/ensure-auth-secret.cjs) and stored in the database when not provided.


⚙️ Configuration Reference

Provider-Specific Settings

Choose one provider setup based on your needs:

<details> <summary><strong>Jellyfin Setup</strong></summary>
PROVIDER=jellyfin
JELLYFIN_URL=http://your-jellyfin:8096              # Internal URL (required)
JELLYFIN_PUBLIC_URL=https://jellyfin.example.com    # Public URL (optional)
JELLYFIN_USE_WATCHLIST=false                         # Use Watchlist (plugin needed) vs Favorites (optional)
</details> <details> <summary><strong>Emby Setup (Experimental)</strong></summary>
PROVIDER=emby
EMBY_URL=http://your-emby:8096        # Internal URL (required)
EMBY_PUBLIC_URL=https://emby.example.com  # Public URL (optional)
</details> <details> <summary><strong>Plex Setup (Experimental)</strong></summary>
PROVIDER=plex
PLEX_URL=http://your-plex:32400       # Internal URL (required)
PLEX_PUBLIC_URL=https://plex.example.com # Public URL (optional)
</details> <details> <summary><strong>TMDB Setup (No Server Required)</strong></summary>
PROVIDER=tmdb
TMDB_ACCESS_TOKEN=your-tmdb-token     # API Read-Only Token (required)
TMDB_DEFAULT_REGION=SE                # Default region for availability/certifications (optional)
</details>

Security & Advanced Options

# Authentication
AUTH_SECRET=random-string-32-chars-min     # Auto-generated on boot/build when not provided. See Security & Privacy.
USE_SECURE_COOKIES=true                    # Required for HTTPS

# Application
PORT=4321                                  # Default port
HOSTNAME=0.0.0.0                          # Bind address
DATABASE_URL=file:/app/data/swiparr.db    # SQLite path or Turso URL
DATABASE_AUTH_TOKEN=your-token            # Required for Turso/Remote DB

# Base path (build-time only — see Custom Base Path section)
# URL_BASE_PATH=/swipe

# Admin
ADMIN_USERNAME=your-username                      # Global auto-grant admin privileges
JELLYFIN_ADMIN_USERNAME=jelly-admin               # Provider-specific admin (overrides global)
PLEX_ADMIN_USERNAME=plex-admin                   # Provider-specific admin (overrides global)
EMBY_ADMIN_USERNAME=emby-admin                   # Provider-specific admin (overrides global)

# Security Headers
X_FRAME_OPTIONS=DENY                       # Frame control
CSP_FRAME_ANCESTORS=none                   # Embedding policy

# Network Safety
ALLOW_PRIVATE_PROVIDER_URLS=false          # Block private/LAN URLs for user-supplied providers (BYOP)
PLEX_ALLOW_SELF_SIGNED=false               # Allow self-signed TLS for Plex (LAN only)
PLEX_IMAGE_ALLOWED_HOSTS=plex.example.com,*.plex.direct  # Optional extra image hosts

# BYOP Mode - Bring Your Own Provider
PROVIDER_LOCK=false                          # Let users choose and configure their own provider

# Misc
USE_ANALYTICS=false                          # Enable anonymous usage analytics (Vercel deployments)
ENABLE_DEBUG=false                           # Enable verbose debug logging and client-server error mapping

Environment Variable Matrix

| Variable | Required? | Default | Description | |----------|-----------|---------|-------------| | PROVIDER | ✳️ | jellyfin | Primary media provider (jellyfin, tmdb, plex, emby) | | PROVIDER_LOCK | ❌ | true | If true, users cannot change the provider at runtime | | JELLYFIN_URL | ✳️ | - | Internal URL of your Jellyfin server | | JELLYFIN_PUBLIC_URL | ❌ | - | Public URL of your Jellyfin server (for client-side access) | | JELLYFIN_USE_WATCHLIST | ❌ | false | Use Jellyfin Watchlist instead of Favorites | | EMBY_URL | ✳️ | - | Internal URL of your Emby server | | EMBY_PUBLIC_URL | ❌ | - | Public URL of your Emby server (for client-side access) | | PLEX_URL | ✳️ | - | Internal URL of your Plex server | | PLEX_PUBLIC_URL | ❌ | - | Public URL of your Plex server (for client-side access) | | PLEX_TOKEN | ❌ | - | Plex Admin/Access Token | | TMDB_ACCESS_TOKEN | ✳️ | - | TMDB API Read-Only Access Token | | TMDB_DEFAULT_REGION | ❌ | SE | Default TMDB region (ISO 3166-1) for streaming availability/certifications | | AUTH_SECRET | ❌ | Auto-generated on boot/build | Secret used for session encryption and guest lending token encryption (min 32 chars). See Security & Privacy. | | USE_SECURE_COOKIES | ❌ | false | Set to true for HTTPS deployments | | DATABASE_URL | ❌ | file:/app/data/swiparr.db | SQLite path or Turso URL [^1] | | DATABASE_AUTH_TOKEN| ❌ | - | Auth token for remote databases (e.g. Turso) | | APP_PUBLIC_URL | ❌ | swiparr.com | The public domain where the app is hosted | | URL_BASE_PATH | ❌ | - | Base path for subpath deployments (e.g. /swipe). Must be set at image build time — see Custom Base Path. | | ADMIN_USERNAME | ❌ | - | Global admin username (overrides provider-specific) [^2] | | JELLYFIN_ADMIN_USERNAME | ❌ | - | Jellyfin-specific admin username [^2] | | EMBY_ADMIN_USERNAME | ❌ |

View on GitHub
GitHub Stars444
CategoryDevelopment
Updated1d ago
Forks14

Languages

TypeScript

Security Score

100/100

Audited on Mar 27, 2026

No findings