A real-time collaborative whiteboard application built with Next.js, Liveblocks, and Convex. SoapBoard enables teams to create, share, and collaborate on interactive boards with drawing tools, shapes, text, and notes.
SoapBoard is a modern collaborative whiteboard platform that allows multiple users to work together in real-time on a shared canvas. Users can create boards, draw with various tools, add shapes and text, and see live cursor positions of other collaborators. The application features organization-based access control, board management, favorites, and comprehensive search functionality.
- Real-time Collaboration: Multiple users can work on the same board simultaneously with live cursor tracking and instant synchronization
- Drawing Tools:
- Pencil tool for freehand drawing with pressure sensitivity
- Rectangle and Ellipse shapes with customizable styling
- Text layers with editable content
- Note layers for annotations and comments
- Layer Management:
- Support for up to 100 layers per board
- Layer selection and manipulation
- Resize handles for shapes with visual feedback
- Multi-layer selection with selection net
- Board Management:
- Create, delete, and rename boards
- Favorite boards for quick access
- Search boards by title
- Organization-based board organization and isolation
- User Experience:
- Undo/Redo functionality with full history
- Color picker for customizing layers
- Responsive design for desktop and tablet
- Dark and light theme support
- Toast notifications for user feedback
- Real-time synchronization via Liveblocks WebSocket connections
- Authentication and authorization via Clerk
- Backend data persistence via Convex database
- Optimistic UI updates for responsive interactions
- Type-safe development with TypeScript
- React Compiler for automatic performance optimizations
- Framework: Next.js 16.1.0 with App Router
- UI Library: React 19.2.3
- Styling: Tailwind CSS 4
- UI Components: Radix UI (Dialog, Dropdown, Avatar, Tooltip, Alert Dialog)
- Icons: Lucide React
- State Management: Zustand
- Real-time Collaboration: Liveblocks React SDK
- Drawing: perfect-freehand
- Color Picker: react-colorful
- Notifications: Sonner
- Theming: next-themes
- Backend: Convex (serverless backend platform)
- Authentication: Clerk
- Real-time Synchronization: Liveblocks
- Database: Convex integrated database
- Language: TypeScript 5 with strict mode
- Linting: ESLint with Next.js configuration
- Build Tool: Next.js with Turbopack
- Compiler: React Compiler via babel-plugin-react-compiler
Before you begin, ensure you have the following installed and configured:
- Node.js 18 or higher
- npm, yarn, or pnpm package manager
- Clerk account for authentication
- Convex account for backend services
- Liveblocks account for real-time collaboration
git clone <repository-url>
cd soapboardnpm install
# or
yarn install
# or
pnpm installCreate a .env.local file in the root directory with the following variables:
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
# Convex Backend
NEXT_PUBLIC_CONVEX_URL=your_convex_url
# Liveblocks Real-time Collaboration
NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_KEY=your_liveblocks_public_key
LIVEBLOCKS_SECRET_KEY=your_liveblocks_secret_key- Create an account at https://clerk.com
- Create a new application in the Clerk dashboard
- Configure a JWT template named "convex" for Convex integration
- Copy your publishable key and secret key to
.env.local - Update
convex/auth.config.tswith your Clerk issuer domain
- Create an account at https://convex.dev
- Create a new project
- Run the following command to initialize Convex:
npx convex dev
- Copy the Convex URL to
.env.local - Deploy your schema:
npx convex deploy
- Create an account at https://liveblocks.io
- Create a new project
- Copy your public key and secret key to
.env.local - Configure the authentication endpoint in your Liveblocks dashboard
npm run dev
# or
yarn dev
# or
pnpm devOpen http://localhost:3000 in your browser to access the application.
npm run buildnpm startThe recommended deployment platform is Vercel:
- Push your code to GitHub
- Import your repository in the Vercel dashboard
- Add all environment variables in the Vercel dashboard
- Deploy
Vercel will automatically detect Next.js and configure the build settings.
soapboard/
├── app/ # Next.js App Router pages and layouts
│ ├── (dashboard)/ # Dashboard route group
│ ├── (auth)/ # Authentication route group
│ ├── api/ # API routes and webhooks
│ ├── board/ # Board pages and components
│ └── layout.tsx # Root layout component
├── components/ # Reusable React components
│ ├── ui/ # shadcn/ui components
│ ├── board/ # Board-specific components
│ └── auth/ # Authentication components
├── convex/ # Convex backend functions and schema
│ ├── board.ts # Board mutations and queries
│ ├── boards.ts # Boards list and search operations
│ ├── auth.config.ts # Authentication configuration
│ └── schema.ts # Database schema definition
├── hooks/ # Custom React hooks
├── lib/ # Utility functions and helpers
├── providers/ # React context providers
├── store/ # Zustand state management stores
├── types/ # TypeScript type definitions
├── public/ # Static assets
├── .env.local # Environment variables (not in repository)
└── package.json # Project dependencies
npm run dev- Start development server with hot reloadnpm run build- Build application for productionnpm start- Start production servernpm run lint- Run ESLint to check code qualitynpx convex dev- Start Convex backend in development mode
- TypeScript strict mode is enabled for type safety
- ESLint configuration includes Next.js best practices
- React Compiler is enabled for automatic optimizations
- Path aliases are configured (
@/*maps to project root) - All code should follow the existing style patterns
New Canvas Tools:
- Add tool definitions to
types/canvas.ts - Implement tool handlers in
app/board/[boardId]/_components/Canvas.tsx - Add UI controls in the toolbar component
New API Endpoints:
- Create new routes in
app/api/directory - Follow existing error handling patterns
- Include proper request validation
New Convex Functions:
- Add mutations and queries to
convex/directory - Update
convex/schema.tsif database schema changes are needed - Test functions using Convex dashboard
New UI Components:
- Create new components in
components/directory - Use Radix UI for base components when appropriate
- Follow existing component structure and prop patterns
- Verify Clerk keys are correctly set in
.env.local - Confirm that Clerk JWT template is properly configured for Convex
- Check that
convex/auth.config.tscontains the correct issuer domain - Review Clerk dashboard for any configuration errors
- Verify
NEXT_PUBLIC_CONVEX_URLis set correctly - Run
npx convex devto ensure Convex is running - Check the Convex dashboard for deployment status and errors
- Review browser console for network errors
- Verify Liveblocks keys are correctly set in
.env.local - Check that
/api/liveblocks-authroute is accessible - Ensure board exists in Convex before attempting access
- Review Liveblocks dashboard for room configuration
- Clear the Next.js build cache:
rm -rf .next - Reinstall dependencies:
rm -rf node_modules && npm install - Check for TypeScript errors:
npx tsc --noEmit - Review build logs for specific error messages
- Check browser console for JavaScript errors
- Verify Liveblocks room is properly initialized
- Ensure camera state is correctly set in canvas context
- Confirm browser supports required Canvas APIs
Contributions are welcome. Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature-name - Commit your changes:
git commit -m 'Add description of changes' - Push to the branch:
git push origin feature/your-feature-name - Open a Pull Request with a clear description of the changes
This project is licensed under the MIT License. See the LICENSE file for details.
- Built with Next.js
- Real-time collaboration powered by Liveblocks
- Authentication by Clerk
- Backend by Convex
- UI components from shadcn/ui
- Drawing library: perfect-freehand
For issues, questions, or suggestions, please open an issue on the GitHub repository.