Thread is a task and schedule manager with native desktop and mobile clients, cloud synchronization, release management, and administration services. This repository combines the former component repositories into one monorepo while retaining their Git histories.
Track. Handle. Remember. Execute. And Deliver.
Website: https://threadapp.kr
| Path | Purpose | Docker Compose |
|---|---|---|
apps/desktop/ |
Electron and React desktop client | No |
apps/mobile/ |
React Native mobile client | No |
packages/e2ee/ |
E2EE and sync protocol shared by desktop/mobile | No |
apps/web/site/ |
React public site | Yes |
apps/web/admin/ |
React administration site | Yes |
services/api/ |
Go and Gin authentication/synchronization server | Yes |
services/rms/ |
Node.js release management server | Yes |
Docker Compose runs MySQL, Redis, the application server, RMS, the public site, and the administration site. Desktop and mobile clients remain native development targets.
Copy-Item .env.example .env
docker compose up --buildLocal endpoints:
- Public site:
http://localhost:3000 - Administration site:
http://localhost:3001 - Application server:
http://localhost:4033 - RMS:
http://localhost:4034
The example credentials are development-only placeholders. Set ADMIN_ID and ADMIN_PASSWORD, replace the database and JWT secrets, and configure real Google OAuth credentials with a matching redirect URL before starting the stack outside a local machine.
Compose injects the administration site's public API endpoints at build time. Keep local values in .env, and set ADMIN_APP_SERVER_ENTRY=https://api.threadapp.kr and ADMIN_RMS_ENTRY=https://rms.threadapp.kr in the ignored root .env.production. Because Create React App embeds these values in the browser bundle, rebuild admin-site after changing them. Start the production stack with:
docker compose --env-file .env.production up -d --buildAll published Compose ports bind to 127.0.0.1. A host-installed Cloudflare Tunnel can publish the site, administration site, API, and RMS from ports 3000, 3001, 4033, and 4034 without exposing those origin ports directly. Set USE_HTTPS=false when Cloudflare terminates public TLS and connects to the private API origin over HTTP. Set it to true only when the Go API itself has readable certificates/cert.pem and certificates/key.pem files.
The administration site uploads desktop release files to RMS in sequential 8 MiB chunks, allowing installers larger than Cloudflare's per-request upload limit. RMS assembles and validates the chunks before marking the platform release as available. Completed releases persist in the rms-releases Compose volume.
The root .env belongs exclusively to the Compose stack. Native clients do not read it. Desktop uses an ignored apps/desktop/.env for development and the packaged apps/desktop/.env.production for production. Create the development file from its template:
Copy-Item apps/desktop/.env.example apps/desktop/.envMobile reads apps/mobile/.env, which must be created from its local template.
macOS notarization credentials are private Desktop build settings. Create the ignored local file before packaging for macOS:
Copy-Item apps/desktop/.env.local.example apps/desktop/.env.localCopy-Item apps/mobile/.env.example apps/mobile/.envWhen Android Emulator connects to an API running on the Windows host, set APP_SERVER_ENDPOINT=http://10.0.2.2:4033. Use http://localhost:4033 for an iOS simulator, or the host's LAN address for a physical device. Client env files are bundled into applications, so never place server secrets in them.
Stop the stack with:
docker compose downTo also remove local database, Redis, and release volumes:
docker compose down --volumesEach Node.js project has its own pnpm lockfile so installing one application does not run lifecycle scripts from another service. Enable pnpm once, then install only the application you need from the repository root:
corepack enable
pnpm install:desktopRun the desktop app on Windows:
pnpm dev:desktopRun the Android app with Metro in a separate terminal:
pnpm install:mobile
pnpm --dir apps/mobile start
pnpm dev:mobileRun the web clients locally:
pnpm install:site
pnpm install:admin
pnpm dev:site
pnpm dev:adminThe monorepo master branch contains subtree merge commits for every former repository. Additional historical branches and tags are namespaced under legacy/<repository>/....
git branch --list "legacy/*"
git tag --list "legacy/*"
git log --all --graph --onelineProject definition and work history are maintained in docs/project.md and docs/tasks.md.