Open-source customer feedback platform — collect feature requests, roadmaps, changelogs, and an embeddable feedback widget. Built as a pnpm + Turborepo monorepo using Effect, Drizzle, and Astro.
Licensed under the GNU AGPL-3.0.
apps/
server/ Effect-based HTTP API (rolldown build, tsx dev)
web/ Astro dashboard (React + Solid islands, Cloudflare deploy)
public-feature-board/ Public feature board UI package (TanStack Router/DB)
packages/
auth/ better-auth integration
db/ Drizzle schemas + migrations (PostgreSQL)
db-migrator/ Migration runner
domain/ Core domain: users, workspaces, boards, posts, comments,
upvotes, reactions, changelogs, tags, billing, S3, RPC router
feedback-widget/ SolidJS embeddable widget
post-ui/ Post rendering components
id/ ID generation
permissions/ Permission policies
rpc-client/ Typed RPC client
sdk/ Embeddable feedback widget SDK (UMD + ESM)
transactional/ Transactional email templates
ui/ Shared UI primitives (shadcn-style)
utils/ Shared utilities
web-shared/ Shared web code
integrations/
core/ Delivery pipeline, provider registry, event recording
slack/ discord/ Provider adapters (Slack, Discord, GitHub, webhook)
github/ webhook/
- Runtime/Server: Node 26+, Effect v4,
@effect/platform-node,@effect/sql-pg - Database: PostgreSQL via Drizzle ORM (
drizzle-kitfor migrations) - Auth: better-auth (with Polar billing integration)
- Web: Astro 7, React 19 + Solid.js islands, TanStack Router/DB/Query/Form, Tailwind v4
- SDK: Framework-agnostic Vite-built widget (Floating UI positioning)
- Tooling: pnpm 11, Turborepo, oxlint + oxfmt, Vitest, Playwright, TypeScript 6
- Infra/Deploy: Docker, Cloudflare (dashboard via Wrangler)
- Node.js
^26.4.0 - pnpm
^11.0.3 - Docker (for local Postgres / MinIO / SMTP) — optional but recommended
-
Install dependencies:
pnpm install
-
Copy the environment file and fill in values:
cp .env.example .env
Required configuration includes
DATABASE_URL,AUTH_ENCRYPTION_KEY,APP_URL,API_URL,APP_ROOT_DOMAIN, SMTP settings, and media upload (S3-compatible) settings. See.env.examplefor details. -
Start local infrastructure (Postgres / MinIO / mail) and run migrations + seed:
pnpm db:start pnpm db:migrate pnpm db:seed
-
Run the dev servers (API + web in parallel via Turbo):
pnpm dev
Or run individually:
pnpm dev:server # API on http://localhost:3000 pnpm dev:web # Dashboard on http://localhost:3001
| Script | Description |
|---|---|
pnpm dev |
Run all dev tasks across the workspace |
pnpm dev:server / pnpm dev:web / pnpm dev:native |
Run a single app |
pnpm build |
Build all packages and apps |
pnpm check-types |
Typecheck the whole workspace |
pnpm db:push |
Push schema to the database |
pnpm db:generate |
Generate SQL migrations from schema changes |
pnpm db:migrate |
Run pending migrations |
pnpm db:seed |
Seed the database with sample data |
pnpm db:studio |
Open Drizzle Studio |
pnpm db:nuke |
Drop and recreate the database |
pnpm db:start / pnpm db:stop / pnpm db:down |
Start/stop/teardown local DB container |
pnpm format |
Format with Biome |
pnpm check / pnpm fix |
Ultracite lint check / autofix |
The embeddable SDK lives in packages/sdk and ships ESM + UMD builds. See packages/sdk/README.md for installation and usage.
Billing uses Polar. Set POLAR_MODE, POLAR_ACCESS_TOKEN, and POLAR_WEBHOOK_SECRET to enable checkout, subscription synchronization, and the customer portal.
Configure the Polar webhook URL as:
https://<API_URL>/api/auth/polar/webhooks
Each recurring product must include metadata that identifies its entitlement plan and billing variant:
{ "plan": "starter", "variant": "monthly" }Supported plan values are starter and professional; supported variants are monthly and yearly. The variant must match the product's recurring interval. Products without valid metadata, archived products, and one-time products are rejected by the checkout API.
After adding the webhook to an existing Polar organization, resend product.created or product.updated events for the current products so the local product catalog is populated before enabling billing.
Production deployments use the Docker images referenced in docker-compose.yml (ghcr.io/g3root/feeblo-server and ghcr.io/g3root/feeblo-web). Images are published automatically to GHCR on pushes to main and version tags. The dashboard can alternatively be deployed to Cloudflare using the Wrangler configuration in apps/web/wrangler.jsonc.
The Compose database uses the pgvector-enabled PostgreSQL image. Post embeddings default to OpenAI text-embedding-3-small at 1536 dimensions. Set EMBEDDING_API_KEY to enable embeddings; OpenAI-compatible self-hosted providers can also set EMBEDDING_API_URL, EMBEDDING_MODEL, and EMBEDDING_DIMENSIONS.
When changing to a model with a different vector size, reconfigure the database column from the published server image before restarting it:
docker compose run --rm server \
node ./migrate/configure-embeddings.js \
--dimensions 768 \
--clear-existingThe command clears incompatible vectors and rebuilds the HNSW index. Omit --clear-existing to make it fail safely when existing vectors would be lost.
Copyright © Feeblo contributors. Distributed under the GNU Affero General Public License v3.0.