twitter-client

A small, quiet Twitter/X client for reading and writing tweets without the noise.

What it does

  • Read your home timeline
  • Post tweets and replies
  • Like tweets
  • View mentions
  • Minimal, X-inspired web UI

Stack

  • Backend: Kotlin + Ktor 2.3, talking to the X API v2 over OAuth 1.0a
  • Cache: Redis (Lettuce) for timeline and user ID caching
  • Frontend: React 19 + TypeScript + Vite
  • Runtime: Docker Compose with separate backend, frontend, and Redis services

Quick start

1. Configure environment

Copy .env.example to .env and fill in your values:

cp .env.example .env

Required variables:

Variable Description
APP_PASSWORD Single password used to log into the web UI
APP_SECRET Long random string used to sign the session cookie
APP_CONSUMER_KEY Your X API app consumer key
APP_CONSUMER_KEY_SECRET Your X API app consumer secret
APP_ACCESS_TOKEN Your X API user access token
APP_ACCESS_TOKEN_SECRET Your X API user access token secret

2. Run with Docker Compose

Create the external network once:

docker network create twitter-network

Then start everything:

# If you use Doppler and Taskfile:
task docker-up

# Otherwise, with env vars exported:
docker compose up -d

The app will be available at http://localhost:5173.

3. Run locally for development

Backend:

cd backend
./gradlew run

Runs on http://localhost:8080. Requires REDIS_URL and all X API env vars to be set.

Frontend:

cd frontend
cp .env.example .env.local   # set VITE_API_URL=http://localhost:8080
npm install
npm run dev

Runs on http://localhost:5173.

Useful commands

# Backend
cd backend && ./gradlew run          # local dev server
cd backend && ./gradlew buildFatJar # build Docker artifact

# Frontend
cd frontend && npm install
cd frontend && npm run dev           # dev server with HMR
cd frontend && npm run build         # production build
cd frontend && npm run lint          # ESLint

# Docker / full stack
task docker-build                    # build images
task docker-up                       # start services
task docker-down                     # stop services
task docker-rebuild                  # rebuild and restart

Notes

  • The backend caches the home timeline in Redis for 10 minutes. Posting a tweet clears the cache.
  • Replies are limited by X itself: you can only reply to posts that mention or quote your account through the API.
  • The Notifications tab is a placeholder; the X API does not expose notifications.
  • Session auth is cookie-based and signed with APP_SECRET.

License

See LICENSE.

S
Description
Small Twitter (now X) client to read and write tweets cleanly and quietly
Readme MIT
430 KiB
Languages
Kotlin 47%
TypeScript 32.2%
CSS 13.1%
HCL 6.4%
HTML 0.5%
Other 0.8%