← 返回 Skills 市场
samber

Crxjs

作者 Samuel Berthe · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
106
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install crxjs
功能描述
CRXJS Chrome extension development — true HMR for popup, options, content scripts, side panels, manifest-driven builds, dynamic content script imports (`?scr...
使用说明 (SKILL.md)

CRXJS

CRXJS is a Chrome extension development tool that provides true HMR for popup, options, content scripts, and side panels. It reads your manifest to auto-generate the extension output, handles content script injection, and manages the service worker build. Under the hood it is a Vite plugin (@crxjs/vite-plugin).

Current status

  • Package: @crxjs/vite-plugin (v2.x stable, latest v2.4.0 as of March 2026)
  • Scaffolding: npm create crxjs@latest (always use @latest)
  • Maintained by: @Toumash and @FliPPeDround (since mid-2025)
  • GitHub: github.com/crxjs/chrome-extension-tools (~4k stars)
  • Vite compatibility: v3 through v8-beta

Quick start

# Scaffold new project (picks framework interactively)
npm create crxjs@latest

# Or add to existing Vite project
npm install @crxjs/vite-plugin -D

Vite config by framework

CRXJS is added as a Vite plugin. The setup varies slightly per framework.

React

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { crx } from "@crxjs/vite-plugin";
import manifest from "./manifest.json";

export default defineConfig({
  plugins: [react(), crx({ manifest })],
});

Use @vitejs/plugin-react (not plugin-react-swc) for best HMR compatibility. If you must use SWC, cast the manifest:

import { ManifestV3Export } from "@crxjs/vite-plugin";
const manifest = manifestJson as ManifestV3Export;

Vue

import vue from "@vitejs/plugin-vue";
import { crx } from "@crxjs/vite-plugin";
import manifest from "./manifest.json";

export default defineConfig({
  plugins: [vue(), crx({ manifest })],
});

Svelte

import { svelte } from "@sveltejs/vite-plugin-svelte";
import { crx } from "@crxjs/vite-plugin";
import manifest from "./manifest.json";

export default defineConfig({
  plugins: [svelte(), crx({ manifest })],
});

Vanilla TypeScript

import { crx } from "@crxjs/vite-plugin";
import manifest from "./manifest.json";

export default defineConfig({
  plugins: [crx({ manifest })],
});

defineManifest — type-safe dynamic manifest

Instead of a static JSON file, use CRXJS's defineManifest for dynamic values and full TypeScript autocompletion:

// manifest.ts
import { defineManifest } from "@crxjs/vite-plugin";
import pkg from "./package.json";

export default defineManifest((config) => ({
  manifest_version: 3,
  name: config.command === "serve" ? `[DEV] ${pkg.name}` : pkg.name,
  version: pkg.version,
  description: pkg.description,
  permissions: ["storage", "activeTab", "scripting"],
  action: {
    default_popup: "src/popup/index.html",
    default_icon: {
      "16": "public/icons/icon16.png",
      "48": "public/icons/icon48.png",
    },
  },
  background: {
    service_worker: "src/background/index.ts",
    type: "module",
  },
  content_scripts: [
    {
      matches: ["https://*/*"],
      js: ["src/content/index.ts"],
      css: ["src/content/styles.css"],
    },
  ],
  options_page: "src/options/index.html",
  side_panel: { default_path: "src/sidepanel/index.html" },
  icons: {
    "16": "public/icons/icon16.png",
    "48": "public/icons/icon48.png",
    "128": "public/icons/icon128.png",
  },
}));

Import in vite.config.ts:

import manifest from "./manifest";
// ... crx({ manifest })

Type declarations

Add to a src/vite-env.d.ts or src/crxjs.d.ts:

/// \x3Creference types="@crxjs/vite-plugin/client" />

This enables types for ?script and ?script&module imports.

HMR behavior by context

Context HMR How it works
Popup Full HMR WebSocket-based, state preserved
Options page Full HMR Same as popup
Side panel Full HMR Same as popup
Content script (manifest) True HMR CRXJS injects loader + HMR client
Content script (dynamic) True HMR Via ?script import
Service worker Auto-reload Changes trigger full extension reload
Main world scripts No HMR Skipped by CRXJS loader

Content script HMR works because CRXJS generates a loader script that imports an HMR preamble, the HMR client, and your actual script — enabling real module-level HMR without full page reload. This is CRXJS's main differentiator.

Dynamic content script imports

For content scripts injected programmatically (not in manifest), CRXJS provides special import suffixes:

// background.ts — ?script gives you a resolved path for executeScript
import contentScript from "./content?script";

chrome.action.onClicked.addListener(async (tab) => {
  await chrome.scripting.executeScript({
    target: { tabId: tab.id! },
    files: [contentScript],
  });
});

For main world injection (no HMR):

import mainWorldScript from "./inject?script&module";

await chrome.scripting.executeScript({
  target: { tabId },
  world: "MAIN",
  files: [mainWorldScript],
});

CRXJS plugin options

crx({
  manifest,
  browser: "chrome", // 'chrome' | 'firefox'
  contentScripts: {
    injectCss: true, // auto-inject CSS for content scripts
    hmrTimeout: 5000, // HMR connection timeout (ms)
  },
});

Development workflow

# Start dev server (outputs to dist/ with HMR)
npm run dev

# 1. Open chrome://extensions
# 2. Enable "Developer mode"
# 3. Click "Load unpacked"
# 4. Select the dist/ directory
# 5. Edit code — popup/content scripts update instantly via HMR
# 6. Service worker changes trigger automatic extension reload

After loading once, subsequent npm run dev sessions reconnect automatically. No need to re-load the extension unless manifest.json changes.

Production build

npm run build    # outputs to dist/

The dist/ directory is ready to zip and upload to Chrome Web Store:

cd dist && zip -r ../extension.zip .

Disable Vite's module preload to avoid CWS rejection of inline scripts:

build: {
  modulePreload: false;
}

Known issues and workarounds

Tailwind CSS HMR in content scripts

New Tailwind classes may not trigger CSS updates in content scripts. Workaround: restart dev server after adding new utility classes. Improved in v2.4.0 but not fully resolved. Ensure injectCss: true in config.

WebSocket connection errors (ws://localhost:undefined/)

Cause: port mismatch between dev server and HMR config. Fix: explicitly set both to the same value:

server: {
  port: 5173,
  strictPort: true,
  hmr: { port: 5173 },
}

"Manifest version 2 is deprecated" warning

If you see this, your manifest is being interpreted as MV2. Fix: ensure "manifest_version": 3 is set.

Content scripts not injecting on file:// URLs

Chrome requires the user to enable "Allow access to file URLs" in the extension settings at chrome://extensions. CRXJS cannot change this.

HMR stops working after Chrome update

CRXJS's HMR relies on injecting a content script that connects to the dev server's WebSocket. Chrome security updates occasionally break this. Fix: update to the latest CRXJS version, which tracks Chrome changes.

CRXJS vs alternatives

Feature CRXJS WXT Plasmo
Content script HMR True HMR File-based reload Partial
Framework support Any Vite framework Any React-focused
Abstraction level Thin (Vite plugin) Full framework Full framework
Messaging helpers None (use chrome.* directly) Built-in Built-in
Storage wrappers None Built-in Built-in
Cross-browser Chrome + Firefox Chrome + Firefox + Safari Chrome + Firefox
File-based routing No Yes Yes
Learning curve Low (know Vite, know CRXJS) Medium Medium

Choose CRXJS when: you want minimal abstraction over raw Chrome APIs and value content script HMR above all. CRXJS stays out of the way — no magic routing, no wrapper APIs, just your code with HMR.

Choose WXT when: you want conventions, built-in utilities, and cross-browser support.

Choose Plasmo when: you're React-focused and want the highest-level abstraction.

Project structure (recommended)

my-extension/
├── src/
│   ├── background/
│   │   └── index.ts
│   ├── content/
│   │   ├── index.ts
│   │   └── styles.css
│   ├── popup/
│   │   ├── index.html        \x3C- CRXJS resolves HTML entry points
│   │   ├── App.tsx
│   │   └── main.tsx
│   ├── options/
│   │   ├── index.html
│   │   └── main.tsx
│   ├── sidepanel/
│   │   ├── index.html
│   │   └── main.tsx
│   └── shared/
│       ├── messages.ts
│       └── storage.ts
├── public/
│   └── icons/
├── manifest.ts               \x3C- or manifest.json
├── vite.config.ts
├── tsconfig.json
└── package.json

CRXJS resolves HTML files referenced in the manifest automatically. Your popup.html can use standard \x3Cscript type="module" src="./main.tsx"> and it works.

If you encounter a bug or unexpected behavior in CRXJS, open an issue at github.com/crxjs/chrome-extension-tools/issues.

安全使用建议
This skill appears to be a straightforward developer helper for CRXJS and is internally consistent. Before using it, be aware that it will instruct the agent to run npm create / npm install and to read and edit project files (vite.config, manifest, src/*). That means: (1) review any package.json scripts and the packages the agent will install—npm packages and scaffolding scripts can run arbitrary code; (2) check the extension manifest permissions (e.g., storage, scripting, activeTab) so you understand runtime capabilities of the extension you build; (3) avoid running commands as an elevated user and keep secrets (env files, private keys) out of the project directory while the agent has file access; (4) if you want maximum safety, run the suggested npm commands yourself and manually review changes rather than granting the agent automatic execution rights. Overall this skill is coherent and fits its stated purpose.
功能分析
Type: OpenClaw Skill Name: crxjs Version: 1.0.0 The skill bundle provides documentation and instructions for using CRXJS, a Vite plugin for Chrome extension development. The content in SKILL.md consists of legitimate technical guidance, code snippets for configuration, and project scaffolding commands (e.g., 'npm create crxjs@latest'). There is no evidence of data exfiltration, malicious execution, or prompt injection intended to subvert the agent's behavior.
能力评估
Purpose & Capability
Name/description (CRXJS Chrome extension development) match the actual requirements: git, node, npm and Vite/npm commands. No unrelated credentials, binaries, or config paths are requested.
Instruction Scope
SKILL.md directs the agent to scaffold projects (npm create), install packages (npm install), and modify project files (vite.config, manifest, src files). That is expected for a dev helper, but it implies the agent will read/write project files and perform network operations (npm registry/GitHub). There are no instructions to access unrelated system files or secrets.
Install Mechanism
Instruction-only skill with no install spec and no downloads. This minimizes disk-write/execute risk; runtime actions rely on standard dev tooling (npm/git).
Credentials
No environment variables or credentials are requested. The few permissions and tools (git, gh, npm) in allowed-tools are appropriate for scaffolding and package management.
Persistence & Privilege
always:false and no indicaton of modifying other skills or system-wide configs. The skill will operate within the project repository (scaffold, install, edit files), which is proportional to its purpose.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install crxjs
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /crxjs 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
crxjs 1.0.0 - Initial release of the crxjs skill for fast Chrome extension development with true HMR for popup, options, content scripts, and side panels. - Provides dynamic, manifest-driven builds using Vite as the build tool. - Supports `defineManifest` for type-safe manifests and dynamic content script imports via `?script` and `?script&module`. - Includes framework-specific Vite config examples for React, Vue, Svelte, and Vanilla. - Documents HMR capabilities for each Chrome extension context and key plugin options. - Covers setup, development workflow, production build, and known issues with workarounds.
元数据
Slug crxjs
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

Crxjs 是什么?

CRXJS Chrome extension development — true HMR for popup, options, content scripts, side panels, manifest-driven builds, dynamic content script imports (`?scr... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 106 次。

如何安装 Crxjs?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install crxjs」即可一键安装,无需额外配置。

Crxjs 是免费的吗?

是的,Crxjs 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Crxjs 支持哪些平台?

Crxjs 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Crxjs?

由 Samuel Berthe(@samber)开发并维护,当前版本 v1.0.0。

💬 留言讨论