Create animated GIFs from Google Slides presentations.
Check it out at slides2gif.com!
Requires Just: brew install just or cargo install just.
just setup— Configure Google Cloud (auth, APIs, buckets). Run once.just verify-env— Check required secrets exist in GSM. Run beforejust dev.just install— Install dependencies for www and png2gif.just dev— Run www + png2gif (secrets from GSM).just build— Build www and png2gif.just lint— Lint www and png2gif.
Each of dev, install, build, and lint has a -www or -png2gif variant (e.g. just dev-www). Also: just ci (full CI locally), just clean (remove build artifacts).
Secrets live in Google Secret Manager (no local .env). First time: just create-secret <name> for secret-cookie-password, oauth-client-id, oauth-client-secret — you’ll be prompted for values. OAuth credentials: APIs & Services → Credentials → Create OAuth 2.0 Client ID (web app).
The project consists of two main services:
- Frontend web application
- API routes for Google Slides integration
- Runs on port
3000(default)
- Converts PNG images to animated GIFs
- Runs on port
3001(configurable viaPORTenv var)
- No authentication required - Both services run without auth in local development
- The png2gif service skips authentication when
NODE_ENV !== 'production'orGOOGLE_CLOUD_PROJECTis not set
- Service-to-service authentication - The www service uses Google Auth Library to get ID tokens
- The png2gif service verifies the
Authorization: Bearer <token>header - Set
PNG2GIF_SERVICE_URLenvironment variable to the Cloud Run service URL
All secrets are loaded from Google Secret Manager when you run just dev. Before starting, the dev command checks that all required env vars are set (from GSM); if any are missing, it exits with a clear error. Required (must exist in GSM):
secret-cookie-password→SECRET_COOKIE_PASSWORD(32+ chars)oauth-client-id→OAUTH_CLIENT_IDoauth-client-secret→OAUTH_CLIENT_SECRETgoogle-cloud-project-number→GOOGLE_CLOUD_PROJECT_NUMBER(Drive Picker)google-picker-developer-key→GOOGLE_PICKER_DEVELOPER_KEY(Drive Picker)
Optional / non-secret: GCS_CACHE_BUCKET (defaults to slides2gif-cache), PNG2GIF_SERVICE_URL (defaults to http://localhost:3001).
Required:
SECRET_COOKIE_PASSWORD- Secret key for encrypting session cookiesOAUTH_CLIENT_ID_PROD- Google OAuth 2.0 Client ID (production)OAUTH_CLIENT_SECRET_PROD- Google OAuth 2.0 Client Secret (production)GCS_CACHE_BUCKET- Google Cloud Storage bucket name for caching
Note: You can use OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET as fallback if you prefer a single client for both environments.
Optional:
PNG2GIF_SERVICE_URL- URL of the png2gif Cloud Run serviceGOOGLE_CLOUD_PROJECT- Google Cloud project ID (automatically set in Cloud Run)
- Frontend
- Next.js / React
- Tailwind CSS
- Material Icons
- Backend
- Cloud Run
- Docker
- Node.js
- APIs
- Google Slides API
- Google Sign-in API
- Google Cloud Storage
Using the Google Slides API to create thumbnails is expensive and has limits.
See limits:
- 500 per project per 100 seconds
- 100 per user per 100 seconds
Configure your Google Cloud project:
just setupThis checks and configures authentication, project, APIs, buckets, service account, and Application Default Credentials. Run it multiple times; it's idempotent.
After setup, deploy both services so they can connect on Cloud Run:
just deployThis will:
- Deploy
png2giffirst (Cloud Run service that converts slides to GIF). - Deploy
wwwwithPNG2GIF_SERVICE_URLset to the png2gif URL (so the "Create GIF" flow works). - Resolve the www service account (custom SA or default compute) and grant it Cloud Run Invoker on the png2gif service so www can call png2gif with an ID token.
- Verify secret access for www.
Order matters: png2gif must be deployed before www so the deploy can discover its URL. Use just deploy to do both in one go.
Secrets live in Google Secret Manager (local dev and production). No .env is needed once secrets are in GSM.
Required secrets (must exist in GSM): secret-cookie-password, oauth-client-id, oauth-client-secret. Verify: just verify-env. First-time: just create-secret <name> for each; you’ll be prompted for values. OAuth: APIs & Services → Credentials → Create OAuth 2.0 Client ID (web application).
To deploy services separately:
just deploy-png2gif
just setup-iam
just deploy-wwwDeploying www without png2gif first will leave PNG2GIF_SERVICE_URL unset until you run just deploy or redeploy www after png2gif exists.