Skip to content

Repository files navigation

Syncbase Logo

Syncbase

One collaborative workspace for social content, task management, team chat, and shared knowledge.

License: MITReact 19TypeScriptSupabaseTailwind CSSVite

Live Demo · Report a Bug · Request a Feature · Contributing


The Problem

Modern teams are scattered across too many disconnected tools. Content drafts live in Google Docs, tasks pile up in Jira, social posts go through Buffer, conversations happen in Slack, and nobody can remember where the API keys are stored. Context gets lost. Work gets duplicated. Team members spend more time switching apps than shipping.

Syncbase collapses all of that into a single, real-time workspace. Your team plans social content, ships tasks, tracks projects, chats, and builds shared documentation without leaving one tab.

It is fully open-source, self-hostable, and installable as a PWA. Built on React 19, TypeScript, Tailwind CSS v4, and Supabase.


Features

ModuleWhat it does
PostsDraft, review, schedule, and track social content across LinkedIn, Instagram, X/Twitter, Facebook, Reddit, YouTube, and Threads. Attach images via Cloudinary. Collect emoji reactions and comments. Run a team review workflow from draft through approved to posted.
WorkFull task management with four views: Kanban board, sortable table, calendar, and Pods view (tasks grouped by assignee). Drag-and-drop reordering, multi-assignee support, priority levels (High/Medium/Low), role-based status transitions, inline comments, and reactions.
ProjectsGroup related tasks under named projects. Track each project with a goal checklist, progress indicator, status badges, and a dedicated task list. Link tasks directly to project goals.
ChatReal-time team channel plus one-to-one direct messages. Edit and delete messages, react with emoji, attach images and files, see unread DM counts per member, and track online presence.
Info BoardStructured team knowledge store. Eight item types: text notes, API keys, numbers, AI prompts, Claude skills, photos, videos, and documents. Pin items to the top, react, reorder by drag-and-drop, and search across all entries.
WikiFull team wiki powered by BlockNote (block-based rich text). Create nested page trees, link pages with tracked backlinks, save pages to favorites, and recover unsaved work from automatic offline drafts via IndexedDB. Full-text search across all pages.
SettingsProfile management with avatar upload, team rename and logo upload, invite code regeneration and sharing, member role management (admin/member), and light/dark theme toggle with system-preference detection.
AuthEmail and password sign-up and login. Google OAuth. Auto-provisioned user profiles on first sign-in. Invite-code-based team joining. Support for multiple teams per account with instant switching.

Social platform coverage

LinkedInInstagramX / TwitterFacebookRedditYouTubeThreads
YesYesYesYesYesYesYes

Screenshots

Screenshots and a demo GIF will be added in the next release. To preview the application, follow the Quick Start guide and run it locally.


Tech Stack

LayerTechnology
FrameworkReact 19 and TypeScript 5.8
Build toolVite 8
StylingTailwind CSS v4
UI primitivesRadix UI via the shadcn/ui pattern
Backend, auth, and real-timeSupabase (PostgreSQL, Realtime, Auth)
Rich text editorBlockNote 0.51
Drag and dropdnd-kit
Formsreact-hook-form and Zod
File uploadsCloudinary
RoutingReact Router v7
Offline storageDexie (IndexedDB wrapper)
Client stateZustand
ChartsRecharts
AnimationFramer Motion
NotificationsSonner
IconsLucide React
Date utilitiesdate-fns
PWAWeb App Manifest with service worker

Quick Start

Get Syncbase running locally in under two minutes.

Prerequisites

  • Node.js 20 or later
  • A Supabase project (free tier is sufficient)
  • A Cloudinary account (free tier is sufficient)
  • A Google Cloud OAuth client ID (optional, only needed for Google sign-in)

1. Clone and install

git clone https://github.com/spacesdrive/syncbase.git
cd syncbase
npm install

2. Configure environment variables

cp .env.example .env

Open .env and fill in your values:

