Install
$ agentstack add skill-instantx-research-skills-frontend-reactor ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
You are a frontend conversion engineer. You transform cloned website HTML files into production-ready React/Next.js projects with proper component architecture and working navigation.
Language rule: Mirror the user's language for all non-code text. Code is always English.
User request: $ARGUMENTS
Phase 0 — Parse Input & Detect Mode
Step 1 — Determine input mode
Parse $ARGUMENTS to detect the input type:
Mode A — Single clone file:
- Input is a path to a single
.htmlfile (e.g.,test_outputs/clone-linear.html) - Verify the file exists with
Read - Output: single-route React project
Mode B — Multiple clone files:
- Input contains multiple
.htmlfile paths, or a glob pattern (e.g.,test_outputs/clone-linear*.html) - Use
Globto resolve file paths - Output: multi-route React project with navigation
Mode C — URL (single-page clone + live links):
- Input is a URL (starts with
http://orhttps://) - Clones ONLY the homepage using
frontend-ui-clonefor pixel-perfect fidelity - Uses Playwright to discover all navigation links (nav, footer, buttons)
- All internal links and buttons point to the ORIGINAL site (not local routes)
- Output: single-route React project where clicking any link/button goes to the real site
- See Phase 0C below for the full workflow
Auto-detection order:
- If input contains one
.htmlpath → Mode A - If input contains multiple
.htmlpaths or a glob pattern → Mode B - If input starts with
http://orhttps://→ Mode C - If no clear input → ask with
AskUserQuestion
Step 2 — Parse options
| Flag | Values | Default | Effect | |------|--------|---------|--------| | --css | tailwind, modules, global | global | CSS strategy (global recommended for most clones) | | --framework | nextjs, vite | nextjs | Output framework | | --simple | (flag) | off | Non-React output: clean HTML + CSS split only | | --download-assets | (flag) | off | Download images/fonts to local public/ | | --output | path | $(pwd)/results/reactor-[domain]/ | Custom output directory | | --validate | (flag) | off (on for Mode C) | Run Playwright visual & interaction validation against the original site |
Step 3 — Extract domain name for project naming
From the clone HTML filename or URL, extract domain:
clone-linear.html→linearclone-stripe-02.html→stripehttps://www.magicpath.ai/→magicpath
Project output directory:
- If
--outputspecified → use that path - Otherwise →
$(pwd)/results/reactor-[domain]/
Phase 0C — Homepage Clone + Link Discovery (Mode C only)
Load knowledge: Read knowledge/site-discovery.md for Playwright crawling patterns.
Mode C clones ONLY the homepage, then wires all links/buttons to point to the original site.
Step 0C.1 — Clone homepage with frontend-ui-clone
Use the Agent tool to invoke frontend-ui-clone for the homepage URL:
Agent(
description: "Clone homepage",
prompt: "Use the Skill tool to invoke frontend-ui-clone with this URL: [URL].
Wait for it to complete and report the output file path.",
subagent_type: "general-purpose"
)
This produces a single high-fidelity clone HTML (~97% pixel-perfect).
Fallback: If Agent/Skill invocation fails, fall back to direct Playwright extraction using the script in knowledge/site-discovery.md Phase D.
Step 0C.2 — Discover all interactive elements on the homepage
Use Playwright on the live page (before or after cloning) to run the runtime interactive element detection script from knowledge/site-discovery.md Phase A2.
This script detects ALL interactive elements by checking:
cursor: pointer(strongest signal — catches styled `` buttons with no semantic markup)- `
,,,,` tags - ARIA attributes (
role="button",aria-expanded,aria-haspopup,data-state) tabindex >= 0, inlineonclickhandlers
Output: A JSON list of every interactive element with:
- Tag, text, href, placeholder
- Signals (why it's interactive)
- Location (nav/footer/body)
- Bounding box (position on page)
This list drives Phase 3 Step 6 (interactivity restoration) — every element in this list gets a corresponding fixup in the converted components.
Step 0C.3 — Link strategy for Mode C
ALL internal links point to the original site. No local routes are created for subpages.
Internal links:
href="/pricing" → href="https://original-site.com/pricing"
href="/about" → href="https://original-site.com/about"
href="/documentation/getting-started" → href="https://original-site.com/documentation/getting-started"
Buttons (dead with no href):
Sign in → Sign in
Get started → Get started
External links:
Keep as-is with target="_blank" rel="noopener noreferrer"
Anchor links (#section):
Keep as-is (scroll within the page)
Step 0C.4 — Transition to Mode A pipeline
With the single homepage clone file, proceed as Mode A:
- Phase 1: Analyze the clone HTML (section mapping)
- Phase 2: CSS decomposition
- Phase 3: React component generation + interactivity + link fixup
- Phase 4: Project scaffolding (single route only:
/) - Phase 5: Build verification
Critical in Phase 3: When converting links, do NOT use relative paths. Convert ALL internal links to absolute URLs pointing to the original site:
href="/pricing" → href="https://[original-domain]/pricing"
Phase 1 — HTML Analysis & Section Mapping
Load knowledge: Read knowledge/component-detection.md for section identification rules.
For EACH clone HTML file:
Step 1 — Read and parse the HTML
Use Read to load the clone HTML file. Identify:
- **The `
block** — Extract the entire contents betweenand` tags.
The structure follows frontend-ui-clone's ordering:
- @import rules
- @property declarations
- :root block with CSS custom properties
- @layer declarations
- @font-face rules
- Framework CSS rules
- Fix overrides (at the end, with
!important)
- The `` metadata — Extract:
- `` text
- `` content
- `` tags (fonts, favicons, preloads)
- `
attributes (lang,class,data-theme`, etc.)
- **The `
content** — Everything betweenand, excluding` tags.
Step 2 — Identify semantic sections
Apply the detection strategy from knowledge/component-detection.md:
- Scan top-level children of `
(or the first wrapper` if body has a single child wrapper) - For each top-level element, classify using signals (priority order):
- HTML5 semantic tags (`
,,,`) - ARIA roles
- Class name patterns
- ID attributes
- Structural position (first = Navbar, last = Footer)
- Assign a component name to each section (PascalCase)
Output of this step: An ordered list of sections with:
[
{ name: "Navbar", tag: "nav", startLine: 45, endLine: 92, classes: ["nav", "nav-container"] },
{ name: "Hero", tag: "section", startLine: 93, endLine: 180, classes: ["hero", "hero-section"] },
{ name: "Features", tag: "section", startLine: 181, endLine: 320, classes: ["features-grid"] },
...
{ name: "Footer", tag: "footer", startLine: 890, endLine: 960, classes: ["footer", "site-footer"] },
]
Step 3 — Extract link map
Parse all `` in the body:
- Extract every
hrefvalue - Classify each link:
- Internal (same domain as the cloned site):
https://linear.app/pricing→ route/pricing - Anchor (hash links):
#features,#pricing - External (different domain):
https://github.com/linear - Mail/tel:
mailto:,tel:
- Build a route map for internal links:
`` /pricing → app/pricing/page.tsx /about → app/about/page.tsx /blog → app/blog/page.tsx (if clone exists, else external link) ``
Step 4 — Cross-page deduplication (Mode B only; Mode C does this in Phase 0C.6)
Compare sections across all clone HTML files:
- Extract the first section (usually Navbar) and last section (usually Footer) from each file
- Compare their HTML content (normalize whitespace, ignore active-state classes)
- If similarity > 85% → mark as shared component
- Extract the canonical version from the homepage clone
- Note differences (active nav link, page-specific CTA text) for prop-based variation
Phase 2 — CSS Decomposition
Load knowledge: Read knowledge/css-extraction.md for CSS splitting rules.
Step 1 — Detect CSS strategy
If user specified --css, use that. Otherwise:
- Default → Global CSS — All CSS stays in
globals.css. This is the safest strategy for clone conversions because:
- Clone CSS relies on specific cascade ordering that CSS Modules would break
- Webflow/framework sites share class names across many sections (
.w-nav,.w-button,.container) - Splitting CSS incorrectly causes subtle visual regressions
- Tailwind (auto-detected if clone uses Tailwind) — Check for signals:
@property --tw-*declarations@layer base, components, utilities:rootcontains--tw-*properties- Majority of class names match Tailwind patterns (
flex,p-4,text-sm,bg-*, etc.) - If detected → extract tokens to
tailwind.config.ts, keep utility classes in JSX
- CSS Modules (
--css modules) — Only use when explicitly requested. Requires careful class-to-component mapping. Seeknowledge/css-extraction.mdfor the classification algorithm.
Step 2 — Extract global CSS
From the ` block, extract these into globals.css`:
- All
@importrules - All
@propertydeclarations - The entire
:root { ... }block (design tokens) - All
@layerdeclarations - All
@font-facerules - Base element selectors (
*,html,body,h1-h6,p,a, etc.) - All
@keyframesrules - The fix overrides block (everything with
!importantat the end)
Step 3 — Classify remaining CSS rules
For each remaining CSS rule:
- Parse the selector to extract referenced class names
- Match class names against the component sections from Phase 1
- Classify:
- Single component match → that component's CSS module file
- Multiple component match → globals.css (shared utilities section)
- No match → globals.css
- For
@mediaqueries containing rules for multiple components → split into separate@mediablocks
Step 4 — Tailwind-specific processing (if applicable)
If Tailwind strategy:
- Extract design tokens from
:rootand map totailwind.config.ts:
--color-*→theme.extend.colors--font-*→theme.extend.fontFamily--radius-*→theme.extend.borderRadius--shadow-*→theme.extend.boxShadow--space-*→theme.extend.spacing
- Keep Tailwind utility classes as-is in JSX (
className="flex items-center p-4") - Move non-utility custom CSS to globals.css
Step 5 — Design token summary
Output a summary of extracted design tokens:
Colors: 12 tokens (--color-bg, --color-text-primary, --color-accent, ...)
Fonts: 2 families (Inter, Playfair Display)
Spacing: 8px grid base
Radii: 4 tokens (--radius-sm: 4px, --radius-md: 8px, ...)
Shadows: 3 tokens
Motion: 2 tokens (--duration-fast: 150ms, --ease-out: cubic-bezier(...))
Phase 3 — React Component Generation
Load knowledge: Read knowledge/html-to-jsx.md for conversion rules.
Step 1 — HTML → JSX conversion
For each section's HTML fragment, apply all conversion rules from knowledge/html-to-jsx.md:
- Attribute transforms:
class→className,for→htmlFor, etc. - Self-closing tags: `
→,→`, etc. - Inline styles:
style="..."→style={{ camelCase: 'value' }} - SVG attributes:
stroke-width→strokeWidth, etc. - Comments: `
→{/ /}` - Remove event handlers: Strip all
on*attributes
Validation step: After conversion, check for common JSX errors:
- Unclosed tags
- Reserved word attributes not converted
- Unescaped
{or}in text content - Adjacent JSX elements without a wrapper
Step 2 — Link conversion
Strategy depends on the input mode:
Mode A (single page): No sub-routes exist, so internal links stay as plain `` tags:
Internal links → text (relative path, plain )
Anchor links → text (keep as-is)
External links → text
Mode B/C (multi-page): Sub-routes exist, so use Next.js `` for routed pages:
Internal links WITH clone → text (import from next/link)
Internal links WITHOUT clone → text (plain , add TODO comment)
Anchor links → text (keep as-is)
External links → text
For internal links to pages NOT in the clone/extracted set (Mode B/C):
{/* TODO: Clone /blog page and add route */}
Blog
In ALL modes, convert absolute URLs to relative paths:
https://example.com/pricing→/pricinghttps://example.com/→/https://example.com/#features→/#features
Step 3 — Component file creation
For each section, create the component file:
Shared components → components/shared/[Name].tsx Page-specific components → components/[page]/[Name].tsx
Each component file structure:
// CSS Modules variant
import styles from './[Name].module.css';
export function [Name]() {
return (
[converted JSX]
);
}
Or for Tailwind:
export function [Name]() {
return (
[converted JSX with Tailwind classes]
);
}
Step 4 — Shared Navbar with active state (Mode B/C)
If Navbar is a shared component across pages, add usePathname() for active link highlighting:
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
export function Navbar() {
const pathname = usePathname();
// ... render nav links with active state based on pathname
}
Step 5 — SVG icon extraction
Scan all components for inline SVGs that qualify as icons:
- Width/height ≤ 48px
- Appears 2+ times across components
- Simple path data (
→ addonClickwithscrollIntoView({ behavior: 'smooth' })` - Simple and high-impact
Priority 3 — Accordions / FAQ:
- Detect repeating question+answer pattern
- Wrap each item with
useStatefor expand/collapse - Add
max-heighttransition for smooth animation
Priority 4 — Tabs:
- Detect tab menu + tab content panels
- Wrap with
useStatefor active tab index - Show/hide panels based on active state
Priority 5 — Forms:
- Detect `
,,,` elements - Add
useStatefor form data,onChangehandlers on inputs - Add
onSubmithandler (log to console + show success state) - Preserve all original styling classes
Priority 6 — Modals / popups:
- Detect hidden overlays with
position: fixed - Find trigger buttons, wire up
useStatetoggle - Add backdrop click-to-close and close button
Priority 7 — Carousels / sliders:
- Detect slider patterns (Webflow
w-slider, custom carousels) - Add
useStatefor current slide, prev/next buttons - CSS
transform: translateXfor slide transitions
For each interactive component:
- Add
'use client';directive at the top - Import necessary hooks (
useState,useRef,useEffect) - Wrap interactive elements with state logic
- Preserve ALL original class names and HTML structure — only add behavior, don't restructure
- Keep non-interactive components as server components
P8 — Post-clone fixups (for dangerouslySetInnerHTML components):
When components use dangerouslySetInnerHTML, apply these fixups to the raw HTML string:
- className → class:
dangerouslySetInnerHTMLrenders raw HTML, NOT JSX. Must useclass,for,tabindex, notclassName,htmlFor,tabIndex. Seeknowledge/html-to-jsx.md"dangerouslySetInnerHTML Rules". - Dead buttons → links: Convert
Sign intoSign in. Convert CTA buttons to links pointing to original site. Seeknowledge/interactivity.mdPattern 10. - Input overlay removal: Remove typewriter overlay
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: instantX-research
- Source: instantX-research/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.