Lightweight
Task Server

Free & open source forever. No subscriptions. No per-seat pricing. No limits.

A real-time Kanban board you can deploy in seconds. One binary, one command. Built with Go and Vite for a 20 MB memory footprint.

Try it — drag cards between columns

Backlog
Investigate ES shard rebalancing after disk watermark breach
INFRA
Mobile responsive layout for board and list views
FEATURE
To Do
Deploy polygon streamer v2
FIX
Fix webhook retry backoff
BUG
In Progress
Fix SSE heartbeat timeout on slow connections
BUG
Add dark/light theme toggle
FEATURE
Add FRED series to macro dashboard
FEATURE
Done
JWT token refresh race condition
FIX
Go
Vite
Docker
PostgreSQL
SQLite
GitHub

Epic swimlanes

Group cards by epic to see progress across workstreams at a glance. Collapse lanes, drag between them, track counts per column.

Backlog 3
To Do 3
In Progress 3
Done 3
LWTS-27 Infrastructure Hardening 7 cards
Transcript parser batch mode for quarterly bulk import
FIX
Add dark/light theme toggle
FEATURE
Investigate ES shard rebalancing after disk watermark breach
INFRA
Database connection pool exhaustion under sustained load
BUG
Implement board-level permissions and access control
INFRA
Add FRED macro series to the economic dashboard
FEATURE
Migrate user avatars to S3-compatible object storage
INFRA
LWTS-28 Frontend Polish 4 cards
Mobile responsive layout for board and list views
FEATURE
Implement live markdown preview in card descriptions
FEATURE
Fix card drag ghost image rendering on Firefox
BUG
Redesign card detail modal with two-column layout
FEATURE

List view & filters

Switch to list view for a dense overview. Filter by assignee, priority, tag, or search across all cards.

Priority: High2
Assignee
Tag
Key Title Status Priority Assignee Points Due
LWTS-4 Fix SSE heartbeat timeout on slow connections In Progress Highest
5 Apr 1
LWTS-26 Fix webhook retry backoff To Do High
3 Today
LWTS-2 Investigate ES shard rebalancing Backlog High
3 Aug 20
LWTS-9 JWT token refresh race condition Done High
2 Mar 28

Everything you need. Nothing you don't.

No bloat, no electron, no SaaS lock-in. Just a fast, self-hosted kanban board that runs anywhere.

Real-Time Collaboration

Server-Sent Events push card updates, comments, and presence to every connected client instantly. No polling, no WebSocket complexity.

Drag & Drop

Move cards between columns with native HTML5 drag-and-drop. Reorder within columns. Optimistic UI with automatic rollback on conflict.

Role-Based Access

Four roles — Owner, Admin, Member, Viewer — with enforced permissions. Invite teammates, manage roles, control who can edit.

Secure by Default

JWT auth with token rotation. Bcrypt password hashing. Rate limiting. CORS. Security headers. Parameterized queries. No shortcuts.

Webhooks

Subscribe to card and comment events per-board. HMAC-SHA256 signed payloads, automatic retries with exponential backoff, delivery history.

Fully Responsive

Desktop columns, tablet scroll, mobile single-column with tabs. Touch-friendly 44px+ targets. Dark and light themes with accent colors.

Customizable

Multiple boards with custom project keys. Configurable columns. Dark/light themes. Accent colors. Density and font size options. Make it yours.

Comments & Activity

Threaded comments on every card with real-time updates. Track reporters, assignees, due dates, story points, priorities, and tags.

REST API

Full CRUD API for boards, cards, comments, webhooks, and users. JWT auth. Search. Presence. Stream events. Build on top of it.

PostgreSQL or SQLite

Use PostgreSQL in production with connection pooling. Or SQLite for single-user or development. Auto-detected from the connection URL.

Zero Frontend Build

Vanilla ES6+ JavaScript, embedded into the Go binary at compile time. No npm, no webpack, no build step. Edit and reload.

Accessible

WCAG 2.1 AA. Keyboard navigation with arrow keys. ARIA roles and labels. Screen reader live regions. Reduced motion support.

Up and running in 60 seconds

One command. That's it.

docker-compose.yml
version: "3.8"

services:
  lwts:
    image: ghcr.io/oceanplexian/lwts:latest
    ports:
      - "8080:8080"
    environment:
      DB_URL: postgres://lwts:lwts@db:5432/lwts
      JWT_SECRET: change-me-in-production
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: lwts
      POSTGRES_PASSWORD: lwts
      POSTGRES_DB: lwts
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
Terminal
$ docker compose up -d
# Open http://localhost:8080
Terminal
# With SQLite (simplest)
$ docker run -p 8080:8080 \
    -e DB_URL=sqlite:///data/lwts.db \
    -e JWT_SECRET=change-me \
    -v lwts-data:/data \
    ghcr.io/oceanplexian/lwts:latest

