A minimalistic, shareable kanban board for organizing your tasks.
- 📋 Local-first - Works offline, data stored in your browser
- 🔗 Shareable boards - Share a link for real-time collaboration
- 📁 Import/Export - Save and load boards as JSON files
- 🔒 Secure - Google OAuth, rate limiting, input validation
- ⏰ Auto-expiring - Shared boards expire after 7 days of inactivity
- 🎨 Minimalist UI - Clean, distraction-free interface
- Node.js 18+
- PostgreSQL 14+
- Google OAuth credentials (for sharing feature)
-
Clone the repository
git clone https://github.com/saadih/tekban.git cd tekban -
Set up the server
cd server npm install cp .env.example .env # Edit .env with your database and OAuth credentials npm run db:push npm run dev
-
Set up the client (in another terminal)
cd client npm install npm run dev
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/tekban
# Session
SESSION_SECRET=your-random-secret-here
# Google OAuth
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3000/auth/google/callback
# URLs
FRONTEND_URL=http://localhost:5173
PORT=3000
NODE_ENV=developmentSee DEPLOYMENT.md for a complete guide on deploying to a VPS with:
- PM2 process manager
- Nginx reverse proxy
- PostgreSQL setup
- Free SSL with Let's Encrypt
# Build client
cd client
npm run build
# Server runs directly with tsx (no build needed)
cd ../server
npm run db:push- Set
NODE_ENV=productionfor secure cookies - Use HTTPS in production (required for OAuth and secure cookies)
- Set a strong
SESSION_SECRET(32+ random characters)
tekban/
├── client/ # React + TypeScript + Tailwind
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── hooks/ # Custom hooks (useBoard)
│ │ ├── pages/ # Route pages
│ │ └── services/ # API client
│ └── public/ # Static assets
│
└── server/ # Express + TypeScript + Drizzle
└── src/
├── auth/ # Passport.js + Google OAuth
├── db/ # Drizzle schema + connection
├── jobs/ # Background jobs (cleanup)
├── middleware/ # Validation, rate limiting
├── routes/ # API endpoints
└── sse/ # Server-Sent Events manager
- Helmet - Security headers (CSP, HSTS, etc.)
- Rate limiting - 100 req/15min general, 10 boards/hour creation
- Input validation - Title/content length limits
- PostgreSQL sessions - Persistent, server-side sessions
- CORS - Configured for frontend origin only
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /boards/:id |
- | Get board by ID |
| GET | /boards/:id/events |
- | SSE updates stream |
| POST | /boards |
✓ | Create new shared board |
| PATCH | /boards/:id |
- | Update board |
| DELETE | /boards/:id |
✓ | Delete board (owner only) |
| GET | /boards/mine |
✓ | Get current user's board |
| GET | /auth/google |
- | Start OAuth flow |
| GET | /auth/me |
- | Get current user |
| POST | /auth/logout |
- | End session |
MIT - see LICENSE
Contributions are welcome! Please open an issue first to discuss changes.