Dirework is a personal project built for my own Twitch co-working and body-doubling streams. It combines a Pomodoro timer, viewer task list, and Twitch chat bot into a single self-hosted tool with customizable OBS overlays.
It is open source and runs entirely on Cloudflare's free plan. If you want the same setup for your own channel, fork it and deploy your own instance — one streamer, one instance, zero distractions.
- Pomodoro Timer - Configurable work/break cycles with a macOS-style progress ring, visible as an OBS overlay.
- Task List - Viewers add and manage tasks via chat commands, displayed as a scrolling OBS overlay.
- Twitch Bot - Dedicated bot account for chat commands
like
!task,!done,!timer start, and!time. Customizable wolf-themed response messages, enable/disable toggles for task and timer command groups, and configurable phase labels. The bot runs in a token-gated browser page (OBS source or pinned tab) — no always-on server needed. - Theme Center - 11 built-in themes including Liquid Glass, Neon Cyberpunk, Sakura, and Retro Terminal with full style customization for colors, fonts, and layout.
- Live Preview - See overlay changes on the dashboard before going live.
- Dashboard - Control the timer, manage tasks, and preview overlays from one page.
- Bot Settings - Bot account management, message customization, command aliases, and the bot console link.
- Serverless - Two Cloudflare Workers plus a D1 database. Free plan, no servers, no Docker, single user per instance.
For full setup instructions including Twitch OAuth, bot account configuration, and OBS setup, see the Documentation.
- Clone the repository
- Install dependencies with
bun install - Copy
.env.exampletopackages/infra/.envand fill inTWITCH_CLIENT_ID,TWITCH_CLIENT_SECRET, and a generatedBETTER_AUTH_SECRET - Start everything with
bun run dev(API worker on port 3000, web on port 3001, local D1 database included) - Open
http://localhost:3001— on first run you'll be redirected to/setupto claim the instance with your Twitch account
| Command | Description |
|---|---|
!task <text> |
Add a new task |
!done [number] |
Mark your oldest (or specific) task done |
!edit [number] <text> |
Edit your oldest (or specific) task |
!remove [number] |
Remove your oldest (or specific) task |
!next <text> |
Complete current task and start a new one |
!check [@user] |
Show your (or another user's) tasks |
| Command | Description |
|---|---|
!clear |
Clear all tasks |
!cleardone |
Clear completed tasks |
!adel @user |
Remove all tasks from a user |
| Command | Description |
|---|---|
!timer start |
Start the timer |
!timer <minutes> |
Start with specific duration |
!timer pause/resume |
Pause or resume the timer |
!timer skip |
Skip the current phase |
!timer goal <num> |
Set pomodoro cycle count |
!time |
Show remaining time |
!eta |
Show when the timer ends |
See the full command reference for all options and customizable bot responses.
Navigate to /dashboard/bot to manage your bot account,
customize all response messages (wolf-themed defaults included),
enable or disable task and timer command groups, set up command
aliases, and copy your bot console link. The bot listens to chat
while the bot console page is open — add it to OBS as a browser
source or keep the tab pinned.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router), React 19, TypeScript 5 |
| Styling | Tailwind CSS v4, shadcn/ui |
| API | Hono + tRPC v11, TanStack React Query |
| Auth | Better Auth (Twitch OAuth) |
| Database | Cloudflare D1 (SQLite) + Drizzle ORM |
| Chat Bot | IRC-over-WebSocket in a token-gated browser page |
| Runtime | Cloudflare Workers (web via OpenNext) |
| Deploy | Alchemy (infrastructure-as-code) + GitHub Actions |
| Docs | Fumadocs |
| Monorepo | Turborepo + Bun workspaces |
- Node.js 22+
- Bun 1.3+
- A Twitch Developer Application (dev.twitch.tv)
-
Clone the repository:
git clone https://github.com/mrdemonwolf/dirework.git cd dirework -
Install dependencies:
bun install
-
Create your environment file:
cp .env.example packages/infra/.env
Fill in
TWITCH_CLIENT_IDandTWITCH_CLIENT_SECRETfrom dev.twitch.tv/console/apps, and generateBETTER_AUTH_SECRETwithopenssl rand -base64 32. Addhttp://localhost:3001/api/auth/callback/twitchandhttp://localhost:3001/api/bot/callback/twitchas redirect URLs on your Twitch app. -
Start everything:
bun run dev
Alchemy runs the API worker (port 3000), the web app (port 3001), and a local D1 database with migrations applied.
bun run dev- Start all apps with a local D1 databasebun run dev:web- Start the web app onlybun run dev:server- Start the API worker onlybun run build- Build all apps for productionbun run check-types- Run TypeScript type checkingbun run test- Run unit tests across all packagesbun run db:generate- Generate a new Drizzle migration from schema changesbun run deploy- Deploy both workers and the database to Cloudflarebun run destroy- Tear down the Cloudflare deployment
- Vitest for unit testing across all packages
- Tests cover the timer state machine, task/timer services, config build/flatten helpers, round-trip consistency, display utilities, task grouping, and token verification
- Run with
bun run test
- TypeScript in strict mode across all packages
- Drizzle ORM for type-safe database access
- tRPC for end-to-end type-safe API layer
- t3-env for environment variable validation
- Turborepo for monorepo build orchestration
- GitHub Actions CI runs type checks, builds, and tests on every push
Dirework deploys to Cloudflare Workers via GitHub Actions:
set five repository secrets, push to main, done. Both
workers, the D1 database, and its migrations are managed by
Alchemy.
See the Deployment guide for the step-by-step walkthrough (Cloudflare API token, Twitch redirect URLs, GitHub secrets, and the post-deploy checklist).
dirework/
├── apps/
│ ├── web/ # Next.js app on Workers (dashboard, overlays, bot page), port 3001
│ ├── server/ # Hono API worker (auth, tRPC, bot OAuth), port 3000
│ └── fumadocs/ # Documentation site, port 4000
├── packages/
│ ├── api/ # tRPC routers, services, bot command logic
│ ├── auth/ # Better Auth configuration
│ ├── db/ # Drizzle schema + D1 client + migrations
│ ├── env/ # Environment bindings + validation
│ ├── infra/ # Alchemy infrastructure (workers + D1)
│ └── config/ # Shared TypeScript configuration
If you have any questions, suggestions, or feedback:
- Discord: Join my server
Made with love by MrDemonWolf, Inc.