HarborFM

HarborFM

Open source podcast creation. Build episodes from segments — record, trim, reorder — then export audio and RSS.

curl -fsSL https://raw.githubusercontent.com/LoganRickert/harborfm/main/install.sh | bash

When prompted, choose nginx and enter your domain and Let's Encrypt email. Best for a single domain: nginx, certbot for SSL, optional Fail2Ban. After install, run certbot once to get the cert; use a cron job to renew.

curl -fsSL https://raw.githubusercontent.com/LoganRickert/harborfm/main/install.sh | bash

When prompted, choose Caddy. Best for automatic HTTPS and dynamic or multiple hostnames — Caddy obtains and renews TLS certificates with no certbot. Ideal if you want custom subdomains per show or user.

HARBORFM_SECRETS_KEY=$(openssl rand -base64 32)
JWT_SECRET=$(openssl rand -base64 32)

docker run --name harborfm -p 3001:3001 \
  -v harborfm-data:/data \
  -e HARBORFM_SECRETS_KEY="$HARBORFM_SECRETS_KEY" \
  -e JWT_SECRET="$JWT_SECRET" \
  ghcr.io/loganrickert/harborfm:latest

Runs HarborFM as a single container. Use nginx or Caddy on the host for HTTPS. Open http://localhost:3001 and complete the one-time setup from the container logs.

git clone https://github.com/LoganRickert/harborfm.git
cd harborfm
pnpm install
pnpm run db:migrate
pnpm run dev

Requires Node.js 22+, pnpm, ffmpeg, and audiowaveform. Open the URL shown in the terminal; use the one-time setup link from the server logs to create the admin account.

About

HarborFM is a modern replacement for Anchor.fm. Create shows, add episodes, and build each episode from segments: record or upload clips, pull intros and bumpers from a library, trim and reorder, then export a single audio file and RSS feed. The app has PWA support — add it to your home screen and connect to your server.

Optional: transcripts via Whisper ASR, LLM helpers (Ollama or OpenAI) for copy suggestions, and public feed pages for discovery. Deploy feeds and audio to S3, R2, FTP, SFTP, WebDAV, IPFS, or SMB.

Features

Podcasts & episodesCreate shows with metadata, artwork, categories. Add episodes with title, description, season/episode numbers.
SegmentsBuild each episode from segments: recorded clips or library assets. Trim, split, remove silence; ffmpeg concatenates to final audio.
LibraryUpload reusable audio (intros, outros, bumpers). Tag and insert into any episode.
TranscriptsGenerate transcripts via Whisper ASR. Optional LLM integration for summaries and copy suggestions.
RSS & exportRSS feed per podcast. Deploy to S3, R2, FTP, SFTP, WebDAV, IPFS, SMB. Only changed files are uploaded.
Auth & usersFirst-user setup, registration, login, password reset. Optional admin and user management. Public feed pages when enabled.

Screenshots

Dashboard, episode editor, recording, and podcast delivery.

Dashboard with list of podcast shows
Dashboard — your shows
Episodes page with segment list
Episodes — build from segments
Recording a segment
Record a segment
Podcast delivery settings
Podcast delivery — S3, FTP, etc.
Library of reusable audio
Library — intros, bumpers
Transcript and LLM segment help
Transcripts & LLM help

Tech stack

Monorepo (pnpm workspaces): shared (Zod schemas, types), server (Fastify API, SQLite with better-sqlite3, ffmpeg for audio), web (React, Vite, TanStack Query). Single Node process serves the API and static web app; no separate database server.

Project structure

harborfm/
├── server/     # API and app entry
├── web/        # React frontend
├── shared/     # Shared schemas and types
├── Dockerfile  # Multi-stage build, Node + ffmpeg
└── pnpm-workspace.yaml

Requirements

For local dev: Node.js 22+, pnpm, ffmpeg, audiowaveform (e.g. brew install audiowaveform on macOS; on Linux, build from bbc/audiowaveform or use a package if available). The Docker image includes ffmpeg.

Open API docs (Swagger) GitHub