How Archify's Live Preview Mode Works with File Watching: A Deep Dive into Real-Time Development
Archify's live preview mode uses a file watcher, incremental rebuild pipeline, and WebSocket server to push HTML updates to the browser instantly when source files change.
Archify, the lightweight static site generator in the tt-a1i/archify repository, ships with a built-in development server that eliminates the manual refresh cycle. When you run npm run preview or archify preview, the tool monitors your project's src/ directory and surfaces changes in the browser within milliseconds — no configuration required.
How the File Watcher Initializes
The live preview starts in scripts/build-start.mjs, where Archify creates a chokidar watcher to monitor the filesystem. Chokidar wraps Node's native fs.watch with cross-platform consistency and reliability.
The watcher targets:
- The
src/directory by default - Any additional folders specified in the
watchconfiguration array
When a file change occurs, the watcher emits a change event with the affected file path:
// scripts/build-start.mjs – file watcher setup
import { watch } from 'chokidar';
const watcher = watch('src/**/*', { ignoreInitial: true });
watcher.on('change', path => {
console.log(`File changed: ${path}`);
// debounced rebuild and WebSocket broadcast follow
});
The ignoreInitial: true option prevents unnecessary rebuilds when the server first starts — only subsequent changes trigger updates.
Incremental Rebuild on File Changes
The watcher callback invokes Archify's incremental rebuild system. Rather than rebuilding the entire site, the pipeline re-renders only the changed file and its dependent pages using the same Markdown-to-HTML transformer employed for static generation.
A debounce timeout guards against excessive work during rapid file saves:
// scripts/build-start.mjs – rebuild orchestration
import { rebuild } from './build.js';
// Inside the change handler:
rebuild(path); // re-render changed file + dependencies
This selective rebuild keeps preview updates fast even for larger projects, as implemented in the tt-a1i/archify source code.
Live Update via WebSocket to Browser
The final piece is bidirectional communication with the browser. The preview server initializes a WebSocket server using the ws package, then broadcasts a reload message to all connected clients:
// scripts/build-start.mjs – WebSocket server
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ server });
// Inside the change handler:
wss.clients.forEach(c => c.send('reload'));
Client-Side Hot Replacement
Each preview page includes a client-side script that receives the reload signal. Rather than triggering a full page refresh, this script fetches the fresh HTML and swaps the <body> element — preserving scroll position and state where possible.
Find this logic in examples/web-app.html:
<!-- examples/web-app.html – live-update client -->
<script>
const ws = new WebSocket('ws://localhost:3000');
ws.onmessage = ev => {
if (ev.data === 'reload') {
fetch(location.href)
.then(r => r.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
document.body.replaceWith(doc.body);
});
}
};
</script>
This DOM diffing approach delivers a near-instant preview experience that feels like native hot module replacement.
Key Files in the Live Preview Pipeline
| File | Purpose |
|---|---|
scripts/build-start.mjs |
Orchestrates the preview server, chokidar watcher, WebSocket broadcast, and incremental rebuild |
examples/web-app.html |
Demonstrates the client-side WebSocket handler that updates the preview |
examples/web-app-rendered.html |
Serves as the rendered output target for the live-preview server |
scripts/run-tests.mjs |
Reuses the watcher infrastructure for integration test automation |
Configuring Watch Directories
By default, Archify watches src/**/*. Override this by adding a watch array to your project configuration:
// archify.config.js
export default {
watch: ['src/**/*', 'content/**/*', 'templates/**/*']
};
Paths are processed as glob patterns through chokidar, supporting exclusion patterns with ! prefixes if needed.
Summary
- File watching uses chokidar in
scripts/build-start.mjsto monitor thesrc/directory and emit change events - Incremental rebuild re-renders only affected files through a debounced
rebuild()call - WebSocket broadcast pushes
reloadmessages to all connected browsers via thewspackage - DOM hot-swap in
examples/web-app.htmlreplaces the<body>without full page refresh for instant feedback
Frequently Asked Questions
What triggers a live preview update in Archify?
Any file creation, modification, or deletion within the watched src/ directory (or configured watch paths) triggers the update chain. The chokidar watcher emits a change event, which debounces into a rebuild and WebSocket broadcast to all connected browsers.
Does Archify live preview support custom watch paths?
Yes. Add a watch array to your Archify configuration with glob patterns for additional directories. The watcher merges these with the default src/**/* pattern before monitoring begins.
Why does Archify use WebSocket instead of Server-Sent Events?
The ws implementation in scripts/build-start.mjs provides bidirectional capability that Archify reserves for future features like browser-to-server logging or configuration override. For the current unidirectional reload signal, either technology would function equivalently.
Can I disable the hot DOM replacement and force full page reload?
The preview server always sends the reload message; the client-side handler in the page template controls the update behavior. To force full refreshes, modify the onmessage handler in your local copy of the preview template to call location.reload() instead of the body replacement logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →