Skip to main content

Welcome Contributors

Thank you for your interest in contributing to ClipSync! This guide will help you get started with contributing code, reporting issues, and improving documentation.
ClipSync is an open-source project, and we welcome contributions of all kinds - from bug fixes to new features, documentation improvements to performance optimizations.

Getting Started

Before You Begin

1

Set Up Development Environment

Follow the Local Setup Guide to get ClipSync running on your machine.
2

Understand the Architecture

Read the Architecture Documentation to understand how the app works.
3

Check Existing Issues

Look through GitHub Issues to see if your idea or bug is already being discussed.

Fork and Clone

1

Fork the Repository

Click the “Fork” button on the GitHub repository to create your own copy.
2

Clone Your Fork

git clone https://github.com/YOUR_USERNAME/clipsync.git
cd clipsync/client
3

Add Upstream Remote

git remote add upstream https://github.com/ORIGINAL_OWNER/clipsync.git
This allows you to sync with the main repository.

Project Structure

Understanding the codebase structure will help you navigate and contribute effectively:
client/
├── public/                    # Static assets
│   ├── favicon/              # App icons and manifest
│   ├── screenshots/          # App screenshots for PWA
│   └── robots.txt
├── src/
│   ├── assets/               # Images and static resources
│   ├── config/               # Configuration files
│   │   └── supabase.js       # Supabase client setup
│   ├── service/              # Business logic
│   │   └── doc.service.js    # Session management
│   ├── utils/                # Helper functions
│   │   └── index.js          # Utility functions
│   ├── App.jsx               # Main application component
│   ├── App.css               # App-specific styles
│   ├── compressedFileUpload.jsx  # Image compression
│   ├── index.css             # Global styles (Tailwind)
│   └── main.jsx              # Application entry point
├── eslint.config.js          # ESLint configuration
├── tailwind.config.js        # Tailwind CSS configuration
├── vite.config.js            # Vite and PWA configuration
├── package.json              # Dependencies and scripts
└── README.md                 # Project documentation

Key Files

Lines: 706 totalThe main application component containing:
  • State management
  • Supabase realtime subscriptions
  • UI components
  • Clipboard operations
  • File upload logic
Reference: src/App.jsx:1-706
Lines: 7 totalInitializes the Supabase client with environment variables.Reference: src/config/supabase.js:1-7
Lines: 14 totalContains the createSession function for generating random session codes.Reference: src/service/doc.service.js:1-14
Lines: 52 totalConfigures Vite and PWA settings including manifest and service worker.Reference: vite.config.js:1-52

Code Style Guidelines

JavaScript/React Conventions

Use Functional Components
// ✅ Good - Functional component with hooks
export default function App() {
    const [state, setState] = useState("");
    
    useEffect(() => {
        // Side effects here
    }, [dependencies]);
    
    return <div>...</div>;
}

// ❌ Avoid - Class components
class App extends React.Component {
    // ...
}

CSS/Tailwind Conventions

Use Tailwind utilities consistently
// ✅ Good - Organized by category
<button className="
    flex items-center gap-2          // Layout
    px-4 py-2 rounded-lg             // Spacing & Border
    bg-blue-500 text-white           // Colors
    hover:bg-blue-600 active:scale-95 // States
    transition                       // Animation
">
    Click Me
</button>

// ❌ Avoid - Random order
<button className="text-white transition gap-2 px-4 bg-blue-500 rounded-lg flex py-2 items-center">

Supabase Best Practices

Structure queries consistently:
// Always destructure { data, error }
const { data, error } = await supabase
    .from("clipboard")
    .select("*")
    .eq("session_code", sessionCode)
    .order("created_at", { ascending: false });

// Check error first
if (error) {
    toast.error("Error message");
    return;
}

// Then use data
setHistory(data);
Reference: src/App.jsx:68-82
Clean up subscriptions:
useEffect(() => {
    if (!sessionCode) return;
    
    const channel = supabase
        .channel("clipboard")
        .on("postgres_changes", {...}, callback)
        .subscribe();
    
    // Important: Clean up on unmount
    return () => {
        supabase.removeChannel(channel);
    };
}, [sessionCode]);
Reference: src/App.jsx:386-410
Handle file uploads properly:
// Show loading state
const toastId = toast.loading("Uploading file...");

try {
    // Upload with unique filename
    const { data, error } = await supabase.storage
        .from("clipboard")
        .upload(`files/${randomId + file.name}`, file);
    
    if (error) throw error;
    
    // Update toast to success
    toast.success("File uploaded!", { id: toastId });
} catch (error) {
    toast.error("Upload failed", { id: toastId });
}
Reference: src/App.jsx:136-164

Development Workflow

Creating a New Feature

1

Create a Feature Branch

git checkout -b feature/your-feature-name
Branch naming:
  • feature/ - New features
  • fix/ - Bug fixes
  • docs/ - Documentation updates
  • refactor/ - Code refactoring
  • perf/ - Performance improvements
2

Make Your Changes

Write your code following the style guidelines above.Tips:
  • Keep commits focused and atomic
  • Test your changes locally
  • Check console for errors
3

Test Thoroughly

  1. Test in Chrome, Firefox, and Safari
  2. Test on mobile device
  3. Test with multiple browser tabs
  4. Test offline mode
  5. Test file uploads (images and documents)
4

Run Linter

npm run lint
Fix any linting errors before committing.Reference: package.json:9
5

Commit Your Changes

git add .
git commit -m "feat: add search functionality to clipboard history"
Commit message format:
<type>: <description>

[optional body]
Types:
  • feat: New feature
  • fix: Bug fix
  • docs: Documentation
  • style: Formatting
  • refactor: Code refactoring
  • perf: Performance
  • test: Tests
  • chore: Maintenance