# With external PostgreSQL
$ docker run -p 8080:8080 \
    -e DB_URL=postgres://user:pass@host:5432/lwts \
    -e JWT_SECRET=change-me \
    ghcr.io/oceanplexian/lwts:latest
Terminal
# Download the latest release
$ curl -sL https://github.com/oceanplexian/lwts/releases/latest/download/lwts-$(uname -s)-$(uname -m) -o lwts
$ chmod +x lwts

# Run with SQLite (zero setup)
$ DB_URL=sqlite://lwts.db JWT_SECRET=change-me ./lwts

# Or with PostgreSQL
$ DB_URL=postgres://user:pass@localhost:5432/lwts JWT_SECRET=change-me ./lwts

Developer-friendly API

Full REST API with JWT auth. Automate your workflow, build integrations, or drive your board from CI/CD.

Create a card
$ curl -X POST https://lwts.example.com/api/v1/boards/1/cards \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Fix login timeout",
      "priority": "high",
      "tag": "bug",
      "column": "todo",
      "assignee_id": "usr_abc123"
    }'
Listen to real-time events
$ curl -N https://lwts.example.com/api/v1/boards/1/stream?token=$TOKEN

event: card_created
data: {"id":"...","title":"Fix login timeout","column":"todo","key":"LWTS-42"}

event: card_moved
data: {"id":"...","column":"in-progress","position":0,"version":2}

event: comment_added
data: {"id":"...","card_id":"...","body":"On it.","user_id":"..."}

event: user_joined
data: {"user_id":"...","username":"sam","initials":"SR"}

Endpoints

POST/api/auth/register
POST/api/auth/login
POST/api/auth/refresh
GET/api/auth/me
GET/api/v1/boards
POST/api/v1/boards
GET/api/v1/boards/{id}/cards
POST/api/v1/boards/{id}/cards
POST/api/v1/cards/{id}/move
GET/api/v1/cards/{id}/comments
POST/api/v1/cards/{id}/comments
GET/api/v1/boards/{id}/stream
GET/api/v1/boards/{id}/presence
POST/api/v1/boards/{id}/webhooks
GET/api/v1/search
GET/api/v1/users
POST/api/v1/keys
GET/api/v1/export
POST/api/v1/import/jira
POST/api/v1/import/trello
GET/healthz

Webhooks that just work

Subscribe to events per-board. Every delivery is HMAC-SHA256 signed so you can verify authenticity. Failed deliveries retry with exponential backoff. Full delivery history in the UI.

card.created card.updated card.moved card.completed card.deleted comment.added *
Webhook payload
// Headers
X-LWTS-Event: card.completed
X-LWTS-Signature: sha256=a1b2c3...
X-LWTS-Delivery: 550e8400-e29b-41d4-a716-446655440000

// Body
{
  "id": "550e8400-...",
  "event": "card.completed",
  "timestamp": "2025-01-15T10:30:00Z",
  "board": {
    "id": "board_123",
    "name": "Sprint 42"
  },
  "data": {
    "card": {
      "key": "LWTS-4",
      "title": "Fix SSE heartbeat timeout",
      "column": "done"
    }
  }
}

Architecture

Simple, auditable, no magic.

Frontend
  • Vanilla ES6+ — no framework
  • Embedded in binary via go:embed
  • Native HTML5 drag-and-drop
  • EventSource SSE client
  • CSS custom properties theming
  • ~25K lines, 10+ modules
Backend
  • Go net/http — no router lib
  • Middleware chain (8 layers)
  • Repository pattern + DB abstraction
  • Structured logging (slog)
  • Graceful shutdown (30s drain)
  • ~9K lines, 30+ files
Infrastructure
  • Single static binary (<30MB image)
  • Multi-arch: amd64 + arm64
  • Distroless container (non-root)
  • PostgreSQL 16 or SQLite 3
  • Health + readiness probes
  • 12-factor env configuration

About the Author

Andreas Echavez

Andreas Echavez

Senior Software Engineer at Netflix

Systems and software engineer with a background at industry leaders in infrastructure, social media, and technology. Focused on distributed systems, cloud networking, AI, Kubernetes, and building tools that engineers actually want to use.

Go Python Kubernetes AWS Distributed Systems
Connect on LinkedIn

/

Add a description...
Add a subtask...
Add a comment...
Status
Type
Priority
Reporter
Assignee
Points
Due Date