Kuayle is currently a runnable MVP of the core issue tracker. The repository includes a Go API, PostgreSQL migrations, Redis configuration, and a SvelteKit frontend that can be run locally with Docker Compose or the Makefile commands below.
| Area | State |
|---|---|
| Core tracker | Implemented end-to-end: auth, workspaces, members/RBAC, teams, custom statuses, issues, labels, comments, history, sub-issues, issue relations, triage, templates, favorites, saved views, notifications, public sharing, uploads, and WebSocket updates. |
| Planning | Implemented: cycles with completion, burndown/velocity support, and UI; projects with status, lead/date metadata, issue lists, and a Gantt view. |
| Integrations | Implemented: workspace webhooks and GitHub App setup, repo linking, PR/branch/commit activity, auto-transitions, and webhook handling. |
| Analytics | Backend endpoints exist for overview and issue distribution; a dedicated frontend analytics page is not wired yet. |
| Dev Machines | Specification/design only in this repo today. The runtime container manager and UI flow are not wired into the app yet; see TECHNICAL.md. |
Note: this is a lightweight snapshot, not a guarantee of current feature parity. Products evolve quickly, so some details may be outdated or incomplete.
Where Kuayle is different:
| Kuayle edge | Why it matters |
|---|---|
| ✅ No paid feature gates | Every implemented feature is intended to stay free. |
| ✅ Apache 2.0 | Permissive for internal forks, embedding, and commercial use. |
| ✅ Small and hackable | Go API, raw SQL, SvelteKit UI, Docker Compose. |
| ✅ Multi-assignee by default | Linear-like workflow without single-owner assumptions. |
| 🟠 Dev Machines direction | Spec points toward issue-to-coding-environment workflows. |
| Area | Kuayle | Linear | Plane |
|---|---|---|---|
| License | ✅ Apache 2.0 | ❌ Proprietary | ✅ Open source |
| Self-hosting | ✅ First-class Docker setup | ❌ Hosted SaaS | ✅ Cloud and self-hosted |
| Paid feature gates | ✅ None intended | 🟠 Tiered | 🟠 Tiered |
| Core issues | ✅ MVP implemented | ✅ Mature | ✅ Mature |
| Multi-assignee | ✅ Built in | ❌ Not a core Linear feature | 🟠 Work-item ownership varies by model |
| Teams and workflows | ✅ Teams + custom statuses | ✅ Mature | ✅ Mature |
| Projects | ✅ Projects + Gantt view | ✅ Projects + roadmaps | ✅ Projects + layouts |
| Cycles | ✅ Cycles + burndown/velocity | ✅ Mature | ✅ Mature |
| Initiatives/modules | ❌ Not yet | ✅ Initiatives | ✅ Initiatives + modules |
| Views/public sharing | ✅ Saved views + public links | ✅ Views | ✅ Views + publish options |
| Analytics UI | 🟠 Backend endpoints only | 🟠 Tiered insights/dashboards | 🟠 Tiered dashboards/analytics |
| GitHub automation | ✅ GitHub App + auto-transitions | ✅ Mature | ✅ GitHub integration |
| Import/export | ❌ Not yet | ✅ Available | ✅ Multiple importers/export |
| Enterprise auth | ❌ No SSO/SCIM/LDAP yet | 🟠 Enterprise tier | 🟠 Paid/self-hosted tiers |
| AI/agents | 🟠 Dev Machines spec only | 🟠 Tiered Linear Agent/features | 🟠 Tiered Plane AI/MCP |
| Best fit | ✅ Hackable, no-gates Linear-style tracker | ✅ Polished hosted engineering workflow | ✅ Broader PM suite with wiki/modules |
I've been a happy Linear user for years, and it has set a very high bar for issue tracking. At the time I started this project, a few things kept bugging me: no multi-assignee on issues, no project-based Gantt, analytics behind a paywall, and per-seat pricing that adds up quickly for small teams.
With AI, building your own tool became realistic, so I did. First for myself, then for anyone who wants a similar workflow without the same cost structure.
I also looked at the open-source alternatives available at the time, and Kuayle took a different approach: every feature is free, forever. No paid tiers, no feature gates, Apache 2.0. If you find it useful, consider sponsoring the project, that's the whole model.
| Feature | Description | |
|---|---|---|
| 🏢 | Workspaces | Multi-tenant with role-based access (owner, admin, member, guest) |
| 👥 | Teams | Custom workflows, each team gets its own statuses and triage settings |
| 📋 | Issues | Priority, due dates, sub-tasks, multi-assignee, labels, comments, audit history |
| 🔄 | Cycles | Sprint planning with time-boxed iterations (upcoming, active, completed) |
| 📁 | Projects | Cross-team work grouped under a single umbrella |
| 🏷️ | Labels | Hierarchical, workspace-scoped, with soft delete |
| 👁️ | Views | Saved and shareable filtered perspectives with JSONB persistence |
| 🔔 | Notifications | Inbox with snooze, read status, and archive |
| 🔗 | Webhooks | Plug into external services and integrations |
| ⚡ | Real-time | WebSocket-powered live updates across all connected clients |
| 🖥️ | Dev Machines | Technical specification for on-demand, single-container development environments |
| 🐙 | GitHub | Link repos, auto-sync issues, webhook-based updates |
| 📊 | Analytics | Backend overview and issue distribution endpoints |
| 🔗 | Public Sharing | Token-based read-only links for issues and views |
The Dev Machines track is currently a technical specification for on-demand, single-container development environments on a VPS. The intended design is a disposable workspace with an IDE, agentic coding CLI, and a browser, accessible via auto-generated subdomains.
See
TECHNICAL.mdfor the full specification, architecture diagrams, and API reference.
You (browser)
│
├─ f8k2m9.kuayle.com → code-server (IDE + Claude Code)
├─ f8k2m9-browser.kuayle.com → Chromium (in-browser web navigation)
└─ f8k2m9-app.kuayle.com → Dev server preview
│
└── All routed through Kuayle auth — no port management needed
- Kuayle spawns a container with code-server + Claude Code CLI + Chromium + your repo
- Assigns random subdomains via wildcard DNS (
*.kuayle.com), with no per-container port management - Authenticates users and agents through Kuayle's session layer
- Tracks all activity (edits, commands, git ops, navigation) and feeds it back into project management
| Mode | Who | What happens |
|---|---|---|
| Agent-only | Kuayle assigns a task | Agent works autonomously, pushes results, machine tears down |
| Human + Agent | Developer clicks "Open Machine" | Gets a browser link to a full IDE with agentic tools, works interactively |
Machines would be configured from Kuayle's UI or via API: repo, branch, env vars, tools, and size. Configuration would resolve in order: project defaults → user preferences → spawn-time overrides.
| Size | CPU | Memory | Disk |
|---|---|---|---|
| Small | 2 cores | 4 GB | 20 GB |
| Medium | 4 cores | 8 GB | 50 GB |
| Large | 8 cores | 16 GB | 100 GB |
Here's what Kuayle runs on and what each piece does:
| Layer | Tech | Role |
|---|---|---|
| API | Go + Echo | High-performance HTTP server with middleware, routing, JWT auth |
| Database | PostgreSQL 17 | Primary data store, raw SQL via sqlx/pgx, no ORM |
| Cache & Jobs | Redis 7 | Configured in Docker/env for future cache and job usage |
| Frontend | SvelteKit + Svelte 5 | SPA with TypeScript, runes-based reactivity, static adapter |
| UI | Tailwind CSS + shadcn-svelte | Utility-first styling with accessible component primitives |
| Editor | Tiptap v3 + Yjs | Rich text with code blocks, mentions, slash commands, task lists |
| Real-time | WebSocket (nhooyr.io) | Live collaboration, presence, issue updates |
| Storage | Local FS or S3-compatible | AWS S3, Cloudflare R2, MinIO, SeaweedFS |
| Reverse Proxy | Caddy | Production HTTPS and routing |
| Dev Machines | code-server + Claude Code + Chromium | Technical specification for single-container agentic dev environments |
| Infra | Docker + Docker Compose | One-command local and production deployment |
cp .env.example .env
make docker-upApp at http://localhost:5173 · API at http://localhost:8080
cp .env.example .env
docker compose up postgres redis -d
make migrate-up && make seed
make dev| Command | What it does |
|---|---|
make dev |
Run backend + frontend |
make dev-backend |
Backend only |
make dev-frontend |
Frontend only |
make migrate-up |
Apply migrations |
make migrate-down |
Roll back migrations |
make seed |
Seed the database |
make test |
Run all tests |
make lint |
Lint everything |
make docker-up |
Start all (Docker) |
make docker-down |
Stop all (Docker) |
Kuayle is designed to be self-hosted. Everything runs in Docker, no managed services required.
- A Linux server (or any host that runs Docker)
- Docker + Docker Compose
- A domain (optional, for HTTPS)
git clone https://github.com/carbogninalberto/kuayle.git
cd kuayle
cp .env.example .envEdit .env with production values:
DATABASE_URL=postgres://kuayle:<strong-password>@postgres:5432/kuayle?sslmode=disable
REDIS_URL=redis://redis:6379
JWT_SECRET=<random-string-at-least-32-chars>
ENVIRONMENT=production
FRONTEND_URL=https://your-domain.comdocker compose up --build -dThis starts 4 containers: PostgreSQL, Redis, backend API (:8080), and frontend (:5173).
docker compose exec backend /app/server migrate up
docker compose exec backend /app/server seedPut Nginx, Caddy, or Traefik in front to handle HTTPS. Example with Caddy, pointing at the frontend container only:
your-domain.com {
reverse_proxy localhost:5173
}
The frontend container serves the app and proxies /api/* to the backend, so one public origin is enough.
By default, uploads go to the local filesystem. For production, you can use any S3-compatible storage:
STORAGE_TYPE=s3
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
S3_BUCKET=kuayle-uploads
S3_REGION=us-east-1
S3_ACCESS_KEY=your-key
S3_SECRET_KEY=your-secretWorks with AWS S3, Cloudflare R2, MinIO, SeaweedFS, and any S3-compatible provider.
Kuayle connects to GitHub via a self-configuring GitHub App. No environment variables needed — everything is set up from the UI.
- Links PRs to issues — mention
ENG-123in a branch name, PR title, or commit message - Auto-transitions — branch created → In Progress, PR opened → In Review, PR merged → Done (configurable)
- Activity feed — linked PRs, branches, and commits on every issue detail page
If your Kuayle instance is reachable from the internet (e.g. https://kuayle.yourcompany.com), setup is fully automatic:
- Go to Settings → GitHub in your workspace
- Click Set up GitHub App — redirects to GitHub with a pre-filled form
- Click Create GitHub App on GitHub
- Redirected back — credentials saved automatically, webhook URL configured
- Click Install on GitHub to grant access to your repos
- Select which repos to link — done!
Everything including the webhook URL is configured automatically. PRs, branches, and commits start appearing on issues immediately.
If your instance runs on a private network (e.g. http://192.168.1.50:5173 or behind a VPN), GitHub can't send webhooks directly. You have two options:
Option A: Webhook proxy with smee.io (simplest)
smee.io is a free webhook relay that forwards GitHub events to your private instance.
- Go to smee.io/new and copy your channel URL (e.g.
https://smee.io/abc123) - Run the proxy on your server:
npx smee-client --url https://smee.io/abc123 --target http://localhost:8080/api/github/webhook
- Set up the GitHub App from Settings → GitHub (same steps as above)
- After the app is created, go to its settings on GitHub: GitHub → Settings → Developer settings → GitHub Apps → your app → General
- Set Webhook URL to your smee channel URL (
https://smee.io/abc123) - Check Active and save
The smee client must stay running to receive events. You can run it as a systemd service:
# /etc/systemd/system/smee-kuayle.service
[Unit]
Description=Smee webhook proxy for Kuayle
After=network.target
[Service]
ExecStart=/usr/bin/npx smee-client --url https://smee.io/abc123 --target http://localhost:8080/api/github/webhook
Restart=always
User=kuayle
[Install]
WantedBy=multi-user.targetsudo systemctl enable --now smee-kuayleOption B: Reverse tunnel (no third-party relay)
Use a reverse tunnel to expose just the webhook endpoint. With cloudflared:
cloudflared tunnel --url http://localhost:8080Or with ngrok:
ngrok http 8080Then set the generated public URL as the webhook URL in your GitHub App settings (append /api/github/webhook).
Option C: Polling (no webhook needed)
If you can't expose any endpoint, the GitHub integration still works for PR/branch/commit linking — it just won't receive real-time webhook events. You can manually refresh issue activity from the UI. Auto-transitions won't fire without webhooks.
For local development, the GitHub App is created without a webhook URL (since localhost isn't reachable). To receive webhook events during development:
- Set up the GitHub App from Settings → GitHub (works on localhost)
- Start a smee proxy:
npx smee-client --url https://smee.io/your-channel --target http://localhost:8080/api/github/webhook
- Update the webhook URL in your GitHub App settings to your smee channel URL
- Events will now flow through to your local instance
kuayle/
├── BE/ # Backend (Go)
│ ├── cmd/server/ # Entrypoint (server, migrate, seed)
│ └── internal/
│ ├── config/ # Configuration
│ ├── domain/ # Domain models
│ ├── dto/ # Data transfer objects
│ ├── handler/ # HTTP handlers
│ ├── service/ # Business logic
│ ├── repository/ # Data access (raw SQL)
│ ├── middleware/ # Auth and request middleware
│ └── realtime/ # WebSocket support
├── UI/ # Frontend (SvelteKit)
│ └── src/
│ ├── routes/ # Pages
│ └── lib/
│ ├── api/ # API client
│ ├── components/ # UI components
│ ├── features/ # Feature modules
│ ├── types/ # TypeScript types
│ └── utils/ # Utilities
├── docker-compose.yml
├── Makefile
├── TECHNICAL.md # Dev Machines specification
└── .env.example
PRs welcome. Fork it, branch it, fix it, ship it.
- Fork the repo
- Create your branch (
git checkout -b feature/cool-thing) - Commit your changes
- Push and open a PR
Apache 2.0, see LICENSE.
Alberto Carbognin, @carbogninalberto
View the full contributor graph on GitHub: contributors.
🤖 Heads up: This codebase was built through AI-assisted development under my supervision, ideas, and direction. It works, but expect some rough edges that still need smoothing.
