A powerful Chrome extension that lets you draw graffiti on web pages, create text annotations, bookmark URLs, and share everything through the decentralized Pubky network. All your data syncs to your personal Pubky homeserver - no third-party tracking!
Draw graffiti directly on any webpage with a persistent canvas overlay:
- 8-color palette for vibrant drawings
- Adjustable brush thickness (2-20px)
- Mouse-based drawing with smooth strokes
- Persistent storage - drawings save automatically per URL
- Pubky sync - backup drawings to your homeserver
- Easy controls - Clear all, save & exit, color picker
Use Cases:
- Annotate screenshots without taking screenshots
- Mark up web pages for design feedback
- Highlight important areas on documentation
- Create visual notes on articles
- Collaborative web graffiti (with shared URLs)
Highlight text and add comments that persist:
- Select any text on a page
- Add detailed comments and notes
- Annotations sync to Pubky homeserver
- View all annotations in the sidebar
- Click annotations to scroll to highlighted text
- Search and filter your annotations
Organize and share your favorite content:
- One-click bookmarking
- Add custom tags to any URL
- Bookmarks sync to Pubky homeserver
- Tag-based discovery
- View bookmarks from people you follow
See what your network is sharing:
- View posts about the current page
- See bookmarks and annotations from followed users
- Chronological feed with real-time updates
- Post your own content with tags
- Engage with your decentralized network
Secure QR-based authentication:
- Scan QR code with Pubky Ring mobile app
- No passwords, no tracking
- Your keys, your data
- Sessions stored locally
- Full control over your identity
Built-in debugging and monitoring:
- Real-time log viewer
- Export logs for troubleshooting
- Filter by log level
- Performance monitoring
- Clear console interface
Option 1: Install from ZIP
- Download
graphiti-extension.zip - Extract to a folder
- Open Chrome β
chrome://extensions - Enable "Developer mode"
- Click "Load unpacked" β Select the
distfolder - Done! π
Option 2: Build from Source
# Clone the repository
git clone https://github.com/yourusername/graphiti.git
cd graphiti
# Install dependencies
npm install
# Build the extension
npm run build
# Load dist/ folder in Chrome at chrome://extensions- Click the Graphiti icon in your Chrome toolbar
- Sign in with Pubky Ring (or skip to use local-only mode)
- Navigate to any website (e.g., https://example.com)
- Try drawing mode - Press
Alt+Dand start drawing!
| Shortcut | Action | Description |
|---|---|---|
Alt+P |
Open Popup | Open the extension popup |
Alt+D |
Toggle Drawing | Enable/disable drawing mode |
Alt+S |
Toggle Sidebar | Open/close the side panel |
Alt+A |
Open Annotations | Jump to annotations tab |
On Mac, use Option instead of Alt
Activate Drawing Mode:
- Navigate to any webpage
- Press
Alt+D(or click π¨ in popup) - A toolbar appears in the top-right corner
Drawing Controls:
- Click and drag to draw
- Color picker - Choose from 8 colors
- Thickness slider - Adjust brush size (2-20px)
- Clear All - Remove all drawings
- Save & Exit - Save and close drawing mode
Important Notes:
- Drawings save automatically per URL
- Return to the page and press
Alt+Dto see your drawing - If signed in, drawings sync to Pubky homeserver
- Works on regular websites (not on chrome:// pages)
Troubleshooting Drawing Mode:
- If it doesn't work, reload the extension at
chrome://extensions - Refresh the webpage you want to draw on
- Make sure you're on a regular HTTP/HTTPS website
- Check console (F12) for "[Graphiti]" logs
Create an Annotation:
- Select text on any page
- Click "Add Annotation" button that appears
- Type your comment
- Click "Post Annotation"
View Annotations:
- Click the extension icon
- Click "View Feed"
- Switch to "Annotations" tab
- Click any annotation to highlight it on the page
Bookmark a Page:
- Navigate to the page
- Click the extension icon
- Click "Bookmark Page" or "β"
- Bookmark saves locally and syncs to Pubky
Remove Bookmark:
- Click the extension icon
- If already bookmarked, click "β Bookmarked"
- Bookmark is removed
Tag a URL:
- Click the extension icon
- Enter tags (comma or space separated)
- Optionally add a comment
- Click "Create Post" or "Tag URL"
Tag Guidelines:
- Maximum 20 characters per tag
- Tags are lowercase
- Use comma or space to separate
- Example:
tutorial, javascript, react
Open Feed:
- Click the extension icon
- Click "π± View Feed"
- Side panel opens on the right
Feed Tabs:
- Posts - All posts about current URL from your network
- Annotations - Text annotations on this page
- Your Content - Your own posts and annotations
- React 18 - UI framework with hooks
- TypeScript - Type-safe development
- Tailwind CSS - Modern utility-first styling
- Vite - Lightning-fast build tool
- Chrome Extension Manifest V3 - Latest extension API
- Pubky Protocol - Decentralized identity and storage
- Vitest - Fast unit and integration testing
graphiti/
βββ manifest.json # Chrome extension manifest
βββ package.json # Dependencies
βββ vite.config.ts # Build configuration
βββ vitest.config.ts # Test configuration
βββ tailwind.config.js # Tailwind config
β
βββ src/
β βββ background/ # Background service worker
β βββ content/ # Content scripts (page injection)
β βββ popup/ # Extension popup UI
β βββ sidepanel/ # Side panel feed UI
β βββ profile/ # Profile viewer pages
β βββ styles/ # Global CSS
β βββ utils/ # Shared utilities
β β βββ __tests__/ # Unit tests
β β βββ crypto.ts # Cryptography, URL hashing
β β βββ storage.ts # Chrome storage wrapper
β β βββ pubky-api-sdk.ts # Pubky homeserver client
β β βββ nexus-client.ts # Nexus API client
β β βββ ... # Other utilities
β βββ test/ # Test setup and mocks
β
βββ docs/ # Documentation
β βββ ARCHITECTURE.md # System architecture
β βββ API_REFERENCE.md # API documentation
β βββ TESTING.md # Test documentation
β βββ UTF16_HASH_ENCODING.md # URL hash spec
β βββ archive/ # Historical dev notes
β
βββ icons/ # Extension icons
βββ dist/ # Build output
Background Service Worker (src/background/background.ts)
- Handles extension lifecycle
- Manages keyboard shortcuts
- Coordinates between popup, content, and sidepanel
- Handles drawing/annotation storage
- Manages Pubky API calls
Content Script (src/content/content.ts)
- Runs on every webpage
- AnnotationManager - text highlighting
- DrawingManager - canvas overlay (NEW!)
- Pubky URL handler - intercepts pubky:// links
Popup (src/popup/)
- Main user interface
- Authentication flow
- Quick actions (bookmark, draw, tag)
- Post creation
- Profile editing
Side Panel (src/sidepanel/)
- Feed viewer
- Post display
- Annotation browser
- Tab-based navigation
All data syncs to your Pubky homeserver:
| Data Type | Homeserver Path | Format |
|---|---|---|
| Profile | /pub/pubky.app/profile.json |
JSON |
| Posts | /pub/pubky.app/posts/ |
Individual post files |
| Bookmarks | /pub/pubky.app/bookmarks/ |
Bookmark references |
| Tags | /pub/pubky.app/tags/ |
Tag metadata |
| Drawings | /pub/graphiti.dev/drawings/ |
Base64 PNG + metadata |
| Annotations | Posts with annotation metadata | JSON |
- Generate Secret - Create 32-byte client secret
- Calculate Channel ID - SHA-256 hash of secret
- Create pubkyauth:// URL - Include relay and capabilities
- Display QR Code - User scans with mobile app
- Poll Relay - Wait for encrypted auth token
- Decrypt Token - Use client secret
- Extract Credentials - Parse pubky ID and capabilities
- Create Session - Store locally
Drawing:
{
id: string; // Unique identifier
url: string; // Page URL
canvasData: string; // Base64 PNG image
timestamp: number; // Creation time
author: string; // Pubky ID
pubkyUrl?: string; // Homeserver URL
}Annotation:
{
id: string;
url: string;
selectedText: string;
comment: string;
startPath: string; // DOM path
endPath: string;
startOffset: number;
endOffset: number;
timestamp: number;
author: string;
postUri?: string;
color: string;
}Bookmark:
{
url: string;
title: string;
timestamp: number;
pubkyUrl?: string;
bookmarkId?: string;
postUri?: string;
}Profile:
{
name: string;
bio?: string;
image?: string; // Avatar URL
status?: string; // Status text + emoji
links?: Array<{
title: string;
url: string;
}>;
}- Node.js 18+ and npm
- Chrome or Edge browser (Chromium-based)
- Pubky Ring mobile app (for authentication)
# Clone repository
git clone https://github.com/yourusername/graphiti.git
cd graphiti
# Install dependencies
npm install
# Development build (with watch mode)
npm run dev
# Production build
npm run build
# Clean build
rm -rf dist && npm run build- Make changes to source files
- Build with
npm run buildornpm run dev - Reload extension at
chrome://extensions - Test your changes
- Check console (F12) for errors
Automated Tests:
# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests with UI
npm run test:uiTests cover:
- Crypto utilities (SHA-256, UTF-16 encoding, Base64URL)
- Storage operations (sessions, bookmarks, tags)
- API integration (Nexus client, Pubky SDK)
- React components (popup, sidepanel)
See docs/TESTING.md for detailed test documentation.
Manual Testing:
- Load extension in Chrome
- Navigate to test page (e.g., https://example.com)
- Test each feature:
- Drawing mode (
Alt+D) - Annotations (select text)
- Bookmarks (click β)
- Tags (add in popup)
- Feed (view sidebar)
- Drawing mode (
Console Debugging:
- Open DevTools (F12)
- Look for "[Graphiti]" log messages
- Check for errors in red
- Use "π§ Debug" panel in popup
New Utility:
- Create file in
src/utils/ - Export functions/classes
- Import in components
- Add types in TypeScript
New Component:
- Create in
src/popup/components/orsrc/sidepanel/components/ - Use React + TypeScript
- Style with Tailwind CSS
- Import and use in parent component
New Storage:
- Add interface to
src/utils/storage.ts - Add CRUD methods
- Test with Chrome storage inspection
New Background Handler:
- Add message type to
src/background/background.ts - Add handler function
- Return appropriate response
- Test with
chrome.runtime.sendMessage
Problem: Drawing mode does nothing
- Solution: Reload extension β Refresh page β Try again
- Check you're on regular website (not chrome://)
- Open console (F12) and look for errors
Problem: Can't see toolbar
- Solution: Check z-index conflicts
- Try on simpler page first
- Make sure drawing mode activated successfully
Problem: Drawings don't save
- Solution: Click "Save & Exit" button
- Don't just close drawing mode
- Check if authenticated for sync
Extension won't load:
- Verify you ran
npm run build - Check you selected
distfolder - Look for errors at
chrome://extensions - Try disabling other extensions
Authentication fails:
- Ensure Pubky Ring app is installed
- Check internet connection
- Try generating new QR code
- Clear extension data and retry
Features not syncing:
- Verify you're signed in
- Check Pubky homeserver is accessible
- Look for sync errors in console
- Check "π§ Debug" panel for details
Annotations not appearing:
- Refresh the page
- Check DOM structure hasn't changed
- Verify annotation was saved (check console)
- Try creating new annotation
Enable detailed logging:
- Open popup
- Click "π§ Debug"
- View all extension activity
- Filter by context or level
- Export logs if needed
Look for these log contexts:
DrawingManager- Drawing featureAnnotationManager- Text annotationsBackground- Service workerStorage- Data persistencePubkyAPISDK- API callsAuth- Authentication
- Drawing viewport-dependent - Drawings match viewport size at creation
- Chrome/Edge only - Manifest V3 required
- No mobile support - Desktop browser extension only
- Content script required - Some pages block content scripts
- Drawing on scroll disabled - Prevents misalignment issues
- Eraser tool for drawings
- Undo/redo for drawings
- Drawing layers
- Touch/stylus support
- Export drawings as images
- Share drawings with specific users
- Collaborative real-time drawing
- Drawing templates and stamps
- Text annotations on drawings
- Voice note annotations
- Rich text in annotations
- Annotation replies/threads
- Mobile app version
- Firefox extension
- Video annotations
- AI-powered features
- Advanced search and filters
- Analytics dashboard
Contributions are welcome! Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test thoroughly
- Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing code style
- Add TypeScript types
- Test all features
- Update documentation
- Write clear commit messages
- Keep PRs focused and small
MIT License - see LICENSE file for details
- Pubky Protocol - Decentralized identity and storage
- Pubky Team - For the innovative protocol and SDK
- Open Source Community - For amazing tools and libraries
- Issues: GitHub Issues
- Docs: See
/docsfolder for detailed documentation - Debug: Use built-in debug panel in extension
If you find Graphiti useful, please star the repository!
Made with β€οΈ for the decentralized web
π¨ Draw freely, annotate wisely, share openly