How to Self-Host Formbricks — Open Source Typeform Alternative 2026
What Is Formbricks?
Formbricks is an open source experience management platform — part survey tool, part in-app feedback system, part user research platform. It lets you:
- Build multi-step forms and surveys (like Typeform)
- Trigger in-app micro-surveys based on user actions
- Create NPS surveys, CSAT forms, and feature interviews
- Run link surveys (shareable URLs)
- Analyze responses with built-in analytics
Typeform costs $50-$83/month for teams that need logic jumps, file uploads, and integrations. Formbricks is free when self-hosted — just server costs (~$10/month on Hetzner CX32).
Key differentiator: Formbricks has a "No-Code SDK" approach — you instrument your app once, then non-engineers can create and target surveys without deployments.
Prerequisites
- VPS with 2 vCPU, 2GB RAM minimum
- Docker + Docker Compose v2
- Domain name pointing to your server
- SMTP credentials (for invite emails)
Docker Compose Deployment
1. Create Project Directory
mkdir formbricks && cd formbricks
2. Create docker-compose.yaml
version: "3.3"
networks:
formbricks:
volumes:
uploads:
database:
services:
postgres:
image: postgres:15-alpine
volumes:
- database:/var/lib/postgresql/data
restart: always
networks:
- formbricks
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: formbricks
POSTGRES_DB: formbricks
formbricks:
image: ghcr.io/formbricks/formbricks:latest
depends_on:
- postgres
ports:
- "3000:3000"
volumes:
- uploads:/home/nextjs/apps/web/uploads
restart: always
networks:
- formbricks
environment:
# App URL
WEBAPP_URL: ${WEBAPP_URL}
# Security
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
# Database
DATABASE_URL: postgresql://formbricks:${POSTGRES_PASSWORD}@postgres:5432/formbricks
# Email
MAIL_FROM: ${MAIL_FROM}
SMTP_HOST: ${SMTP_HOST}
SMTP_PORT: ${SMTP_PORT}
SMTP_USER: ${SMTP_USER}
SMTP_PASSWORD: ${SMTP_PASSWORD}
SMTP_SECURE_ENABLED: ${SMTP_SECURE_ENABLED}
# Instance settings
PRIVACY_URL: ${PRIVACY_URL:-}
TERMS_URL: ${TERMS_URL:-}
IMPRINT_URL: ${IMPRINT_URL:-}
# Optional: disable new signups
# DISABLE_REGISTRATION: "1"
3. Create .env
# .env
# App URL (no trailing slash)
WEBAPP_URL=https://forms.yourdomain.com
# Security keys — generate strong random values
NEXTAUTH_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
# Database
POSTGRES_PASSWORD=your-secure-db-password
# Email (SMTP)
MAIL_FROM=noreply@yourdomain.com
SMTP_HOST=smtp.yourdomain.com
SMTP_PORT=587
SMTP_USER=your-smtp-username
SMTP_PASSWORD=your-smtp-password
SMTP_SECURE_ENABLED=1
4. Start Formbricks
docker compose up -d
# Check startup
docker compose logs -f formbricks
# Look for: "Ready - started server on 0.0.0.0:3000"
Configure Caddy Reverse Proxy
# /etc/caddy/Caddyfile
forms.yourdomain.com {
reverse_proxy localhost:3000
# Allow large file uploads in forms
request_body {
max_size 50MB
}
}
systemctl reload caddy
First Login and Setup
Visit https://forms.yourdomain.com:
1. Click "Create account"
2. Enter name, email, and password
3. Complete the onboarding (create your first environment)
4. You're now the admin of your instance
Formbricks Concepts
Organization (your company/team)
└── Products (your apps/websites)
└── Environments (Production / Development)
└── Surveys
├── Link Surveys (standalone URL)
├── In-App Surveys (triggered by user actions)
└── Web Surveys (embedded in site)
Building Your First Survey
Link Survey (Like Typeform)
1. Go to Surveys → New Survey
2. Select "Link Survey"
3. Add questions:
- Rating (NPS 0-10)
- Open Text
- Single Select
- Multi Select
- Matrix
- File Upload
4. Configure logic: "If rating < 7, show follow-up"
5. Set thank you card
6. Publish → Copy link
In-App Survey (No Extra Deploy Needed)
Formbricks shines with in-app micro-surveys. Install the SDK once, then trigger surveys via the dashboard:
npm install @formbricks/js
// app/providers.tsx (Next.js)
"use client";
import { useEffect } from "react";
import formbricks from "@formbricks/js";
export function FormbricksProvider({ children, user }) {
useEffect(() => {
formbricks.setup({
environmentId: "your-env-id", // from Formbricks dashboard
apiHost: "https://forms.yourdomain.com",
});
// Identify the user (for targeted surveys)
if (user) {
formbricks.setUserId(user.id);
formbricks.setEmail(user.email);
// Custom attributes for targeting
formbricks.setAttribute("plan", user.plan);
formbricks.setAttribute("createdAt", user.createdAt);
}
// Track actions to trigger surveys
formbricks.track("Dashboard Visited");
}, [user]);
return children;
}
Then in the Formbricks dashboard, create a survey with trigger: "When user visits Dashboard 3 times" — no code change needed.
Integrations
Webhooks (Send to Any Service)
Survey Settings → Webhooks → Add Webhook
URL: https://hooks.yourdomain.com/formbricks
Events: Response Created, Response Finished
Payload format:
{
"event": "responseCreated",
"data": {
"surveyId": "abc123",
"response": {
"finished": true,
"data": {
"question-1": "Very satisfied",
"question-2": "The UI is intuitive"
}
}
}
}
Slack Integration
Survey Settings → Integrations → Slack
→ Connect Slack workspace
→ Choose channel for response notifications
Google Sheets
Survey Settings → Integrations → Google Sheets
→ Authenticate with Google
→ Map survey fields to columns
→ New responses auto-append rows
Segment Your Audience for Targeted Surveys
Formbricks lets you target surveys based on user attributes:
Show survey to users where:
- plan = "free"
- AND account age >= 7 days
- AND has_used_feature_X = false
Display: when user opens "Upgrade" modal
This is what replaces tools like Sprig, Qualtrics, or Typeform's conditional logic — but at the SDK level, not form logic level.
Email Follow-Up After Survey
Survey Settings → Actions → Send Email on Completion
When: Survey finished
Send to: {respondent_email} (if you collected email)
Subject: Thanks for your feedback, {first_name}!
Body: (rich text with dynamic variables)
Disable Public Registration
After setting up your team:
# docker-compose.yaml — formbricks service environment
DISABLE_REGISTRATION: "1"
docker compose up -d
New users can only be invited by existing members.
Backup and Restore
#!/bin/bash
# backup-formbricks.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/formbricks"
mkdir -p $BACKUP_DIR
# Database
docker compose exec -T postgres pg_dump \
-U formbricks formbricks | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# Uploaded files (if using local storage)
UPLOADS_PATH=$(docker volume inspect formbricks_uploads --format '{{.Mountpoint}}')
tar -czf $BACKUP_DIR/uploads_$DATE.tar.gz "$UPLOADS_PATH"
# Retain 30 days
find $BACKUP_DIR -mtime +30 -delete
Formbricks vs Typeform vs SurveyMonkey
| Feature | Formbricks (self-hosted) | Typeform | SurveyMonkey |
|---|---|---|---|
| Price | ~$10/mo server | $50-83/mo | $39-99/mo |
| Self-hosted | ✅ | ❌ | ❌ |
| In-app surveys | ✅ | ❌ | ❌ |
| Conditional logic | ✅ | ✅ | ✅ |
| File upload | ✅ | ✅ | ✅ |
| NPS tracking | ✅ | ✅ | ✅ |
| Webhooks | ✅ | ✅ | ✅ |
| Data ownership | ✅ Full | ❌ | ❌ |
| GDPR compliant | ✅ (by design) | ⚠️ EU transfer | ⚠️ |
| White-label | ✅ | 💰 Paid | 💰 Paid |
| API | ✅ | ✅ | ✅ |
| Response analytics | ✅ | ✅ | ✅ |
Troubleshooting
Formbricks won't start:
docker compose logs formbricks
# "DATABASE_URL" connection error: ensure postgres is healthy
docker compose ps # check postgres status
Emails not sending:
docker compose logs formbricks | grep -i "smtp\|email\|mail"
# Test SMTP: docker compose exec formbricks curl smtp://your-host:587
SDK not triggering surveys:
# In browser console:
formbricks.getState()
# Should show environmentId and person attributes
Formbricks is a top Typeform alternative on OSSAlt — see all open source form and survey builders.