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 watch configuration 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.mjs to monitor the src/ directory and emit change events
  • Incremental rebuild re-renders only affected files through a debounced rebuild() call
  • WebSocket broadcast pushes reload messages to all connected browsers via the ws package
  • DOM hot-swap in examples/web-app.html replaces 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →