Real-time DOM manipulation with source file synchronization
Edit your UI directly in the browser and have changes automatically sync to source files. Perfect for rapid UI development and bridging the designer-developer workflow.
- Live DOM Editing: Content-editable mode with visual feedback
- Real-time Sync: Changes automatically saved to JSON files (300ms debounce)
- Bidirectional Updates: Edit files externally β browser auto-reloads
- Element Tracking: Unique IDs for precise change tracking
- WebSocket Communication: Instant sync between browser and file system
- VCS-Friendly: Clean JSON diffs for version control
npm installnpm run server
# Or with custom options:
node server.js --port 3001 --dir ./src# Option 1: Python
python -m http.server 8000
# Option 2: Node http-server
npx http-server -p 8000
# Option 3: PHP
php -S localhost:8000http://localhost:8000/test.html
You should see:
- β "Connected - Live editing enabled" status
- π΄ "LIVE EDIT MODE" indicator in top-right
- Blue outlines on hover (editable elements)
- Click any text and start typing
- Watch the console - you'll see sync logs
- Check
src/.live-dom/dom-state.json- your changes are saved! - Edit the JSON file - browser reloads automatically
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<div class="app">
<h1>My Editable App</h1>
<p>Start editing to see changes sync!</p>
</div>
<script type="module">
import { LiveDOMSync } from './live-dom-sync.js';
const sync = new LiveDOMSync({
wsUrl: 'ws://localhost:3001',
sourceFile: 'my-app-state.json'
});
sync.connect().then(() => {
sync.enable();
});
</script>
</body>
</html>const sync = new LiveDOMSync({
wsUrl: 'ws://localhost:3001', // WebSocket server URL
sourceFile: 'dom-state.json', // State file name
debounceMs: 300, // Sync debounce (ms)
ignoredSelectors: [ // Elements to ignore
'[data-live-dom-ignore]',
'script',
'style',
'.no-sync'
]
});
// Connect and enable
await sync.connect();
sync.enable();
// Manual controls
sync.disable(); // Stop tracking
sync.enable(); // Resume tracking
sync.forceSync(); // Immediate sync (bypass debounce)
// Keyboard shortcut: Cmd/Ctrl + S to force sync<!-- Ignore specific elements -->
<div data-live-dom-ignore>
This won't be tracked or synced
</div>
<!-- Or use custom selectors -->
<div class="no-sync">
Also ignored if added to ignoredSelectors
</div>βββββββββββββββββββ WebSocket ββββββββββββββββββββ
β Browser Client β ββββββββββββββββββββββββββ β Sync Server β
β β β β
β - DOM Observer β Mutations (JSON) β - File Watcher β
β - Change Queue β βββββββββββββββββββββββββ β - JSON Writer β
β - UI Overlay β β - Change Notify β
β β State Updates β β
β β ββββββββββββββββββββββββββββ β
βββββββββββββββββββ ββββββββββββββββββββ
β
β
βββββββββββββββ
β JSON Files β
β (versioned)β
βββββββββββββββ
{
"elements": [
{
"selector": "[data-live-id=\"live-0\"]",
"tagName": "h1",
"attributes": {
"class": "hero-title"
},
"styles": {
"color": "blue",
"font-size": "48px"
},
"textContent": "My Awesome Title"
}
],
"timestamp": 1729123456789,
"url": "/index.html",
"syncedAt": "2025-10-23T12:34:56.789Z",
"version": 1
}node server.js [options]
Options:
--port <number> WebSocket port (default: 3001)
--dir <path> Project directory (default: ./src)
--reload-debounce <ms> Delay before reloading on file changes (default: 3000)State files are saved to: <dir>/.live-dom/<sourceFile>
If the page reloads too quickly when you're editing the JSON files, you can increase the reload delay:
# Use the slower preset (5 second delay)
npm run server:slow
# Or customize the delay
node server.js --reload-debounce 5000
# On Windows, use the convenience script
start-slow.batSkip the code-save-reload cycle. Edit directly in browser, changes persist to source.
Designers can tweak the real UI without touching code. Developers get clean JSON diffs.
Feed the state JSON to VLMs for:
- "Make this more spacious" β AI adjusts spacing
- "Match this screenshot" β AI generates changes
- "Add a dark mode toggle" β AI creates variant
Quickly create variations by editing the JSON file:
cp dom-state.json dom-state-variant-a.json
# Edit variant-a.json
# Switch between them to testAll logs are prefixed with [LiveDOMSync] or [Server].
Browser console:
// Check connection status
window.liveDOMSync.ws.readyState
// 0 = CONNECTING, 1 = OPEN, 2 = CLOSING, 3 = CLOSED
// Force sync
window.liveDOMSync.forceSync();
// Capture current state
const snapshot = window.liveDOMSync.captureSnapshot();
console.log(snapshot);Server logs:
# Shows all connections, syncs, and file changes
[Server] Client connected
[Server] Synced state to src/.live-dom/dom-state.json
[Server] - 12 elements tracked
[Server] External change detected in src/.live-dom/dom-state.json"Connection failed"
- Ensure server is running:
npm run server - Check WebSocket URL matches server port
- Check browser console for CORS/mixed-content errors
"Changes not syncing"
- Check element isn't in
ignoredSelectors - Look for console errors
- Try manual sync:
Cmd/Ctrl + S
"Page not reloading on external edits"
- Verify file watcher is active (check server logs)
- Ensure you're editing the correct state file
- Check file permissions
- VLM Integration Layer: Send snapshots to Claude/GPT for AI-assisted editing
- Component Extraction: Detect repeated patterns β suggest components
- Undo/Redo: State history with time-travel debugging
- Collaborative Editing: Multi-user real-time sync
- CSS Variable Support: Track design tokens
- Framework Adapters: React, Vue, Svelte wrappers
- Git Integration: Auto-commit on sync
- Visual Diff Tool: Side-by-side comparison
MIT
This is a rapid prototype built for real-world use. Contributions welcome!
Priority areas:
- VLM integration examples
- Framework adapters
- Performance optimizations
- More robust element selectors
Built for developers who are tired of the UI development cycle.
Start editing. Changes just work. Ship faster. π