HolyStitch converts your Stitch screens without spending a single AI token on the conversion itself. Everything from HTML fetching to file writing is deterministic code — no LLM calls, no guesswork.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/BaselAshraf81/holystitch/llms.txt
Use this file to discover all available pages before exploring further.
Input and output
Input:RawScreen[]
Each screen is a plain object with three fields:
fetchScreens.
Output: ConvertStitchOutput
The nine-step pipeline
Resolve screens
The Stitch SDK sometimes returns a signed download URL in the All screens are resolved in parallel via
html field instead of raw HTML. The resolver detects this by checking whether the string starts with http:// or https://, then fetches the real content before any other step touches it.Promise.all.Parse HTML comment boundaries → component slices
parseStitchHtml reads the body HTML and scans for <!-- ComponentName --> markers using an AST built by htmlparser2. Each marker claims the next sibling block element as a named component slice, producing a full component tree.See Component extraction for the full algorithm.Extract fonts and custom CSS from `<head>`
The parser scans the
<head> for Google Fonts <link> tags and inline <style> blocks. Font links are split into two buckets:- Text fonts (Inter, JetBrains Mono, etc.) — eligible for
next/font/googleoptimization in Next.js - Icon fonts (Material Symbols, Material Icons) — always loaded via CSS
@importbecausenext/font/googledoes not support them
<style> blocks is accumulated across all screens and written into globals.css / src/index.css.Extract Tailwind `theme.extend` config
Stitch embeds a
tailwind.config object in a <script id="tailwind-config"> tag. The parser extracts theme.extend, plugins, and darkMode using balanced-bracket parsing (not JSON.parse — the config uses JS object syntax, not strict JSON).When multiple screens are processed, color token values are compared across screens. Conflicts are recorded as warnings:Compile each component's HTML to JSX
compileHTMLToJSX applies a series of deterministic transforms to each component’s HTML slice:- Attributes renamed (
class→className,for→htmlFor, etc.) - Event handlers camelCased (
onclick→onClick) - Void elements self-closed (
<img>,<br>,<input>, etc.) - Inline
stylestrings converted to JS objects - Material Symbols icon-name text stripped
<pre><code>curly braces escaped as HTML entities
Wrap each slice in a React component file
Each compiled JSX slice is wrapped in a
.tsx / .jsx file with:- A
'use client';directive if the component contains event handlers or<button>elements (Next.js only) importstatements for any child components- An empty typed
interface ComponentNameProps {}with prop hints surfaced as comments - A named default export function
Generate page files and all framework config files
For each screen, a page file is generated that imports its root components and renders them. The page body uses
pageBodyHtml — the original body HTML with root component blocks replaced by <ComponentName /> placeholders.Config files generated alongside components and pages:| File | Description |
|---|---|
package.json | Dependencies for Next.js 14 or Vite 5 |
tailwind.config.js | Extracted theme.extend, plugins, darkMode |
postcss.config.js | Tailwind + autoprefixer |
tsconfig.json | TypeScript config (when language is typescript) |
next.config.js | Minimal Next.js config (Next.js only) |
app/layout.tsx | Root layout with next/font/google imports (Next.js only) |
app/globals.css | Tailwind directives + font imports + custom CSS |
src/App.tsx | Hash-based router with all page routes (Vite only) |
src/main.tsx | ReactDOM entry point (Vite only) |
For Vite projects, routing is hash-based (
/#/route-name). src/App.tsx maps every route to its page component using a plain object lookup — no router library needed.Write everything to disk
writeProjectFiles writes all accumulated ProjectFile objects to the output directory. It creates intermediate directories automatically and supports base64-encoded binary files.stitch-source/<screen-name>.html as a reference file for post-conversion AI work.Write `project-context.md`
The final step writes
project-context.md to the output directory. This file is designed to be read by an AI assistant in a follow-up session and contains:- A source map linking each route to its
stitch-source/*.htmlreference file - A fix checklist (unclosed tags, style objects, routing, font token normalization)
- A full component list with file paths
- All structural warnings generated during conversion
Why no AI tokens are needed
Every transform in the pipeline is a deterministic algorithm:- Attribute renaming — a static lookup table (
ATTR_MAP) - Style conversion — a balanced-bracket CSS parser
- Component detection — an AST scan for uppercase HTML comments
- Shared component deduplication — Jaccard similarity over token sets
- Tailwind config extraction — balanced-bracket object parsing
- File writing —
fs.writeFilewith directory creation
href="#" links), project-context.md documents exactly what needs fixing and where to find the source HTML.
Shared component detection
When the same component name appears on multiple screens, HolyStitch computes Jaccard similarity over word tokens from both HTML strings:- Similarity ≥ 0.7 — the component is treated as shared; the existing file is reused
- Similarity < 0.7 — the component is treated as a different widget that happens to share a name; a screen-scoped copy is created as
ComponentName + PascalCasedScreenName, and a warning is emitted