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 with key backup:
- Scan QR code with Pubky Ring mobile app
- No passwords, no tracking
- Your keys, your data
- Sessions stored locally
- Recovery file export - Backup your keys with encrypted recovery files
- 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 (Recommended)
- Download
graphiti-extension.zipfrom the repository - Extract the zip file to a folder (e.g.,
graphiti-extension) - Open Chrome →
chrome://extensions - Enable "Developer mode" (toggle in top-right)
- Click "Load unpacked"
- Select the extracted folder (not the zip file itself)
- Done!
Note: The zip file contains the pre-built extension. You don't need to build it yourself.
Option 2: Build from Source
# Clone the repository
git clone https://github.com/BitcoinErrorLog/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 |
Alt+Shift+A |
Toggle Annotations | Enable/disable annotation button |
Shift+? |
Show Shortcuts | Display keyboard shortcuts help |
Ctrl+Z / Cmd+Z |
Undo | Undo last action (in drawing mode) |
Ctrl+Y / Cmd+Shift+Z |
Redo | Redo last action (in drawing mode) |
Escape |
Close/Exit | Close modal or exit drawing mode |
On Mac, use Option instead of Alt and Cmd instead of Ctrl
Tip: Press Shift+? in the popup or sidepanel to see all available shortcuts!
Activate Drawing Mode:
- Navigate to any webpage
- Press
Alt+D(or click Drawing button 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 star icon
- 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
Edit Your Profile:
- Click the extension icon
- Click "Edit Profile"
- Update your name, bio, avatar, status, and links
- Click "Save Profile" to sync to your homeserver
Export Recovery File (Key Backup):
- Click the extension icon
- Click "Edit Profile"
- Scroll to "Key Backup" section
- Click "Export Recovery File"
- Enter a strong passphrase (min 8 chars, letters + numbers)
- Confirm the passphrase
- File downloads automatically (
pubky-recovery-YYYY-MM-DD.recovery)
Important: Store your recovery file securely! You'll need it and your passphrase to restore your keys if you lose access to your device.
- 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
- 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/BitcoinErrorLog/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 star icon)
- 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
- Documentation: See
/docsfolder for detailed technical documentation - Features: See FEATURES.md for complete feature documentation
- Security: See SECURITY.md for security information
- Contributing: See CONTRIBUTING.md for contribution guidelines
- Changelog: See CHANGELOG.md for version history
- Debug: Use built-in debug panel in extension (click Debug in popup)
Made with care for the decentralized web
Draw freely, annotate wisely, share openly