HowlCast is a self-hosted, invite-only live streaming platform for a single broadcaster. It runs on Cloudflare Workers and uses GetStream for the live video and chat path, so streams stay fast everywhere while the surrounding app — auth, channel page, dashboard, emotes, panels, branding — is fully under your control. Built for one person who wants Twitch-style streaming without Twitch.
Stream on your terms. Keep the howl in the den.
- Invite-only by design. A single
is_invitedflag gates chat posting on every stream and gates watching on private streams. No tiers, no subscriptions, no follower counts. - Public or private per stream. Toggle visibility before going live. Public streams let anyone watch (invitees chat); private streams hide everything from non-invitees.
- Cloudflare-native. Two Workers (web on
howlcast.tv, API onapi.howlcast.tv), D1 for data, R2 for avatars and panel images, KV for emote metadata, all provisioned declaratively via Alchemy. - GetStream live path. RTMPS ingest from OBS, WebRTC playback to viewers. Stream content never touches your Workers — they only mint short-lived JWTs and serve UI.
- Multi-provider emotes. Channel and global emotes pulled from Twitch, 7TV, BTTV, and FrankerFaceZ using your single Twitch user ID. Refreshed every 12 hours plus a manual refresh button on the dashboard.
- Better Auth with four sign-in methods. Email + password, username,
magic link, and passkey. Two-factor authentication built in. Sessions
share across
howlcast.tvsubdomains. - Discord webhooks for go-live. Two webhooks (public stream and private stream) configured from the dashboard, fired automatically when streams start and end.
- White-label ready. Custom logo, platform name, footer attribution, and bare-minimum Privacy Policy and Terms editor live in the broadcaster dashboard. Drop in your own brand without touching code.
- Den-only layout. One channel page, one streamer, one focused viewing experience. No theatre mode, no editorial mode, no decision fatigue.
Full docs live in docs/. Start with
START-HERE.md for the two-job onboarding flow, or
PRE-FLIGHT.md for the account-setup checklist.
Quick start once accounts are wired:
- Clone the repository and install dependencies with
bun install. - Copy
.envvalues intoapps/server/.env,apps/web/.env, andpackages/infra/.envper the manifests inPRE-FLIGHT.md. - Run
bun run db:generateto materialise the initial migrations. - Run
bun run devto boot both Workers locally. - Open
http://localhost:3001for the web app andhttp://localhost:3000/api/healthfor the API health check.
| Layer | Technology |
|---|---|
| Frontend | Next.js 16, React 19, Tailwind CSS v4 |
| UI primitives | shadcn/ui, lucide-react |
| Backend | Hono on Cloudflare Workers |
| API | tRPC v11 |
| Auth | Better Auth 1.5 with Drizzle adapter |
| Database | Cloudflare D1 (SQLite) |
| ORM | Drizzle |
| Object storage | Cloudflare R2 (howlcast-public, howlcast-isr) |
| Cache | Cloudflare KV (HOWLCAST_EMOTES) |
| Live video and chat | GetStream |
| Resend | |
| Infrastructure | Alchemy |
| Deploy target | Cloudflare Workers |
| Build tooling | Turborepo, bun + Turborepo catalogs, ESLint, Prettier, Husky |
| Runtime | Node 20+, bun 1.3+ |
- Node.js 20 or newer
- bun 1.3 or newer
- Wrangler 4 or newer, authenticated against your Cloudflare account
- A Cloudflare account on the Free plan (Paid is not required)
- A GetStream account with API credentials
- A Resend account with a verified sending domain
- OBS Studio (or any RTMPS-capable encoder) for testing streams
-
Install dependencies.
bun install
-
Generate the initial Drizzle migration from the auth schema.
bun run db:generate
-
Populate
apps/server/.env,apps/web/.env, andpackages/infra/.envwith values from your 1Password vault (seePRE-FLIGHT.md). -
Boot the dev environment.
bun run dev
-
Deploy to your Cloudflare account when you are ready.
bun run deploy
bun run dev- Run both Workers under Alchemy with hot reload.bun run dev:web- Run the web Worker only.bun run dev:server- Run the API Worker only.bun run dev:mail- Start mailpit (local dev inbox at http://localhost:8025).bun run dev:mail:stop- Stop the mailpit container.bun run dev:mail:logs- Tail the mailpit container logs.bun run build- Build all workspaces via Turborepo.bun run check-types- Type-check every workspace.bun run check- Run ESLint and Prettier format check across the repo.bun run lint- Run ESLint only.bun run lint:fix- Run ESLint with autofix.bun run format- Format all files with Prettier.bun run test- Run tests across all workspaces via Turborepo.bun run db:generate- Generate Drizzle migrations from the schema.bun run db:push- Push the Drizzle schema directly (skips migration files).bun run deploy- Provision and deploy all Cloudflare resources via Alchemy.bun run destroy- Tear down the Alchemy-managed Cloudflare resources.
HowlCast uses three email transports, chosen automatically:
- If
RESEND_API_KEYis set, mail goes through Resend. Production path. - Else if
SMTP_URLis set and reachable, mail goes through SMTP. Local default points at mailpit onlocalhost:1025. Runbun run dev:mailto start mailpit, then open the inbox at http://localhost:8025 to see captured emails. - Else the email is printed to the server terminal. Zero-setup fallback; handy when you just want to click a magic link without spinning Docker.
- ESLint handles linting; Prettier handles formatting. Both run together
via
lint-stagedon pre-commit. - Husky runs
lint-stagedonpre-commitso commits never land malformed code. - TypeScript is configured with
tsc -bfor incremental project references. - React Compiler is enabled on the web Worker for automatic memoisation.
howlcast/
├── apps/
│ ├── web/ # Next.js Worker - howlcast.tv
│ └── server/ # Hono Worker - api.howlcast.tv
├── packages/
│ ├── api/ # tRPC routers and context
│ ├── auth/ # Better Auth factory
│ ├── config/ # Shared TypeScript and tooling config
│ ├── db/ # Drizzle schema, migrations, client factory
│ ├── env/ # Validated runtime env loaders
│ ├── infra/ # Alchemy resource declarations
│ ├── mail/ # Email transport (Resend / SMTP / console)
│ └── ui/ # shadcn components and globals.css tokens
├── design-handoff/ # Locked HTML mockups and design tokens
├── docs/ # Architecture, build plan, integration guides
├── assets/ # Brand SVGs and logo variants
├── CLAUDE.md # AI collaborator instructions
├── DESIGN-DECISIONS.md # Locked product and design decisions
├── PRE-FLIGHT.md # Pre-scaffold account setup checklist
├── PROGRESS.md # Phase-by-phase build progress
├── RESUME.md # Session resume context for Claude Code
└── START-HERE.md # Top-level onboarding doc
- Discord: Join my server
- Website: mrdemonwolf.com
Made with love by MrDemonWolf, Inc.