download 01 / Install
Install Stitch
npm i @vkdatta/stitch -g
Stitch is a build tool for your website. Install it globally, then run it inside the project you build and deploy.
folder_open 02 / Structure
Keep your source organized
project/
├── src/
│ ├── index.html
│ ├── repo.html
│ ├── components/
│ │ ├── header.html
│ │ └── footer.html
│ ├── style.css
│ └── script.js
└── package.json
Stitch reads src/ and writes the deployable site to dist/. Static assets are copied into dist/stitch_assets/. HTML files are processed for Stitch imports.
extension 03 / Components
Consume a component
<stitch src="components/header.html"></stitch>
<main>
<h1>Hello</h1>
</main>
<stitch src="components/footer.html"></stitch>
Paths are resolved relative to the HTML file containing the tag. This lets nested HTML files reference components relative to their own location. The referenced HTML may itself contain additional <stitch src> calls — composition is recursive.
Extension handling
When the referenced path has no extension, Stitch appends .html automatically.
<stitch src="/tags/opening"></stitch>
resolves as: src/tags/opening.html
data_object 04 / Data
Reuse one component with different values
A reusable component declares placeholders:
<stitch reusable></stitch>
<article class="card">
<span>{{icon}}</span>
<h2>{{title}}</h2>
</article>
A caller supplies values through data-* attributes:
<stitch src="components/card.html"
data-title="API"
data-icon="bolt"></stitch>
Stitch produces:
<article class="card">
<span>bolt</span>
<h2>API</h2>
</article>
Substitution happens at build time. The same component can be consumed repeatedly with different values. Substitution may occur in text or attributes. The <stitch reusable> declaration itself never appears in generated HTML.
If a caller supplies data-* values but the target does not declare <stitch reusable>, Stitch pauses the build and asks whether the target should be marked reusable. The user may approve the conversion or abort.
build 05 / Build
Build your site
npx stitch build
The generated dist/ directory is the deployable output. Deploy dist/, not src/. Manual changes to generated files are not durable — always modify src/, then rebuild.
Before → after
Source
<header>
...
</header>
<stitch src="components/footer.html"></stitch>
Generated output
<header>
...
</header>
<footer>
...
</footer>
The browser does not need to understand <stitch>. It receives finished HTML directly with no component-fetching requests and no runtime component parser.
recycling 06 / Component Lifecycle
Only consumed components disappear
A file becomes a consumed component when another HTML file references it through <stitch src="...">. Its contents are embedded into the consumer, so that source component is omitted from dist/.
Unused HTML files and ordinary assets remain. CSS, JavaScript, images, fonts, manifests, JSON, PDFs, and other files are copied — non-HTML static source files go into dist/stitch_assets/.
lightbulb 07 / Why Stitch
Runtime imports are convenient. Build-time imports are faster.
Stitch is a build-time HTML composition processor. It allows a developer to split a large HTML project into modular files, recursively compose those files during the build, and deploy ordinary static HTML.
The problem with runtime composition
A runtime component processor improves source modularity but shifts composition work onto every visitor:
- component HTML may require additional network requests;
- component assembly begins only after the browser starts loading;
- runtime JavaScript must locate and process component tags;
- every visitor repeats the same composition work;
- the deployed website depends on a custom component runtime.
What Stitch gives you
- Easy file management
- Reusable components with build-time data substitution
- Recursive nested composition
- Fast sites — no component-loader JavaScript shipped to visitors
- Host-native routing via
_redirects
Build time may increase slightly because Stitch performs assembly before deployment. That cost happens once per build instead of being paid by every visitor.
SOURCE → ZAP BUILD → DIST → STATIC HOST / CDN → BROWSER
There is no Stitch component loader running in the deployed website.
compare 08 / Comparison
How Stitch compares to other approaches
Rough conceptual ranges assuming the network response has already arrived. Network latency can dominate all of these numbers.
| Method | Assembly happens | Initial network requests | Time to usable page* | Browser CPU | HTML transfer size | Best for |
|---|---|---|---|---|---|---|
| Stitch (build-time) | Once during build | 1 page + assets | ~10–100 ms browser-side assembly | Very low | Higher | Static sites / docs |
| Plain static HTML | Developer manually | 1 page + assets | ~10–100 ms | Very low | Higher | Small / simple sites |
| JS fetch components | Every visitor | Many / additional | ~100–1000+ ms | Medium–high | Lower initial HTML | Rarely ideal for static sites |
| JS <template> cloning | Every visitor | 1 HTML + JS | ~20–300 ms | Medium | Lower HTML | Large dynamic repeated UI |
| Web Components | Every visitor | HTML + JS | ~30–500 ms | Medium | Lower HTML | Reusable interactive UI |
| Server-side includes (SSI) | Every request | 1 page + assets | ~5–100 ms server assembly | Very low | Normal | Traditional server sites |
| SSR / server rendering | Every request or cache miss | 1 page + assets | ~20–500+ ms server work | Low | Normal | Dynamic / user-specific pages |
| Edge rendering | At CDN edge / cache miss | 1 page + assets | ~10–200 ms | Low | Normal | Personalized / global apps |
| Static site generator | Once during build | 1 page + assets | ~10–100 ms | Very low | Higher | Static sites / docs |
| Hybrid: static + JS enhancement | Static at build, dynamic parts runtime | 1 page + JS | ~10–150 ms | Low | Balanced | Modern content-heavy sites |
* Time to usable page is a rough conceptual range assuming the network response has arrived.
account_tree 09 / Architecture
Current Architecture
Stitch is intentionally a build-time system. Its responsibility ends when the final deployable files have been generated.
src/
│
├── modular HTML files
├── nested directories
├── reusable components
├── routed pages
├── CSS / JS / images / fonts / other assets
│
▼
ZAP BUILD
│
├── scan HTML files
├── build dependency graph
├── validate routes
├── detect cycles
├── recursively compose HTML
├── perform data-* substitution
├── strip Stitch directives
├── emit public HTML pages
├── centralize static assets → dist/stitch_assets/
├── rewrite local asset URLs
└── generate host routing rules → dist/_redirects
│
▼
dist/
│
├── index.html
├── routed HTML files
├── stitch_assets/
├── _redirects (when routes exist)
└── host configuration files at root
│
▼
STATIC HOST / CDN → REAL BROWSER NAVIGATION
Stitch does not replace browser navigation. Clicking a normal internal link performs normal navigation. The host serves the destination page. The browser loads and renders that page as an ordinary HTML document.
What Stitch does not need
- no route runtime;
- no route manifest;
- no client-side page fetcher;
- no body replacement;
- no navigation interception;
- no route cache;
- no transition loader;
- no lazy / JIT route resource system;
- no automatically injected Stitch runtime JavaScript.
route 11 / Path Resolution
Component Path Resolution
Stitch resolves component paths relative to the file containing the <stitch src> call, unless the path explicitly indicates the source root.
| Style | Example | Resolution |
|---|---|---|
| Relative | ./header |
Relative to the current HTML file. |
| Parent relative | ../shared/header |
Relative to the parent directory of the current file. |
| Source-root | tags/header |
Resolved from the source root. |
| Explicit source-root | src/tags/header |
The src/ prefix is removed; resolution starts at the source root. |
| Leading slash shorthand | /tags/header |
Source-root shorthand — resolved inside src/, not the OS filesystem root. |
A resolved component path must remain inside the source directory. Any reference that escapes the source root is a hard build error.
repeat 12 / Reusable Components
Reusable Components & Data Substitution
Rules
- substitution happens during the build;
- the same component may be consumed multiple times with different values;
- raw component source must not be permanently cached as one rendered result;
- substitution may occur in text or attributes;
- reusable components may consume other components recursively;
- the reusable declaration is removed from output.
Source files are normally read-only from Stitch's perspective. The explicit user-approved reusable conversion (triggered by the interactive warning) is the only exception.
fork_right 13 / Routing
Static Host Routing
Routing is a deployment concern, not a browser-side Stitch runtime concern.
How explicit routes work
src/fx/fx_counter.html
contains: <stitch route="/fx_counter"></stitch>
Stitch emits:
dist/fx/fx_counter.html
And generates the host rule:
/fx_counter /fx/fx_counter.html 200
Result:
example.com/fx_counter → host routing → dist/fx/fx_counter.html → browser
The route controls the public URL. The source file's relative location controls where the generated HTML is written inside dist/.
_redirects generation
When one or more explicit routes exist, Stitch generates dist/_redirects. Each route uses an HTTP 200 rewrite so the visible URL remains the route while the host serves the generated HTML file.
Route validation rules
- an explicit route must begin with
/; - duplicate route values are forbidden (hard error);
- routes are URL paths, not output directories;
- routed files are standalone public pages.
A routed HTML file cannot be consumed inline through <stitch src>. Stitch emits a warning, removes that reference from the caller, and continues building. The correct way to reach a routed page is ordinary navigation: <a href="/privacy">Privacy</a>.
storage 14 / Static Assets
Centralized Asset Output
Non-HTML static source files are copied into a single owned output directory:
src/style.css → dist/stitch_assets/style.css
src/script.js → dist/stitch_assets/script.js
src/images/logo.svg → dist/stitch_assets/images/logo.svg
Asset URL rewriting
Because assets are centralized during the build, Stitch resolves each local asset reference and rewrites the generated URL to the final public asset path.
<link rel="stylesheet" href="../style.css">
→ <link rel="stylesheet" href="/stitch_assets/style.css">
<img src="../../images/logo.svg">
→ <img src="/stitch_assets/images/logo.svg">
URL suffix preservation
Query strings and fragments are preserved during rewriting: ../style.css?v=3 → /stitch_assets/style.css?v=3
External URLs not rewritten
URLs beginning with https://, http://, //, data:, javascript:, mailto:, tel:, or a bare #fragment are never modified.
Resource-bearing attributes rewritten
link[href] script[src] img[src] source[src] video[src]
video[poster] audio[src] iframe[src] embed[src] object[data]
track[src] input[src] srcset
wrangler.toml is deployment configuration, not a browser asset. It must not be copied into stitch_assets/ — it is preserved at the root of dist/.
output 15 / Output Rules
What Goes Into dist/
- root
src/index.htmlis emitted asdist/index.html; - HTML files with explicit
<stitch route>are emitted at their mirrored relative locations; - consumed component files are not emitted as standalone public HTML;
- non-HTML static assets are copied under
dist/stitch_assets/; - deployment configuration files that must remain at the deployment root are preserved appropriately.
Full example
src/
├── index.html
├── style.css
├── script.js
├── wrangler.toml
├── tags/
│ ├── opening.html
│ └── closing.html
├── pages/
│ ├── privacy.html ← <stitch route="/privacy">
│ └── support.html
└── fx/
├── fx_counter.html ← <stitch route="/fx_counter">
└── fx_clamp.html ← <stitch route="/fx_clamp">
↓ npx stitch build ↓
dist/
├── index.html
├── _redirects
├── wrangler.toml
├── stitch_assets/
│ ├── style.css
│ └── script.js
├── pages/
│ ├── privacy.html
│ └── support.html
└── fx/
├── fx_counter.html
└── fx_clamp.html
error 16 / Validation
Errors & Warnings
| Situation | Severity | Behaviour |
|---|---|---|
<stitch src> target does not exist |
Hard Error | Stop the build; clearly show the caller and resolved missing path. |
| Target exists but is not HTML | Hard Error | Stop — <stitch src> consumes HTML components only. |
| Circular component dependency | Hard Error | Stop and show the complete dependency chain. |
| Path escapes source root | Hard Error | Stop with a path traversal error. |
| Duplicate explicit route | Hard Error | Stop and show both source files. |
Route does not begin with / |
Hard Error | Stop and show the invalid route and source file. |
<stitch src> points to a routed HTML file |
Warning | Warn, drop the inline reference, continue building. |
data-* supplied to non-reusable target |
Interactive Warning | Offer reusable conversion or abort the build. |
Cycle detection
a.html → b.html → c.html → a.html ← HARD ERROR
Stitch stops and reports the full cycle. Recursive composition has a maximum supported nesting depth of 32. Exceeding the limit fails clearly rather than risking uncontrolled recursion.
inventory_2 17 / Package Structure
Recommended Package Shape
├── package.json
├── bin/
│ └── stitch.js
└── lib/
├── index.js
├── utils.js
├── graph.js
└── build.js
Responsibilities
| File | Responsibility |
|---|---|
utils.js |
Stitch tag parsing, path resolution, tag stripping, local asset URL rewriting, and shared helpers. |
graph.js |
HTML discovery, dependency graph construction, route validation, reusable metadata, and cycle detection. |
build.js |
Composition orchestration, public HTML emission, asset copying, and route rule generation. |
index.js |
Package exports and public API. |
bin/stitch.js |
CLI entry point for commands such as npx stitch build. |
There is no need for manifest.js or runtime.js in the current architecture. They represented the removed browser-side route / resource runtime.
timeline 18 / Workflow
Developer Workflow
1. Develop in src/
src/
├── modular HTML
├── nested components
├── reusable templates
├── routed pages
├── CSS / JavaScript / images
└── deployment configuration
2. Build
npx stitch build
3. Deploy dist/
npx wrangler pages deploy dist
4. Browser
https://example.com/
https://example.com/privacy
https://example.com/fx_counter
These are normal browser navigations to ordinary static HTML output.
Developers receive modular source files. Visitors receive already-assembled HTML.
science 19 / Testing
Minimum Regression Tests
Any modification to the build system should test at least:
- simple component composition;
- nested component composition;
- deep recursive component composition;
- the same component consumed from multiple callers;
- the same reusable component consumed with different data values;
- relative component paths;
- source-root component paths;
- leading-slash source-root shorthand;
- missing component errors;
- circular component errors;
- path traversal protection;
- duplicate route errors;
- invalid route errors;
- attempted consumption of routed pages;
- asset copying into
stitch_assets/; - asset URL rewriting from deeply nested HTML files;
- query string and fragment preservation during asset rewriting;
- external URL preservation;
wrangler.tomlpreservation outsidestitch_assets/;_redirectsgeneration when routes exist;- no
<stitch>directives remaining in emitted HTML.
block 20 / Hard Rules
What Stitch Never Does
- leave any
<stitch>directive in generated HTML; - reintroduce a browser-side Stitch component loader;
- reintroduce runtime route processing;
- reintroduce a route manifest for browser navigation;
- fetch component HTML in the deployed browser;
- intercept ordinary navigation merely to implement Stitch routing;
- replace the browser's document body as a routing mechanism;
- hide routed page content while waiting for a removed runtime;
- generate lazy / JIT route loading infrastructure;
- move deployment configuration such as
wrangler.tomlinto browser assets; - copy HTML components into
stitch_assets/; - change external URLs during local asset rewriting;
- allow component paths to escape the source root;
- silently ignore circular dependencies;
- silently resolve duplicate routes;
- remap physical output locations based solely on route values;
- modify source files without explicit behaviour that authorizes it;
- treat
dist/as a second hand-maintained source project; - add architecture unrelated to build-time HTML composition without an explicit requirement.
Stitch should remain small, deterministic, dependency-light, and focused.
MODULAR SOURCE
+
BUILD-TIME COMPOSITION
+
STATIC OUTPUT
+
HOST-NATIVE ROUTING
=
ZAP