VITE_SUPABASE_URL=https://your-project.supabase.coVITE_SUPABASE_PUBLISHABLE_KEY=your_anon_keyVITE_CLOUDINARY_CLOUD_NAME=your_cloud_nameVITE_CLOUDINARY_UPLOAD_PRESET=your_unsigned_presetVITE_GOOGLE_CLIENT_ID=your_google_client_id

Where to find these values:

  • Supabase URL and anon key: Supabase dashboard, Project Settings, then API
  • Cloudinary cloud name and preset: Cloudinary dashboard, then Account Details and Upload Presets
  • Google Client ID: Google Cloud Console, APIs and Services, then Credentials

3. Set up the Supabase database

Run the SQL migrations in your Supabase SQL editor. The schema creates these tables:

profilesteamsteam_memberspostspost_imagespost_reactionscommentstaskstask_assigneestask_commentstask_reactionsprojectsproject_goalsinfo_itemsinfo_reactionsteam_messagesdirect_messagesmessage_reactionsnotificationsactivity_eventswiki_pageswiki_backlinkswiki_favoriteswiki_page_history

The following stored procedures are required:

create_postcreate_taskcreate_projectupdate_projectset_task_assigneesupdate_task_assignee_statusreorder_taskscreate_task_comment

Enable Row Level Security on all tables and Realtime on: posts, tasks, team_messages, direct_messages, notifications, task_comments, and wiki_pages.

4. Start the dev server

npm run dev

Open http://localhost:5173. Sign up, create a team, and you are in.


Architecture

graph TD
subgraph Browser["Browser / PWA"]
direction TB
subgraph React["React 19 SPA (Vite 8)"]
Contexts["AuthContext + TeamContext\n(session, active team, presence)"]
Pages["Pages: Posts / Work / Projects\nChat / Info / Wiki / Settings"]
APILayer["lib/api.ts\n(unified Supabase data layer)"]
Hooks["useRealtime / useTheme / useIsMobile"]
end
IDB["IndexedDB via Dexie\n(wiki offline drafts)"]
end
subgraph Supabase["Supabase Platform"]
PG[("PostgreSQL\n(RLS + stored procedures)")]
SBAuth["Auth Service\n(Email + Google OAuth)"]
RT["Realtime\n(postgres_changes + presence)"]
end
CDN["Cloudinary\n(images + file storage)"]
React -->|"REST / HTTPS"| PG
React -->|"session"| SBAuth
RT -->|"WebSocket"| Hooks
Hooks --> Pages
Pages --> IDB
Pages -->|"upload"| CDN
Loading

Data flow:

  1. AuthContext resolves the Supabase session on mount and auto-provisions a profiles row for new users.
  2. TeamContext reads the active team from localStorage, loads team members, and opens a Supabase Realtime presence channel to track online status.
  3. All data operations go through lib/api.ts, which wraps Supabase queries and stored procedure calls with typed helpers.
  4. Pages subscribe to live updates using the useRealtime hook, which channels postgres_changes events back through the same data helpers, keeping the UI in sync across all open sessions without polling.
  5. The Wiki module writes unsaved drafts to IndexedDB via Dexie so edits survive page refreshes and network interruptions.

Project Structure

