Cross-browser bookmark sync extension with cloud storage support.
MarkSyncr is a browser extension that enables two-way bookmark synchronization between browsers and external storage sources. Sync your bookmarks across devices using your own storage (GitHub, Dropbox, Google Drive) or our managed cloud service.
- Two-way sync: Changes sync bidirectionally between browser and storage
- Preserve bookmark structure: Maintains toolbar, menu, and folder hierarchy
- Multiple storage options:
- Local file (free)
- GitHub repository (free)
- Dropbox (free)
- Google Drive (free)
- MarkSyncr Cloud (paid)
- Cross-browser support: Chrome and Firefox (Safari planned for Pro)
- Automatic & manual sync: Schedule syncs or trigger manually
- Conflict resolution: Smart handling of concurrent changes
- Cross-device sync: Track sync status across all your devices
This is a monorepo managed with pnpm workspaces and Turborepo:
marksyncr/
├── apps/
│ ├── web/ # Next.js web app (marksyncr.com)
│ └── extension/ # Browser extension (Chrome/Firefox)
├── packages/
│ ├── core/ # Sync engine, diff, conflict resolution
│ ├── sources/ # Storage integrations (GitHub, Dropbox, etc.)
│ └── types/ # Shared JSDoc types
├── supabase/
│ └── migrations/ # Database schema
└── plans/
└── architecture.md # System design documentation
- Node.js 20+
- pnpm 9+
# Clone the repository
git clone https://github.com/yourusername/marksyncr.git
cd marksyncr
# Install dependencies
pnpm install
# Set up git hooks (runs build and tests before each commit)
./scripts/setup-hooks.sh
# Start development
pnpm dev
# Build all packages
pnpm build
# Run tests
pnpm test- Web App:
cd apps/web && pnpm dev- Runs on http://localhost:3000 - Extension:
cd apps/extension && pnpm dev- Builds todist/for loading in browser
# Build for all browsers
cd apps/extension
pnpm build
# Build for specific browser
pnpm build:chrome
pnpm build:firefoxChrome:
- Go to
chrome://extensions/ - Enable "Developer mode"
- Click "Load unpacked"
- Select
apps/extension/dist/chrome
Firefox:
- Go to
about:debugging#/runtime/this-firefox - Click "Load Temporary Add-on"
- Select
apps/extension/dist/firefox/manifest.json
Copy .env.example to .env.local in each app directory:
apps/web/.env.local:
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
STRIPE_SECRET_KEY=your-stripe-secret
STRIPE_WEBHOOK_SECRET=your-webhook-secret
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your-publishable-key- Create a new Supabase project
- Run the migration in
supabase/migrations/001_initial_schema.sql - Configure OAuth providers (GitHub, Google) in Supabase Auth settings
- Update environment variables with your project credentials
- Create a Stripe account
- Create products and prices for Pro and Team plans
- Set up webhook endpoint pointing to
/api/webhooks/stripe - Update environment variables with your Stripe keys
- Frontend: React 19, Tailwind CSS
- Build: Vite (extension), Next.js 16 (web)
- Backend: Supabase (auth, database, storage)
- Payments: Stripe
- Testing: Vitest
- Monorepo: pnpm workspaces, Turborepo
Bookmarks are stored in a custom JSON format that preserves:
- Toolbar, menu, and other bookmark locations
- Folder hierarchy with nested children
- Metadata (created, modified timestamps)
- Content-based IDs for portable identification
The sync engine implements two-way sync with:
- Change detection via checksums
- Conflict resolution strategies (newer-wins, local-wins, remote-wins, merge)
- Field-level merging for non-conflicting changes
- Version tracking for optimistic concurrency
Each storage source implements a common interface:
read()- Fetch bookmark datawrite(data)- Save bookmark dataisAvailable()- Check connectivityvalidateCredentials()- Verify authentication
| Feature | Free | Pro ($5/mo) | Team ($12/mo) |
|---|---|---|---|
| Bookmarks | Unlimited | Unlimited | Unlimited |
| GitHub/Dropbox/Drive | ✓ | ✓ | ✓ |
| Local File | ✓ | ✓ | ✓ |
| MarkSyncr Cloud | - | ✓ | ✓ |
| Safari Support | - | ✓ | ✓ |
| Version History | - | 30 days | 1 year |
| Shared Folders | - | - | ✓ |
| Team Management | - | - | ✓ |
Railway provides Docker-based deployment with automatic builds.
# Install Railway CLI
npm install -g @railway/cli
# Login to Railway
railway login
# Initialize project (from repo root)
railway init
# Deploy
railway upEnvironment Variables to configure in Railway:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYSTRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYSTRIPE_PRO_MONTHLY_PRICE_IDSTRIPE_PRO_YEARLY_PRICE_IDSTRIPE_TEAM_MONTHLY_PRICE_IDSTRIPE_TEAM_YEARLY_PRICE_IDNEXT_PUBLIC_APP_URL(your Railway domain)
# Build the Docker image
docker build -t marksyncr-web -f apps/web/Dockerfile .
# Run locally
docker run -p 3000:3000 --env-file .env marksyncr-web
# Or use docker-compose
docker-compose up web# Start development mode with hot reload
docker-compose --profile dev up web-dev- Build the extension:
pnpm build - ZIP files are created in
apps/extension/dist/ - Upload to respective stores:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
pnpm test - Submit a pull request
MIT
- Documentation: https://docs.marksyncr.com
- Issues: https://github.com/yourusername/marksyncr/issues
- Email: support@marksyncr.com