npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

website-clone-skill

v1.0.4

Published

Install the website-clone skill for Claude Code, Codex CLI, opencode, Cursor, and Antigravity

Readme

Website Clone Skill

npm version npm version npm version

A skill for Claude Code, Codex CLI, opencode, Cursor, and Antigravity that enables cloning any website into a Next.js App Router project.

Packages

| Package | Version | Description | |---------|---------|-------------| | website-clone-skill | 1.0.3 ✅ | Recommended - CLI installer with latest fixes | | create-website-clone | 1.3.1 ⚠️ | Legacy CLI installer (outdated) | | website-clone-plugin | 1.0.2 | Core plugin with Playwright/Firecrawl utilities |

Note: website-clone-skill is the actively maintained package with the latest fixes including:

  • Node.js 21+ localStorage error fix
  • Automatic CSS url() path rewriting for fonts/assets

Quick Install (Recommended)

# Recommended (latest fixes)
npx website-clone-skill

# Legacy (may have issues on Node.js 21+)
npx create-website-clone

This will:

  1. Ask which editor to install for (Claude Code, Codex CLI, opencode, Cursor, Antigravity)
  2. Copy skill files to the correct location
  3. Run npm install for dependencies
  4. Install Playwright Chromium browser
  5. Prompt for your Firecrawl API key and save it to your config file (and shell config when possible)

That's it! Restart your editor and ask: "Clone https://example.com"


Architecture

User: "Clone https://example.com"
          │
          ▼
┌─────────────────────────────────────────────────────────────┐
│                     Claude (You)                             │
│                                                              │
│  0. scaffoldProject() ─► Next.js + shadcn boilerplate        │
│  1. renderPageWithExtraction() ─► Playwright renders HTML    │
│  2. scrapePage() ──────► Firecrawl + download assets         │
│  3. Analyze HTML + screenshot ─► Identify sections           │
│  4. Generate TSX ──────► Write React components              │
│  5. Write files ───────► Save to output directory            │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Key insight: Claude IS the LLM. The skill provides:

  • Playwright for rendering (handles SPAs, JavaScript)
  • Firecrawl for clean HTML extraction
  • Asset downloading utilities
  • File writing utilities

Claude handles:

  • Analyzing the DOM structure
  • Identifying visual sections
  • Generating TSX components
  • Writing Tailwind CSS

Manual Installation

Claude Code

git clone https://github.com/improdead/website-cloning-skills.git
cp -r website-cloning-skills/skill ~/.claude/skills/website-clone
cd ~/.claude/skills/website-clone && npm install && npx playwright install chromium

opencode

git clone https://github.com/improdead/website-cloning-skills.git
cp -r website-cloning-skills/skill ~/.config/opencode/skills/website-clone
cd ~/.config/opencode/skills/website-clone && npm install && npx playwright install chromium

Codex CLI

git clone https://github.com/improdead/website-cloning-skills.git
cp -r website-cloning-skills/skill ~/.codex/skills/website-clone
cd ~/.codex/skills/website-clone && npm install && npx playwright install chromium

Cursor

git clone https://github.com/improdead/website-cloning-skills.git
mkdir -p .cursor/rules
cp website-cloning-skills/skill/SKILL.md .cursor/rules/website-clone.md
cp -r website-cloning-skills/skill ./website-clone-skill
cd website-clone-skill && npm install && npx playwright install chromium

Antigravity (workspace)

git clone https://github.com/improdead/website-cloning-skills.git
cp -r website-cloning-skills/skill .agent/skills/website-clone
cd .agent/skills/website-clone && npm install && npx playwright install chromium

Antigravity (global)

git clone https://github.com/improdead/website-cloning-skills.git
mkdir -p ~/.gemini/antigravity/global_skills
cp -r website-cloning-skills/skill ~/.gemini/antigravity/global_skills/website-clone
cd ~/.gemini/antigravity/global_skills/website-clone && npm install && npx playwright install chromium

Uninstall

# Claude Code
rm -rf ~/.claude/skills/website-clone

# opencode
rm -rf ~/.config/opencode/skills/website-clone

# Codex CLI
rm -rf ~/.codex/skills/website-clone

# Cursor
rm -f .cursor/rules/website-clone.md
rm -rf ./website-clone-skill

# Antigravity (workspace)
rm -rf .agent/skills/website-clone

# Antigravity (global)
rm -rf ~/.gemini/antigravity/global_skills/website-clone

Firecrawl API Key

If you skipped the API key prompt during install, set it manually:

# macOS/Linux
export FIRECRAWL_API_KEY="fc_your_key"

# Save to config file used by the skill
mkdir -p ~/.config/website-clone-skill
echo 'FIRECRAWL_API_KEY="fc_your_key"' >> ~/.config/website-clone-skill/.env

# Add to shell config for persistence
echo 'export FIRECRAWL_API_KEY="fc_your_key"' >> ~/.zshrc

# Windows
setx FIRECRAWL_API_KEY "fc_your_key"
# Or add to: %APPDATA%\website-clone-skill\.env