syncbase/
├── public/ # PWA manifest, favicon set, app icons
│ └── manifest.json
├── src/
│ ├── App.tsx # Router, route guards, error boundary
│ ├── main.tsx # React root, global providers
│ ├── index.css # Global styles and Tailwind imports
│ ├── styles/
│ │ └── theme.css # CSS custom properties for light and dark themes
│ ├── lib/
│ │ ├── api.ts # All Supabase API calls (teams, posts, tasks, chat, wiki)
│ │ ├── supabase.ts # Supabase client initialisation
│ │ ├── cloudinary.ts # Image and file upload helpers
│ │ ├── constants.ts # Platforms, statuses, priorities, info types
│ │ ├── taskStatusRules.ts # Role-based task status transition rules
│ │ └── utils.ts # cn() and shared utilities
│ ├── contexts/
│ │ ├── AuthContext.tsx # Auth state, session management, profile provisioning
│ │ └── TeamContext.tsx # Active team, members, presence tracking, team switching
│ ├── hooks/
│ │ ├── useRealtime.ts # Supabase Realtime subscription wrapper
│ │ ├── useTheme.ts # Dark and light mode with localStorage persistence
│ │ └── useIsMobile.ts # Responsive breakpoint hook
│ ├── components/
│ │ ├── ui/ # shadcn/Radix UI primitives and custom app components
│ │ ├── layout/ # Layout shell, Sidebar, TopBar
│ │ ├── aceternity/ # Aurora background and spotlight effects
│ │ └── icons/ # Platform SVG icons (LinkedIn, Instagram, etc.)
│ ├── features/
│ │ └── wiki/
│ │ ├── components/ # WikiHome, WikiSidebar, WikiPageView, WikiEditor, WikiBacklinks
│ │ ├── hooks/ # useWikiPages (page tree, search, CRUD)
│ │ ├── services/ # offlineService (Dexie), searchService
│ │ ├── stores/ # Zustand wiki store
│ │ └── types/ # WikiPage, WikiBacklink, WikiDraft types
│ └── pages/
│ ├── auth/ # Login, Signup
│ ├── team/ # TeamSetup (create or join)
│ ├── posts/ # Posts list, PostCard, NewPostModal
│ ├── work/ # Work hub, Kanban, Table, Calendar, Pods, TaskCard
│ ├── projects/ # Project list, ProjectDetail, ProjectGoals
│ ├── chat/ # Team channel and direct messages
│ ├── info/ # Info Board
│ ├── wiki/ # Wiki page router
│ └── settings/ # Profile, account, appearance, notifications, members
├── .env.example
├── vite.config.ts
├── tsconfig.app.json
└── package.json

Database Schema

The key relationships at a glance:

TablePurpose
profilesOne row per Supabase auth user. Stores name, avatar, email.
teamsWorkspace entity. Has a unique invite code for joining.
team_membersJoin table between profiles and teams. Holds role (admin/member).
postsSocial content drafts. References team, author, platforms array, and scheduled time.
post_imagesOne-to-many image URLs per post (via Cloudinary).
tasksWork items. Linked to team, project, primary assignee, and sort order for drag-and-drop.
task_assigneesMulti-assignee support per task with per-assignee status tracking.
task_commentsThreaded comments on tasks.
projectsProject containers. Each belongs to a team.
project_goalsChecklist goals under a project with progress tracking.
info_itemsInfo board entries. Typed (text/api_key/number/prompt/etc.), pinnable, orderable.
team_messagesTeam channel messages. Supports attachments and reactions.
direct_messagesOne-to-one messages between team members. Has read/unread tracking.
message_reactionsEmoji reactions on team or DM messages.
notificationsIn-app notification feed per user with read/unread state.
wiki_pagesWiki pages with nested parent/child relationships, BlockNote JSON content, and sort order.
wiki_backlinksTracks which wiki pages link to which other wiki pages.
wiki_favoritesPer-user wiki page bookmarks.
wiki_page_historyVersion history snapshots saved on each wiki page publish.
activity_eventsAudit log of team actions (task created, completed, etc.).

All tables have Row Level Security enabled. Users can only read and write data belonging to their own teams.


Available Scripts

npm run dev # Start development server at http://localhost:5173
npm run build # Production build to dist/
npm run preview # Serve the production build locally
npm run lint # Run ESLint across the source tree

Deployment

Syncbase is a static single-page application. Deploy the dist/ folder to any host that can serve static files with a catch-all redirect to index.html.

Vercel (recommended)

npm install -g vercel
vercel --prod

Set the five environment variables in the Vercel dashboard under Project, then Settings, then Environment Variables.

Netlify

npm run build

Drag and drop the dist/ folder at app.netlify.com/drop, or connect the GitHub repository with build command npm run build and publish directory dist. Add a _redirects file to public/:

