|
1 | 1 | <p align="center"> |
2 | | - <img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" /> |
3 | | - <img src="https://img.shields.io/badge/go-1.25+-00ADD8?style=flat-square&logo=go" /> |
4 | | - <img src="https://img.shields.io/badge/bun-1.2+-fbf0df?style=flat-square&logo=bun" /> |
5 | | - <img src="https://img.shields.io/badge/PostgreSQL-16-4169E1?style=flat-square&logo=postgresql" /> |
| 2 | + <img src="docs/screenshots/dashboard.png" alt="Waitless Dashboard" width="720" /> |
6 | 3 | </p> |
7 | 4 |
|
8 | 5 | <h1 align="center">⚡ Waitless</h1> |
9 | 6 |
|
10 | 7 | <p align="center"> |
11 | | - Open-source waitlist platform — self-hosted, your own SMTP, no lock-in. |
| 8 | + <strong>Open-source waitlist & launch platform — self-hosted, your own SMTP, zero lock-in.</strong> |
| 9 | +</p> |
| 10 | + |
| 11 | +<p align="center"> |
| 12 | + <a href="#-quick-start"><img src="https://img.shields.io/badge/get_started-→-6366f1?style=for-the-badge" /></a> |
| 13 | + <a href="#-features"><img src="https://img.shields.io/badge/features-→-22c55e?style=for-the-badge" /></a> |
| 14 | + <a href="https://github.com/waitlss/waitless/releases"><img src="https://img.shields.io/badge/download-latest-f59e0b?style=for-the-badge" /></a> |
| 15 | +</p> |
| 16 | + |
| 17 | +<p align="center"> |
| 18 | + <img src="https://img.shields.io/badge/go-1.25+-00ADD8?style=flat-square&logo=go&logoColor=white" alt="Go" /> |
| 19 | + <img src="https://img.shields.io/badge/react-19-61DAFB?style=flat-square&logo=react&logoColor=black" alt="React" /> |
| 20 | + <img src="https://img.shields.io/badge/PostgreSQL-16+-4169E1?style=flat-square&logo=postgresql&logoColor=white" alt="PostgreSQL" /> |
| 21 | + <img src="https://img.shields.io/badge/docker-ready-2496ED?style=flat-square&logo=docker&logoColor=white" alt="Docker" /> |
| 22 | + <img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License" /> |
| 23 | + <img src="https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square" alt="PRs Welcome" /> |
12 | 24 | </p> |
13 | 25 |
|
14 | 26 | --- |
15 | 27 |
|
16 | | -## Features |
| 28 | +Waitless lets you launch beautiful waitlist pages, collect signups, and manage subscribers — all from a single self-hosted binary. No third-party email lock-in, no monthly fees, no limits. |
| 29 | + |
| 30 | +## ✨ Features |
| 31 | + |
| 32 | +<table> |
| 33 | +<tr> |
| 34 | +<td width="50%"> |
| 35 | + |
| 36 | +### 🚀 Launch |
| 37 | +- **Public waitlist pages** — branded `/w/:slug` pages, ready to share |
| 38 | +- **Embeddable widget** — drop a `<script>` tag into any website |
| 39 | +- **Referral system** — unique codes for viral growth |
| 40 | +- **Coupon engine** — reward early adopters |
| 41 | + |
| 42 | +</td> |
| 43 | +<td width="50%"> |
| 44 | + |
| 45 | +### 📊 Manage |
| 46 | +- **Analytics dashboard** — signup trends, growth metrics, charts |
| 47 | +- **Subscriber management** — search, filter, sort, bulk actions |
| 48 | +- **CSV import/export** — migrate data in and out freely |
| 49 | +- **Multi-project** — unlimited waitlists from one install |
| 50 | + |
| 51 | +</td> |
| 52 | +</tr> |
| 53 | +<tr> |
| 54 | +<td width="50%"> |
| 55 | + |
| 56 | +### 📧 Email |
| 57 | +- **OAuth email** — Gmail & Zoho Mail (OAuth2, no app passwords) |
| 58 | +- **Any SMTP** — Mailgun, SES, SendGrid, Postmark, self-hosted |
| 59 | +- **Professional templates** — beautiful HTML welcome emails |
| 60 | +- **Custom from name** — send as your brand |
17 | 61 |
|
18 | | -- 🔐 **Your own SMTP** — Gmail, Mailgun, SES, or any SMTP server |
19 | | -- 🏢 **Multi-tenant** — create unlimited waitlist projects |
20 | | -- 👥 **Access control** — admin and user roles |
21 | | -- 📊 **Analytics** — signup trends and platform-wide metrics |
22 | | -- 📋 **Subscriber viewer** — search, filter, sort, bulk actions, CSV export |
23 | | -- 🔌 **REST API** — API key authentication for programmatic access |
24 | | -- 🧩 **Embeddable widget** — drop a form into any website |
25 | | -- 🚀 **Single binary** — Go + embedded frontend, Docker-ready |
26 | | -- 🌐 **Public pages** — beautiful, branded `/w/:slug` landing pages |
| 62 | +</td> |
| 63 | +<td width="50%"> |
27 | 64 |
|
28 | | -## Quick Start |
| 65 | +### 🔐 Platform |
| 66 | +- **REST API** — full API with key-based auth for integrations |
| 67 | +- **Webhooks** — real-time event push to your backend |
| 68 | +- **Telegram notifications** — get alerted on new signups |
| 69 | +- **Admin panel** — manage users, projects, platform-wide |
| 70 | + |
| 71 | +</td> |
| 72 | +</tr> |
| 73 | +</table> |
| 74 | + |
| 75 | +## 📸 Screenshots |
| 76 | + |
| 77 | +<p align="center"> |
| 78 | + <img src="docs/screenshots/dashboard.png" alt="Analytics Dashboard" width="32%" /> |
| 79 | + <img src="docs/screenshots/subscribers.png" alt="Subscriber Management" width="32%" /> |
| 80 | + <img src="docs/screenshots/widget.png" alt="Public Waitlist Page" width="32%" /> |
| 81 | +</p> |
| 82 | +<p align="center"> |
| 83 | + <em>Dashboard Analytics · Subscriber Management · Public Waitlist Page</em> |
| 84 | +</p> |
| 85 | + |
| 86 | +## 🚀 Quick Start |
29 | 87 |
|
30 | 88 | ### Docker (Recommended) |
31 | 89 |
|
32 | 90 | ```bash |
33 | | -git clone https://github.com/waitless/waitless |
| 91 | +git clone https://github.com/waitlss/waitless |
34 | 92 | cd waitless |
35 | 93 | docker compose -f docker/docker-compose.yml up -d |
36 | 94 | ``` |
37 | 95 |
|
38 | | -Visit [http://localhost:8080](http://localhost:8080) — the first account you create becomes the platform admin. |
| 96 | +Visit **http://localhost:8080** — the first account becomes the admin. |
39 | 97 |
|
40 | 98 | ### From Source |
41 | 99 |
|
42 | | -**Requirements:** Go 1.25+, Bun 1.2+, PostgreSQL 16+ |
43 | | - |
44 | 100 | ```bash |
45 | 101 | # Clone |
46 | | -git clone https://github.com/waitless/waitless |
47 | | -cd waitless |
| 102 | +git clone https://github.com/waitlss/waitless && cd waitless |
48 | 103 |
|
49 | 104 | # Configure |
50 | | -cp .env.example .env |
51 | | -# Edit .env with your database settings |
| 105 | +cp .env.example .env # Edit with your database settings |
52 | 106 |
|
53 | | -# Build & run |
| 107 | +# Build & run (single binary!) |
54 | 108 | make build |
55 | 109 | ./waitless |
56 | 110 | ``` |
57 | 111 |
|
58 | | -### Development |
| 112 | +> **Requirements:** Go 1.25+, Bun 1.2+, PostgreSQL 16+ |
59 | 113 |
|
60 | | -```bash |
61 | | -# Terminal 1: backend |
62 | | -make dev-backend |
| 114 | +### Development Mode |
63 | 115 |
|
64 | | -# Terminal 2: frontend (http://localhost:3000 → proxies /api to :8080) |
65 | | -make dev-frontend |
| 116 | +```bash |
| 117 | +make dev-backend # Terminal 1: Go server with hot reload |
| 118 | +make dev-frontend # Terminal 2: Vite dev server → proxies to :8080 |
66 | 119 | ``` |
67 | 120 |
|
68 | | -## Environment Variables |
| 121 | +## ⚙️ Configuration |
69 | 122 |
|
70 | | -See `.env.example` for all configuration options. |
| 123 | +### Environment Variables |
71 | 124 |
|
72 | 125 | | Variable | Description | Default | |
73 | 126 | |---|---|---| |
74 | 127 | | `DATABASE_URL` | PostgreSQL connection string | — | |
75 | | -| `DB_HOST` | Database host | `localhost` | |
76 | | -| `DB_PORT` | Database port | `5432` | |
77 | | -| `DB_USER` | Database user | — | |
78 | | -| `DB_PASSWORD` | Database password | — | |
79 | | -| `DB_NAME` | Database name | — | |
80 | 128 | | `PORT` | Server port | `8080` | |
| 129 | +| `BASE_URL` | Public URL (for OAuth callbacks) | `http://localhost:8080` | |
| 130 | +| `ENCRYPTION_KEY` | 32-byte key for encrypting tokens at rest | auto-generated | |
81 | 131 |
|
82 | | -## SMTP Configuration |
| 132 | +### Email Providers |
83 | 133 |
|
84 | | -Each project can configure its own SMTP server from the dashboard. Common providers: |
| 134 | +Each project configures its own email from the dashboard. |
85 | 135 |
|
86 | | -| Provider | Host | Port | |
| 136 | +| Provider | Type | Setup | |
87 | 137 | |---|---|---| |
88 | | -| Gmail | `smtp.gmail.com` | 587 | |
89 | | -| Mailgun | `smtp.mailgun.org` | 587 | |
90 | | -| SendGrid | `smtp.sendgrid.net` | 587 | |
91 | | -| Amazon SES | `email-smtp.us-east-1.amazonaws.com` | 587 | |
92 | | -| Self-hosted | your own | any | |
| 138 | +| **Gmail** | OAuth2 | One-click connect with Google account | |
| 139 | +| **Zoho Mail** | OAuth2 | One-click connect (supports .in/.com/.eu) | |
| 140 | +| **Mailgun** | SMTP | `smtp.mailgun.org:587` | |
| 141 | +| **SendGrid** | SMTP | `smtp.sendgrid.net:587` | |
| 142 | +| **Amazon SES** | SMTP | `email-smtp.{region}.amazonaws.com:587` | |
| 143 | +| **Postmark** | SMTP | `smtp.postmarkapp.com:587` | |
| 144 | +| **Any SMTP** | SMTP | Your own host & port | |
93 | 145 |
|
94 | | -## REST API |
| 146 | +### OAuth2 Email (Optional) |
95 | 147 |
|
96 | | -All API endpoints require a Bearer token or `X-API-Key` header. |
| 148 | +```bash |
| 149 | +# Gmail OAuth |
| 150 | +GOOGLE_CLIENT_ID=your-google-client-id |
| 151 | +GOOGLE_CLIENT_SECRET=your-google-client-secret |
| 152 | + |
| 153 | +# Zoho OAuth |
| 154 | +ZOHO_CLIENT_ID=your-zoho-client-id |
| 155 | +ZOHO_CLIENT_SECRET=your-zoho-client-secret |
| 156 | +ZOHO_DOMAIN=zoho.in # or zoho.com, zoho.eu |
| 157 | +``` |
| 158 | + |
| 159 | +## 🔌 REST API |
| 160 | + |
| 161 | +All API endpoints use Bearer token or `X-API-Key` authentication. |
97 | 162 |
|
98 | 163 | ```bash |
99 | 164 | # List subscribers |
100 | 165 | curl -H "X-API-Key: wl_your_key" \ |
101 | | - https://your-domain.com/api/v1/projects/:projectId/subscribers |
| 166 | + https://your-domain.com/api/v1/projects/:id/subscribers |
102 | 167 |
|
103 | 168 | # Add subscriber |
104 | 169 | curl -X POST -H "X-API-Key: wl_your_key" \ |
105 | 170 | -H "Content-Type: application/json" \ |
106 | 171 | -d '{"email":"user@example.com","name":"User"}' \ |
107 | | - https://your-domain.com/api/v1/projects/:projectId/subscribers |
| 172 | + https://your-domain.com/api/v1/projects/:id/subscribers |
108 | 173 | ``` |
109 | 174 |
|
110 | | -## Architecture |
| 175 | +> 📖 **Full API docs:** [docs/rest-api-v1.md](docs/rest-api-v1.md) · [docs/public-api.md](docs/public-api.md) |
| 176 | +
|
| 177 | +## 🧩 Embeddable Widget |
111 | 178 |
|
| 179 | +Drop this into any website to show a waitlist signup form: |
| 180 | + |
| 181 | +```html |
| 182 | +<div id="waitless-widget"></div> |
| 183 | +<script src="https://your-domain.com/widget.js" |
| 184 | + data-project="your-project-slug"> |
| 185 | +</script> |
112 | 186 | ``` |
113 | | -Single binary: ./waitless |
114 | | -├── Go HTTP server (Chi router) |
115 | | -│ ├── /api/auth/* Auth (register, login, logout) |
116 | | -│ ├── /api/dashboard/* Dashboard API (authenticated) |
117 | | -│ ├── /api/admin/* Admin API (admin role required) |
118 | | -│ ├── /api/v1/* REST API (API key auth) |
119 | | -│ └── /api/public/* Public waitlist API |
120 | | -└── Embedded TanStack Start frontend |
121 | | - ├── / (landing page) |
122 | | - ├── /dashboard (management UI) |
123 | | - └── /w/:slug (public waitlist pages) |
| 187 | + |
| 188 | +## 🏗️ Architecture |
| 189 | + |
124 | 190 | ``` |
| 191 | +./waitless (single binary, ~17MB) |
| 192 | +├── Go HTTP server (Chi) |
| 193 | +│ ├── /api/auth/* → Auth (register, login, sessions) |
| 194 | +│ ├── /api/dashboard/* → Dashboard API (authenticated) |
| 195 | +│ ├── /api/admin/* → Admin API (role-gated) |
| 196 | +│ ├── /api/v1/* → REST API (API key auth) |
| 197 | +│ ├── /api/public/* → Public waitlist API |
| 198 | +│ └── /api/oauth/* → OAuth2 callbacks (Gmail, Zoho) |
| 199 | +└── Embedded React frontend (TanStack Router) |
| 200 | + ├── / → Landing page |
| 201 | + ├── /dashboard → Management UI |
| 202 | + ├── /docs → API documentation |
| 203 | + └── /w/:slug → Public waitlist pages |
| 204 | +``` |
| 205 | + |
| 206 | +**Tech stack:** Go · React 19 · TanStack Router · PostgreSQL · GORM · Recharts |
| 207 | + |
| 208 | +## 🚢 Deploy |
125 | 209 |
|
126 | | -## Deploying to VPS |
| 210 | +### VPS / Bare Metal |
127 | 211 |
|
128 | 212 | ```bash |
129 | | -# Build binary on your machine |
130 | 213 | make build |
| 214 | +scp waitless .env user@server:/opt/waitless/ |
131 | 215 |
|
132 | | -# Copy to server |
133 | | -scp waitless user@server:/opt/waitless/ |
134 | | -scp .env user@server:/opt/waitless/ |
| 216 | +# On server |
| 217 | +cd /opt/waitless && ./waitless |
| 218 | +``` |
135 | 219 |
|
136 | | -# On server — run with systemd or screen |
137 | | -./waitless |
| 220 | +### Docker |
| 221 | + |
| 222 | +```bash |
| 223 | +docker compose -f docker/docker-compose.yml up -d |
| 224 | +``` |
| 225 | + |
| 226 | +### Systemd Service |
| 227 | + |
| 228 | +```ini |
| 229 | +[Unit] |
| 230 | +Description=Waitless |
| 231 | +After=postgresql.service |
| 232 | + |
| 233 | +[Service] |
| 234 | +WorkingDirectory=/opt/waitless |
| 235 | +ExecStart=/opt/waitless/waitless |
| 236 | +Restart=always |
| 237 | + |
| 238 | +[Install] |
| 239 | +WantedBy=multi-user.target |
138 | 240 | ``` |
139 | 241 |
|
140 | | -## Contributing |
| 242 | +## 🤝 Contributing |
141 | 243 |
|
142 | | -Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md). |
| 244 | +Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md). |
143 | 245 |
|
144 | | -1. Fork the repository |
145 | | -2. Create a feature branch (`git checkout -b feature/amazing-feature`) |
146 | | -3. Commit your changes |
147 | | -4. Push and open a Pull Request |
| 246 | +1. Fork the repo |
| 247 | +2. Create a branch (`git checkout -b feature/amazing`) |
| 248 | +3. Commit & push |
| 249 | +4. Open a Pull Request |
148 | 250 |
|
149 | | -## License |
| 251 | +## 📜 License |
150 | 252 |
|
151 | 253 | MIT — see [LICENSE](LICENSE) |
| 254 | + |
| 255 | +--- |
| 256 | + |
| 257 | +<p align="center"> |
| 258 | + <sub>Built with ❤️ for the open-source community</sub> |
| 259 | +</p> |
0 commit comments