Get your key at https://firecrawl.dev

Quickstart

  1. Run npx website-clone-skill and follow the prompts
  2. Restart your editor
  3. Ask: "Clone https://example.com"
  4. Run the clone:
cd output
npm install
npm run dev

Usage

Claude Code / opencode

  • Trigger the skill with /website-clone or “Clone https://example.com”.
  • Follow the step-by-step guides in workflow/ (start at step0-scaffold.md).
  • The skill writes a Next.js project to your chosen output directory.

Cursor

  • Paste SKILL.md into .cursor/rules/website-clone.md (see Installation).
  • Ask: “Clone https://example.com” or “Use website-clone skill”.
  • If Cursor doesn’t auto-open linked files, open the referenced workflow/ or rules/ file manually.

Antigravity

  • Start a conversation and mention the skill: “Use the website-clone skill to clone https://example.com”.
  • Antigravity will load SKILL.md and follow linked files in workflow/ and rules/.

Programmatic usage

See the Example Usage section below for a full script.

How It Works

When a user asks to clone a website, Claude:

  1. Scaffolds a Next.js 15 + Tailwind 4 + shadcn/ui project
  2. Renders the page using Playwright (captures JavaScript-rendered content)
  3. Scrapes assets and HTML using Firecrawl
  4. Analyzes the HTML + screenshot to identify sections
  5. Generates TSX components for each section
  6. Writes files to the output directory

Plugin API

renderPage(options)

Renders a page with Playwright and captures HTML, screenshot, and network requests.

import {renderPage} from './plugin';

const result = await renderPage({
  url: 'https://example.com',
  viewport: {width: 1440, height: 900},
  waitUntil: 'networkidle',
  extraWaitMs: 2000,
});

// result.html - Full rendered HTML
// result.screenshot - Buffer with PNG screenshot
// result.requests - Array of network requests

scrapePage(options)

Scrapes assets using Firecrawl and downloads images/fonts.

import FirecrawlApp from '@mendable/firecrawl-js';
import {scrapePage, createProjectStructure, getFirecrawlApiKey} from './plugin';

const firecrawl = new FirecrawlApp({apiKey: getFirecrawlApiKey()});

await createProjectStructure('./output');

const result = await scrapePage({
  url: 'https://example.com',
  renderResult: renderResult,
  firecrawlClient: firecrawl,
  outputDir: './output',
});

// result.assets - Downloaded assets with local paths
// result.html - Playwright HTML
// result.firecrawlHtml - Firecrawl clean HTML

getFirecrawlApiKey()

Loads the Firecrawl API key from the environment or the skill config file.

import {getFirecrawlApiKey} from './plugin';

const apiKey = getFirecrawlApiKey();

writeFile(path, content)

Writes a file to disk, creating directories as needed.

import {writeFile} from './plugin';

await writeFile('./output/src/components/hero.tsx', heroTsxCode);

saveScreenshot(buffer, path)

Saves a screenshot buffer to a file.

import {saveScreenshot} from './plugin';

await saveScreenshot(result.screenshot, './output/screenshot.png');

renderPageWithExtraction(options)

Enhanced render that automatically extracts fonts and colors.

import {renderPageWithExtraction} from './plugin';

const result = await renderPageWithExtraction({
  url: 'https://example.com',
  viewport: {width: 1440, height: 900},
});

// All standard render results plus:
// result.fonts.googleFontsImports - Google Fonts URLs found
// result.fonts.fontFamilies - Font family names used
// result.colors.hex - All hex colors found
// result.colors.rgb - All RGB colors found
// result.colors.cssVariables - CSS custom properties for colors
// result.stylesheets - All CSS content captured

extractComputedStyles(options)

Extract exact computed CSS values from rendered elements.

import {extractComputedStyles} from './plugin';

const styles = await extractComputedStyles({
  url: 'https://example.com',
  selectors: ['h1', '.hero-button', 'nav a'],
  properties: ['color', 'background-color', 'font-family', 'font-size'],
});

// Returns: [{ selector: 'h1', styles: { 'font-size': '160px', 'color': 'rgb(60, 47, 18)' } }]

extractFonts(html, css?)

Extract font information from HTML/CSS content.

import {extractFonts} from './plugin';

const fonts = extractFonts(htmlContent, cssContent);
// fonts.googleFontsImports - Google Fonts import URLs
// fonts.fontFamilies - Font family names (filtered)
// fonts.fontFaceDeclarations - @font-face rules

extractColors(content)

Extract all color values from content.

import {extractColors} from './plugin';

const colors = extractColors(htmlContent + cssContent);
// colors.hex - Hex colors like #F5F3ED
// colors.rgb - RGB/RGBA colors
// colors.hsl - HSL/HSLA colors
// colors.cssVariables - CSS custom properties that contain colors

compareScreenshots(original, clone, diffPath?)

Compare two screenshots for visual similarity.

import {compareScreenshots} from './plugin';