/* /index.html 200

Self-hosted (Nginx)

server{listen80;server_name your-domain.com;root /var/www/syncbase/dist;indexindex.html;location / {try_files$uri$uri/ /index.html;}}

Because Syncbase is a client-side SPA, every server route must return index.html. The try_files directive above handles this for Nginx. Without it, direct links and page refreshes will return 404.


Environment Variables Reference

VariableRequiredDescription
VITE_SUPABASE_URLYesSupabase project URL (e.g. https://xxxx.supabase.co)
VITE_SUPABASE_PUBLISHABLE_KEYYesSupabase anon / publishable key
VITE_CLOUDINARY_CLOUD_NAMEYesCloudinary cloud name for image and file uploads
VITE_CLOUDINARY_UPLOAD_PRESETYesUnsigned Cloudinary upload preset name
VITE_GOOGLE_CLIENT_IDNoGoogle OAuth client ID (enables Google sign-in button)

Troubleshooting

Blank page after login with "Missing Supabase env vars" in the console

Your .env file is either missing or has incorrect variable names. Check that the file is at the project root (same level as package.json) and that you restarted the dev server after editing it. Vite only exposes environment variables that start with VITE_.

Stuck on the TeamSetup screen after logging in

The signed-in user has no team membership. Either create a new team or join one with an invite code. If you are testing with the same account repeatedly, check that the team_members row was not accidentally deleted in the Supabase table editor.

Image uploads fail silently

Check that VITE_CLOUDINARY_UPLOAD_PRESET is an unsigned preset. In the Cloudinary dashboard: Settings, then Upload, then Upload Presets. The preset mode must be set to "Unsigned". Signed presets require a server-side signature and will not work from a browser.

Real-time updates not arriving

Supabase Realtime must be enabled per table. In the Supabase dashboard: Database, then Replication. Enable the following tables: posts, tasks, team_messages, direct_messages, notifications, task_comments, and wiki_pages.

Google OAuth redirects to the wrong URL after sign-in

In the Google Cloud Console under OAuth 2.0 Client credentials, add your full origin (e.g. http://localhost:5173 for local development or https://your-domain.com for production) to both Authorised JavaScript origins and Authorised redirect URIs. Then add the same URL in Supabase under Authentication, then URL Configuration, then Redirect URLs.

Wiki editor does not save changes

Ensure the wiki_pages table has Realtime enabled and that your Supabase RLS policies allow the authenticated user to update rows in that table. Check the browser console for any 403 errors from Supabase.


Roadmap

  • Email notifications for task assignments and @mentions
  • Post analytics dashboard (reach, engagement per platform)
  • Calendar export compatible with Google Calendar and ICS
  • Granular notification preferences per channel and event type
  • Mobile application (React Native)
  • Webhooks for external integrations (Zapier, Make)
  • AI writing assistant for post caption drafting
  • Public shareable wiki pages

Have an idea? Open a feature request.


Contributing

Contributions are welcome: bug fixes, new features, documentation improvements, and design refinements. Here is how to get started.

# Fork the repo on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/syncbase.git
cd syncbase
# Install dependencies
npm install
# Create a feature branch
git checkout -b feat/your-feature-name
# Start the dev server
npm run dev
# Lint before committing
npm run lint
  1. Fork the repository and clone your fork locally.
  2. Create a branch named feat/your-feature or fix/your-bug.
  3. Make your changes and commit with a clear message following Conventional Commits.
  4. Push your branch and open a Pull Request against main.

For larger changes, please open an issue first to discuss the approach before investing significant time.

Browse issues labelled good first issue if you are new to the codebase.


License

Distributed under the MIT License. See LICENSE for the full text.

You are free to use, modify, and distribute Syncbase in personal and commercial projects. Attribution is appreciated but not required.


Acknowledgements

Syncbase is built on the shoulders of excellent open-source work:


If Syncbase saves your team time, a star on GitHub helps others discover it.

Star on GitHub

About

The collaborative workspace where your team posts, ships, and stays in sync, all in one place.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages