A modern, full-featured form builder application built with TanStack Start, React, and Appwrite. Create, share, and manage dynamic forms with an intuitive drag-and-drop interface.
- β Email/password authentication
- β Protected admin routes
- β Optional form authentication for participants
- β Session management with secure cookies
- β Create, edit, duplicate, and delete forms
- β Search forms by title
- β Form list with creation dates and metadata
- β Share form links with one click
- β
11 field types:
- Short Text (single-line input)
- Long Text (multi-line textarea)
- Checkbox (multiple choice)
- Dropdown/Select
- Radio buttons
- Date picker
- Number input
- File upload
- Rating (1-5 stars)
- Email input
- Section divider
- β Drag-and-drop reordering with visual feedback
- β Field customization (label, placeholder, required, options)
- β Auto-save (500ms debounce)
- β Real-time preview
- β
Unique form URLs (e.g.,
/form/{formId}) - β Public form access with optional authentication
- β Client-side and server-side validation
- β Success confirmation page
- β Responsive mobile-friendly forms
- β View all submissions in table format
- β Detailed submission view
- β Export to CSV
- β Export to JSON
- β Delete submissions with confirmation
- β Submission metadata (timestamp, participant email)
- Framework: TanStack Start (React meta-framework)
- Router: TanStack Router
- State Management: TanStack Query
- Backend: Appwrite (Database, Auth, Storage)
- UI Components: shadcn/ui
- Styling: Tailwind CSS v4
- Drag & Drop: @dnd-kit
- Form Handling: React Hook Form + Zod
git clone <repository-url>
cd form-builder-saasbun installCopy .env.example to .env:
cp .env.example .envFill in your Appwrite credentials in .env:
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
APPWRITE_API_KEY=your-api-key
APPWRITE_BUCKET_ID=imagine-project-bucket
APPWRITE_PROJECT_ID=your-project-id
VITE_INSTRUMENTATION_SCRIPT_SRC= # Optional analyticsThe database schema is defined in appwrite.json. Deploy it to your Appwrite project:
# Install Appwrite CLI if you haven't already
npm install -g appwrite-cli
# Login to Appwrite
appwrite login
# Deploy the schema
appwrite deploy collectionThis will create:
- Forms collection (stores form metadata)
- FormFields collection (stores individual form fields)
- FormSubmissions collection (stores participant responses)
- Storage bucket (for file uploads)
bun run devThe app will be available at http://localhost:3000.
- Sign up with valid email/password
- Sign in with existing account
- Sign out successfully
- Protected routes redirect to sign-in when not authenticated
- After sign-in, user is redirected to dashboard
- View list of forms
- Search forms by title
- Create new form with title, description, and auth toggle
- Edit form (navigates to form builder)
- Duplicate form (creates copy with all fields)
- Delete form (shows confirmation, removes form and data)
- Copy form link to clipboard
- Add fields by clicking field types
- Drag and drop fields to reorder
- Select field to open settings panel
- Edit field label, placeholder, required toggle
- Add/remove options for select/radio/checkbox fields
- Delete field (shows on hover)
- Auto-save updates (check by refreshing page)
- Preview form (opens in new tab)
- Back to dashboard navigation
- Access form via
/form/{formId}URL - Form shows authentication prompt if
requireAuthis enabled - All 11 field types render correctly
- Required fields show validation errors
- Form submits successfully
- Success message displays after submission
- Form is responsive on mobile devices
- View submissions list for a form
- Click "View" to see submission details
- Export submissions to CSV
- Export submissions to JSON
- Delete submission with confirmation
- Submission stats display correctly
- Keyboard navigation works throughout app
- Focus states are visible
- Form labels are properly associated
- Error messages are announced
- Color contrast meets WCAG 2.1 AA standards
- Test on mobile (320px-767px)
- Test on tablet (768px-1023px)
- Test on desktop (1024px+)
- Touch targets are at least 44x44px
- Text is readable without zooming
bun run buildThis creates an optimized production build in the dist directory.
bun run serveThe application can be deployed to any Node.js hosting platform:
- Connect your Git repository
- Set environment variables
- Deploy (platform will auto-detect TanStack Start)
docker build -t form-builder .
docker run -p 3000:3000 form-builderbun run build
bun run start| Variable | Description | Required |
|---|---|---|
APPWRITE_ENDPOINT |
Appwrite API endpoint URL | Yes |
APPWRITE_API_KEY |
Appwrite API key with full permissions | Yes |
APPWRITE_BUCKET_ID |
Storage bucket ID for file uploads | Yes |
APPWRITE_PROJECT_ID |
Appwrite project ID | Yes |
VITE_INSTRUMENTATION_SCRIPT_SRC |
Analytics script URL (optional) | No |
- Code Splitting: Routes are lazy-loaded
- Auto-save Debouncing: Field updates debounced by 500ms
- Query Caching: TanStack Query caches API responses
- Optimistic Updates: UI updates immediately for smooth UX
- Use browser DevTools Performance tab
- Check Network tab for API response times
- Monitor bundle size with
bun run build --analyze
- Enable Appwrite CDN for faster API responses
- Use a CDN for static assets
- Enable compression on your hosting platform
- Monitor error rates with Sentry or similar
- Set up uptime monitoring
src/
βββ components/ # Reusable UI components
β βββ ui/ # shadcn/ui components (read-only)
β βββ auth/ # Authentication components
β βββ dashboard/ # Dashboard components
β βββ form-builder/ # Form builder components
β βββ submissions/ # Submission management components
βββ hooks/ # Custom React hooks
βββ lib/ # Utilities and helpers
β βββ field-types.ts # Field type definitions
β βββ utils.ts # General utilities
βββ routes/ # TanStack Router routes
β βββ _public/ # Public routes (home, forms)
β βββ _protected/ # Protected routes (dashboard, builder, submissions)
β βββ _auth/ # Auth routes (sign-in, sign-up, sign-out)
βββ server/ # Server-side code
β βββ lib/ # Server utilities
β β βββ appwrite.ts # Appwrite client setup
β β βββ db.ts # Database helpers
β β βββ appwrite.types.ts # TypeScript types
β βββ functions/ # Server functions
β βββ auth.ts # Authentication logic
β βββ forms.ts # Form CRUD operations
β βββ formFields.ts # Field CRUD operations
β βββ submissions.ts # Submission handling
βββ styles.css # Global styles (Tailwind)
- Never expose API keys: Environment variables are server-only
- Ownership verification: All CRUD operations verify user ownership
- Input validation: Zod schemas validate all user input
- SQL injection protection: Appwrite handles parameterized queries
- XSS protection: React auto-escapes rendered content
- CSRF protection: Session cookies use
httpOnlyandsecureflags
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License.
- TanStack for the amazing ecosystem
- Appwrite for the backend infrastructure
- shadcn/ui for beautiful UI components
- @dnd-kit for drag-and-drop functionality
For issues and questions:
- Open an issue on GitHub
- Check existing issues for solutions
- Review the documentation
Built with β€οΈ using modern web technologies