const comparison = await compareScreenshots(
  originalBuffer,
  cloneBuffer,
  './screenshots/diff.png'
);

// comparison.similarity - 0 to 1, where 1 is identical
// comparison.diffPixels - Number of different pixels
// comparison.totalPixels - Total pixels compared
// comparison.diffImagePath - Path to diff image (if generated)

Note: Requires optional pixelmatch and pngjs packages.

generateThemeBlock(options)

Generate Tailwind v4 @theme block from extracted design tokens.

import {generateThemeBlock} from './plugin';

const themeBlock = generateThemeBlock({
  fonts: extractedFonts,
  colors: extractedColors,
});
// Returns CSS @theme block for globals.css

generateGoogleFontsUrl(fonts)

Generate a Google Fonts import URL.

import {generateGoogleFontsUrl} from './plugin';

const url = generateGoogleFontsUrl([
  {name: 'Inter', weights: [400, 500, 600, 700]},
  {name: 'Caveat', weights: [400, 700]},
]);
// Returns: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Caveat:wght@400;700&display=swap'

scaffoldProject(outputDir, templateDir)

Copy boilerplate files to create a complete Next.js 15 + shadcn/ui project.

import {scaffoldProject, createProjectStructure} from './plugin';

await createProjectStructure('./output');
await scaffoldProject('./output', './templates');
// Copies: package.json, next.config.ts, tsconfig.json, components.json, etc.

installShadcnComponents(projectDir, components)

Install additional shadcn/ui components using the CLI.

import {installShadcnComponents} from './plugin';

await installShadcnComponents('./output', [
  'button', 'card', 'dialog', 'dropdown-menu', 'input'
]);

generateAgentsMd(options)

Generate an AGENTS.md file documenting the cloned project.

import {generateAgentsMd, writeFile} from './plugin';

const agentsMd = generateAgentsMd({
  sourceUrl: 'https://example.com',
  siteName: 'Example Site',
  sections: ['Navigation', 'Hero', 'Features', 'Footer'],
});

await writeFile('./output/AGENTS.md', agentsMd);

Example Usage

import FirecrawlApp from '@mendable/firecrawl-js';
import {
  createProjectStructure,
  scaffoldProject,
  renderPageWithExtraction,
  scrapePage,
  saveScreenshot,
  generateAgentsMd,
  writeFile,
  getFirecrawlApiKey,
} from './plugin';

const outputDir = './output';
const templateDir = './templates'; // Use absolute path if running elsewhere
const sourceUrl = 'https://example.com';

// 0. Scaffold Next.js + shadcn/ui
await createProjectStructure(outputDir);
await scaffoldProject(outputDir, templateDir);

// 1. Render with extraction
const render = await renderPageWithExtraction({url: sourceUrl});
await saveScreenshot(render.screenshot, `${outputDir}/screenshots/original.png`);

// 2. Scrape assets
const firecrawl = new FirecrawlApp({apiKey: getFirecrawlApiKey()});
const scrape = await scrapePage({
  url: sourceUrl,
  renderResult: render,
  firecrawlClient: firecrawl,
  outputDir,
});

// 3. Analyze HTML + screenshot (Claude does this)
// ... analyze scrape.html to find sections ...
// ... generate TSX for each section ...

// 4. Write project files
await writeFile(`${outputDir}/src/app/page.tsx`, pageTsx);
await writeFile(`${outputDir}/src/app/globals.css`, globalsCss);
await writeFile(`${outputDir}/src/components/sections/hero.tsx`, heroTsx);

// 5. Generate AGENTS.md
const agentsMd = generateAgentsMd({
  sourceUrl,
  siteName: 'Example Site',
  sections: ['Navigation', 'Hero', 'Footer'],
});
await writeFile(`${outputDir}/AGENTS.md`, agentsMd);

Output Structure

output/
├── package.json
├── next.config.ts
├── tsconfig.json
├── components.json
├── postcss.config.mjs
├── eslint.config.mjs
├── .gitignore
├── public/
│   ├── assets/
│   └── fonts/
├── src/
│   ├── app/
│   │   ├── layout.tsx
│   │   ├── globals.css
│   │   └── page.tsx
│   ├── components/
│   │   ├── ui/
│   │   │   └── button.tsx
│   │   └── sections/
│   │       ├── navigation.tsx
│   │       ├── hero.tsx
│   │       └── footer.tsx
│   └── lib/
│       └── utils.ts
├── screenshots/
│   └── original.png
└── AGENTS.md

Running the Clone

cd output
npm install
npm run dev

Open http://localhost:3000 to view the clone.

No Anthropic API Key Needed

This skill runs inside Claude Code/opencode, so Claude IS the AI. The skill provides utilities for:

  • Rendering pages (Playwright)
  • Scraping content (Firecrawl)
  • Downloading assets
  • Writing files

Claude uses its own intelligence to:

  • Analyze the HTML structure
  • Identify visual sections
  • Generate clean TSX components
  • Apply appropriate Tailwind classes