How Hallmark Performs Pre-Flight Scanning: A Complete Technical Breakdown
Hallmark performs pre-flight scanning by walking the project source tree once, caching static-analysis data to .hallmark/preflight.json, and re-using that cache on subsequent runs unless configuration files have been modified.
This article explains Hallmark's incremental preprocessing system as implemented in the Nutlope/hallmark repository. The pre-flight scanner serves as the foundation for Hallmark's design-system-aware rendering pipeline, enabling fast, deterministic builds through intelligent caching mechanisms.
What Pre-Flight Scanning Accomplishes
When Hallmark first processes a project, it needs to understand the codebase structure before rendering any components. The scanner extracts asset references, component usage patterns, theme settings, and dependency information from files like package.json and tailwind.config.*. Rather than repeating this expensive analysis on every invocation, Hallmark persists results to a hidden cache.
According to skills/hallmark/SKILL.md (lines 177-179), this approach transforms a potentially slow filesystem crawl into a near-instant cache lookup for typical development workflows.
The Four-Stage Pre-Flight Process
Initial Scan and Cache Creation
The first time Hallmark runs against a project, it executes a full scan. The scanner traverses the source tree, reads relevant configuration files, and builds a comprehensive analysis object. This data includes:
- Installed dependencies from
package.json - Tailwind theme customizations
- Image asset references
- Component registration patterns
Once collected, the results are serialized to .hallmark/preflight.json in the project root.
// Simplified pre-flight generation logic
import { readFileSync, writeFileSync } from 'fs';
function runPreflight() {
if (!isCacheStale()) {
console.log('Re-using cached pre-flight data');
return JSON.parse(readFileSync(preflightPath, 'utf8'));
}
console.log('Scanning project for pre-flight data...');
const data = {
dependencies: JSON.parse(readFileSync(pkgPath, 'utf8')).dependencies,
// Additional analysis omitted
};
writeFileSync(preflightPath, JSON.stringify(data, null, 2));
return data;
}
Cache Re-Use on Subsequent Runs
Hallmark optimizes for the common case: multiple invocations against an unchanged codebase. On every run, it compares modification timestamps (mtimes) between the cache and primary configuration files. When package.json and all tailwind.config.* files remain unmodified, Hallmark skips the scan entirely and loads .hallmark/preflight.json directly.
This design prioritizes developer experience—subsequent renders complete in milliseconds rather than seconds.
Cache Invalidation Strategy
Stale caches are automatically detected through timestamp comparison. If either package.json or any Tailwind configuration file has a newer mtime than .hallmark/preflight.json, Hallmark discards the old cache and re-executes the full scan.
// Cache staleness detection
function isCacheStale() {
if (!fs.existsSync(preflightPath)) return true;
const cacheMtime = statSync(preflightPath).mtimeMs;
const pkgMtime = statSync(pkgPath).mtimeMs;
const twMtime = statSync(tailwindPath).mtimeMs;
return pkgMtime > cacheMtime || twMtime > cacheMtime;
}
This ensures that newly added dependencies, theme changes, or style configuration updates immediately propagate through the rendering pipeline without manual cache clearing.
Asset Fallback Resolution
The cached pre-flight data directly powers rendering decisions. As documented in skills/hallmark/references/hero-enrichment.md (line 30), Hallmark implements a three-tier asset resolution strategy:
- Attached image files take priority
- Cached entries from
.hallmark/preflight.jsonserve as secondary sources - Placeholder assets provide graceful degradation
function getHeroImage(assetPath) {
const preflight = JSON.parse(readFileSync('.hallmark/preflight.json', 'utf8'));
if (fs.existsSync(assetPath)) return assetPath;
if (preflight.heroImage) return preflight.heroImage;
return '/assets/placeholder.svg';
}
Critically, Hallmark never overwrites cached assets—the system treats pre-flight data as read-only after initial generation.
Key Source Files and Their Roles
| File | Purpose |
|---|---|
skills/hallmark/SKILL.md |
Defines persistence logic and cache invalidation rules |
skills/hallmark/references/hero-enrichment.md |
Documents asset handling and fallback behavior |
site/js/main.js |
Runtime loader that consumes pre-flight JSON |
package.json & tailwind.config.* |
Configuration sources that trigger cache refresh |
.hallmark/preflight.json |
Generated cache file (runtime only) |
Performance Characteristics
The pre-flight scanning architecture delivers several measurable benefits:
- First run: Full scan overhead (acceptable as one-time cost)
- Typical run: Sub-millisecond cache load
- Cache refresh: Triggered only when configuration changes
- Disk usage: Single JSON file, typically under 50KB
This trade-off—accepting initial scan latency for near-zero recurring cost—aligns with Hallmark's target use case: interactive component rendering during development.
Summary
- Hallmark's pre-flight scanner runs once per project to collect static-analysis data
- Results are cached to
.hallmark/preflight.jsonfor fast subsequent access - Mtime comparison against
package.jsonandtailwind.config.*enables automatic cache invalidation - The cache supports asset fallback chains that never overwrite stored data
- Core logic is defined in
SKILL.md(lines 177-179) with enrichment details inhero-enrichment.md
Frequently Asked Questions
How does Hallmark know when to invalidate the pre-flight cache?
Hallmark compares modification timestamps. If package.json or any tailwind.config.* file has been modified more recently than .hallmark/preflight.json, the cache is discarded and regenerated. This happens automatically without user intervention.
Can I manually clear the pre-flight cache?
Deleting the .hallmark/preflight.json file forces a fresh scan on the next invocation. Hallmark does not provide a dedicated CLI flag for cache management—the system relies on automatic invalidation based on file mtimes.
What happens if a referenced image asset is deleted after the pre-flight scan?
Hallmark's asset resolution implements fallbacks. It first checks for the file directly, then consults the cached pre-flight data, and finally serves a placeholder. The system never corrupts the cache by writing missing asset status back to .hallmark/preflight.json.
Does the pre-flight scanner analyze every file in the project?
The scan targets configuration files and asset references specifically. It does not perform deep static analysis of every source file—instead focusing on package.json, Tailwind configurations, and explicitly referenced resources that influence rendering decisions.
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 →