Syncing with Upstream

1

Fetch Latest Changes

git fetch upstream
2

Merge Main Branch

git checkout main
git merge upstream/main
3

Rebase Your Feature Branch

git checkout feature/your-feature-name
git rebase main
Resolve any conflicts if they occur.

Testing Approach

Manual Testing Checklist

  • Generate new session
  • Join existing session
  • Session code validation
  • Leave session
  • Session persistence across refreshes
  • Add clipboard content
  • Copy content to clipboard
  • Edit clipboard entry
  • Delete single entry
  • Delete all entries
  • Mark content as sensitive
  • Upload text file
  • Upload image (compression works)
  • Upload document (PDF, Word, etc.)
  • Download/view uploaded file
  • Delete uploaded file
  • File size validation (>10MB rejected)
  • New entries appear in other tabs
  • Deleted entries disappear in other tabs
  • Syncs across different devices
  • Handles network interruptions

Testing Realtime Sync

1

Open Multiple Windows

Open ClipSync in 3+ browser windows/tabs
2

Use Different Browsers

Test in Chrome, Firefox, and Safari simultaneously
3

Test Scenarios

  • Add content in Window A → Should appear in B and C
  • Delete in Window B → Should disappear in A and C
  • Edit in Window C → Should update in A and B
  • Upload file in A → Should appear with link in B and C

Performance Testing

Large History

Test with 100+ clipboard entries
  • Scroll performance
  • Search responsiveness
  • Memory usage

File Uploads

Test file upload performance
  • Compression speed
  • Upload progress
  • Large file handling

Network Conditions

Test under poor network
  • Slow 3G
  • Offline/online transitions
  • High latency

Multiple Devices

Test with many connected devices
  • 5+ devices in same session
  • Sync performance
  • Realtime lag

Submitting Pull Requests

Before Submitting

1

Complete Checklist

  • Code follows style guidelines
  • All tests pass
  • Linter passes (npm run lint)
  • Feature works in Chrome, Firefox, Safari
  • Mobile responsive
  • Dark mode works
  • No console errors
  • Realtime sync tested
2

Update Documentation

If your feature adds new functionality:
  • Update README if needed
  • Add code comments for complex logic
  • Update this contributing guide if workflow changes
3

Push to Your Fork

git push origin feature/your-feature-name

Creating the Pull Request

1

Open PR on GitHub

  1. Go to your forked repository
  2. Click “Compare & pull request”
  3. Select the base repository and branch
2

Write a Clear Title

Format:
feat: Add search functionality to clipboard history
Use prefixes:
  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation
  • refactor: - Code refactoring
  • perf: - Performance improvement
3

Write Detailed Description

Template:
## Description
Brief description of what this PR does.

## Changes
- Added search input to clipboard history
- Implemented real-time filtering
- Added keyboard shortcut (Ctrl+F)

## Screenshots
(If UI changes, add before/after screenshots)

## Testing
- [ ] Tested in Chrome, Firefox, Safari
- [ ] Mobile responsive
- [ ] Works with 100+ items
- [ ] Dark mode support

## Related Issues
Closes #123
4

Request Review

Tag relevant maintainers for review

After Submitting

  • Check for review comments
  • Address requested changes promptly
  • Push additional commits to the same branch
  • Be respectful and open to suggestions

Code Review Guidelines

For Reviewers

  • Code follows style guidelines
  • No obvious bugs or edge cases
  • Error handling is present
  • Performance considerations
  • Security concerns (especially with file uploads)
  • Accessibility issues
Be constructive:
  • Explain why something should change
  • Suggest alternatives
  • Distinguish between required changes and suggestions
Example:
❌ "This code is bad."

✅ "Consider using async/await here instead of .then() 
   for consistency with the rest of the codebase. 
   See src/App.jsx:140 for examples."

For Contributors

Responding to reviews:
  • Thank reviewers for their time
  • Ask questions if feedback is unclear
  • Don’t take criticism personally
  • Mark conversations as resolved after addressing

Common Contribution Areas

Good First Issues

UI Improvements

  • Add animations
  • Improve mobile layout
  • Enhance dark mode colors
  • Better loading states

Feature Enhancements

  • Add keyboard shortcuts
  • Implement drag-and-drop
  • Add more file type support
  • Enhanced search (regex, filters)

Bug Fixes

  • Fix edge cases
  • Improve error messages
  • Handle race conditions
  • Memory leak fixes

Documentation

  • Improve code comments
  • Add setup tutorials
  • Create video guides
  • Translate to other languages

Areas Needing Help

  • Add unit tests (React Testing Library)
  • E2E tests (Playwright/Cypress)
  • Performance benchmarks
  • Accessibility audits

Getting Help

Discord

Join our Discord server for real-time help and discussions

GitHub Discussions

Ask questions and share ideas in GitHub Discussions

Issue Tracker

Report bugs or request features via GitHub Issues

Email

Contact maintainers directly for sensitive topics

Code of Conduct

Our Pledge

We are committed to providing a welcoming and inclusive environment for all contributors.
  • Be respectful and inclusive
  • Accept constructive criticism gracefully
  • Focus on what’s best for the community
  • Show empathy towards others

Recognition

All contributors will be:
  • Added to CONTRIBUTORS.md
  • Mentioned in release notes
  • Given credit in the README
  • Featured on our website (if applicable)
Thank you for contributing to ClipSync! Your efforts help make this project better for everyone.

Next Steps

Local Setup

Get your development environment ready

Architecture

Understand how ClipSync works

Tech Stack

Learn about the technologies used

Build docs developers (and LLMs) love