Skip to main content

Prerequisites

Before you begin, ensure you have the following installed on your system:

Node.js

Version: 18.x or higherDownload Node.js

Package Manager

Options: npm, yarn, pnpm, or bunComes with Node.js (npm)

Git

Version: 2.x or higherDownload Git

Code Editor

Recommended: VS CodeDownload VS Code

Verify Installation

1

Check Node.js Version

node --version
# Should output v18.x.x or higher
2

Check npm Version

npm --version
# Should output 9.x.x or higher
3

Check Git Version

git --version
# Should output git version 2.x.x

Supabase Account Setup

You’ll need a Supabase project to run ClipSync locally. The app cannot function without a configured backend.

Create Supabase Project

1

Sign Up for Supabase

  1. Go to supabase.com
  2. Click “Start your project”
  3. Sign up with GitHub or email
2

Create New Project

  1. Click “New Project”
  2. Choose an organization (or create one)
  3. Fill in project details:
    • Name: ClipSync (or any name)
    • Database Password: Generate a strong password
    • Region: Choose closest to you
  4. Click “Create new project”
  5. Wait for project to finish setting up (~2 minutes)
3

Get API Credentials

  1. Navigate to SettingsAPI
  2. Copy the following values:
    • Project URL (under “Project URL”)
    • anon public key (under “Project API keys”)
Keep these credentials safe! You’ll need them for the .env file.

Set Up Database Tables

1

Open SQL Editor

Navigate to SQL Editor in the left sidebar
2

Create Tables

Run the following SQL queries to create required tables:
CREATE TABLE sessions (
  id BIGSERIAL PRIMARY KEY,
  code VARCHAR(5) UNIQUE NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Create index for faster lookups
CREATE INDEX idx_sessions_code ON sessions(code);
3

Enable Realtime

Enable realtime for the clipboard table:
  1. Navigate to DatabaseReplication
  2. Find the clipboard table
  3. Toggle Enable Realtime to ON
Or run this SQL:
ALTER PUBLICATION supabase_realtime ADD TABLE clipboard;

Set Up Storage Bucket

1

Navigate to Storage

Go to Storage in the left sidebar
2

Create Bucket

  1. Click “New bucket”
  2. Name: clipboard
  3. Public bucket: Toggle ON (files need to be publicly accessible)
  4. Click “Create bucket”
3

Configure Bucket Policies

Set up storage policies to allow uploads and deletes:
  1. Click on the clipboard bucket
  2. Go to Policies tab
  3. Add the following policies:
CREATE POLICY "Allow public uploads"
ON storage.objects FOR INSERT
TO public
WITH CHECK (bucket_id = 'clipboard');
CREATE POLICY "Allow public access"
ON storage.objects FOR SELECT
TO public
USING (bucket_id = 'clipboard');
CREATE POLICY "Allow public deletes"
ON storage.objects FOR DELETE
TO public
USING (bucket_id = 'clipboard');
In a production environment, you would want to add authentication and restrict these policies to authenticated users only.

Project Setup

Clone Repository

1

Clone the Repo

git clone <repository-url>
cd clipsync
Replace <repository-url> with the actual repository URL.
2

Navigate to Client Directory

cd client
The client application is in the client/ subdirectory.

Install Dependencies

npm install
Reference: package.json:12-38

Environment Configuration

1

Create .env File

Create a .env file in the client/ directory:
touch .env
2

Add Environment Variables

Add your Supabase credentials to .env:
.env
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
Replace your_supabase_project_url and your_supabase_anon_key with the actual values from your Supabase project settings.
3

Update Storage URL (if needed)

If your Supabase project URL is different, update the storage URL in src/App.jsx:
src/App.jsx:156
const url = `https://YOUR_PROJECT_ID.supabase.co/storage/v1/object/public/${data.fullPath}`;
Replace YOUR_PROJECT_ID with your actual Supabase project ID.Reference: src/App.jsx:156
Reference: src/config/supabase.js:1-7

Verify Configuration

1

Check .env File

Ensure your .env file looks like this:
VITE_SUPABASE_URL=https://xxxxxxxxxxxxx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
2

Add to .gitignore

Ensure .env is in .gitignore to avoid committing secrets:
.gitignore
.env
.env.local
.env.production

Running Locally

Development Server

Reference: package.json:7
npm run dev
1

Start Development Server

Run the dev command. You should see output like:
VITE v6.2.0  ready in 350 ms

  Local:   http://localhost:5173/
  Network: use --host to expose
  press h + enter to show help
2

Open in Browser

Navigate to http://localhost:5173The app should load with the ClipSync interface.
3

Test Functionality

  1. Enter some text in the clipboard textarea
  2. Click “Send to Clipboard”
  3. A session code should be generated
  4. Verify the clipboard entry appears in the history
Hot Module Replacement (HMR) is enabled by default. Changes to your code will instantly reflect in the browser without a full reload.

Development Workflow

1

File Watching

Vite watches all files in src/ for changes. Save any file to see instant updates.
2

Error Handling

Errors appear both in the browser overlay and terminal console.
3

Network Access

To test on other devices (mobile, tablet), use:
npm run dev -- --host
Then access via your local IP (e.g., http://192.168.1.100:5173)

Build and Preview

Production Build

Reference: package.json:8
npm run build
This command:
  1. Runs type checking (if TypeScript is configured)
  2. Bundles and minifies all assets
  3. Optimizes images and fonts
  4. Generates service worker for PWA
  5. Outputs production-ready files to dist/
Build output typically includes:
  • HTML, CSS, JS files (minified & hashed)
  • Service worker
  • PWA manifest
  • Static assets (images, fonts, icons)

Preview Production Build

Reference: package.json:10
npm run preview
This starts a local server serving the built files from dist/.
The preview server is for local testing only. Do not use it in production.

Lint Code

Reference: package.json:9
npm run lint
Runs ESLint to check for code quality issues and style violations. Reference: eslint.config.js:7-38

Development Tips

VS Code Extensions

ESLint

ID: dbaeumer.vscode-eslintHighlights linting errors in real-time

Tailwind CSS IntelliSense

ID: bradlc.vscode-tailwindcssAutocomplete for Tailwind classes

ES7+ React Snippets

ID: dsznajder.es7-react-js-snippetsReact code snippets and shortcuts

Prettier

ID: esbenp.prettier-vscodeCode formatting on save

Browser DevTools

Install the React DevTools browser extension to:
  • Inspect component tree
  • View component props and state
  • Profile performance

Testing Realtime Sync

1

Open Multiple Tabs

Open ClipSync in 2+ browser tabs or windows
2

Join Same Session

Use the same session code in all tabs
3

Test Sync

Add clipboard content in one tab and watch it appear instantly in others
4

Test Delete

Delete an item in one tab and verify it disappears in all tabs

Testing Offline Mode

1

Open DevTools

Press F12 to open browser DevTools
2

Simulate Offline

  1. Go to Network tab
  2. Change throttling to “Offline”
  3. Reload the page
3

Verify Offline Banner

You should see the red “You are offline” banner
4

Go Back Online

  1. Change throttling back to “Online”
  2. The app should reconnect automatically
  3. Clipboard history should refetch
Reference: src/App.jsx:40-53

Common Development Issues

Error: Port 5173 is already in useSolution:
# Kill process on port 5173 (macOS/Linux)
lsof -ti:5173 | xargs kill -9

# Or use a different port
npm run dev -- --port 3000
Error: Network errors when loading the appSolution:
  1. Verify .env variables are correct
  2. Check Supabase project is running (not paused)
  3. Ensure you’re using the correct API URL (not the reference ID)
  4. Restart the dev server after changing .env
Error: Changes don’t sync between tabsSolution:
  1. Verify Realtime is enabled for the clipboard table
  2. Check browser console for WebSocket errors
  3. Ensure both tabs are using the same session code
  4. Check Supabase realtime quota (free tier has limits)
Error: File upload returns 403 or 401Solution:
  1. Verify storage bucket clipboard exists
  2. Check bucket policies allow public uploads
  3. Ensure bucket is set to public
  4. Update hardcoded storage URL in src/App.jsx:156

Next Steps

Architecture

Learn about the system architecture

Contributing

Guidelines for contributing to ClipSync

Tech Stack

Deep dive into technologies used

Build docs developers (and LLMs) love