← 返回 Skills 市场
tenequm

typescript-dev

作者 Misha Kolesnik · GitHub ↗ · v0.1.0 · MIT-0
cross-platform ⚠ suspicious
45
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install typescript-dev
功能描述
Build modern TypeScript frontend apps with Vite 8, React 19, Tailwind CSS v4, shadcn/ui, Biome, and Vitest. Covers the full stack - build tooling and dev ser...
使用说明 (SKILL.md)

TypeScript Frontend Development

One coherent stack for building type-safe React apps: Vite 8 (build + dev server, Rolldown-powered), React 19.2 with the React Compiler, TypeScript 6.0 (strict), Tailwind CSS v4.3 + shadcn/ui for styling, Biome 2.4 for linting and formatting, and Vitest 4 for testing. The pieces are designed to fit together - this skill covers how they wire up and the sharp edges that span more than one of them.

The body below is the cross-cutting layer: the rules that bite when these tools meet, plus one working end-to-end setup. Each tool also has a deep-dive reference - read the one you need:

  • references/vite.md - Vite 8 config, dev server, proxy, HMR, Rolldown, code splitting, build optimization, deployment.
  • references/react.md - React 19 patterns: Actions, use(), Activity, useEffectEvent, document metadata, and the React Compiler.
  • references/typescript.md - Strict TypeScript 6.0 config and patterns: tsconfig defaults, generics, utility types, import defer, tsgo.
  • references/tailwind.md - Tailwind CSS v4 CSS-first config, OKLCH theming, dark mode, v4.3 utilities.
  • references/shadcn.md - shadcn/ui CLI, component authoring with CVA + data-slot, registries, Radix vs Base UI.
  • references/biome.md - Biome config, biome check, domains, type-aware linting, GritQL, ESLint/Prettier migration.
  • references/vitest.md - Vitest config, Testing Library, jsdom/happy-dom, coverage, browser mode, projects.

Version targets

Tool Version Note
Vite 8.0.16 Rolldown is the single default bundler
@vitejs/plugin-react 6.0.2 v6 removed the inline babel option
React / react-dom 19.2.7 React Compiler is stable (1.0)
babel-plugin-react-compiler 1.0.0 pin with --save-exact
TypeScript 6.0.3 last JS-based TS; bridge to tsgo/TS 7
Tailwind CSS 4.3.0 CSS-first config, no JS config file
shadcn/ui CLI 4.10.0 create is an alias of init
Biome 2.4.16 single binary for lint + format + imports
Vitest 4.1.8 Vite-native test runner; reuses vite.config

Cross-cutting critical rules

These are the rules that fail in confusing ways precisely because they sit at the seam between two tools. The single-tool details live in the references.

Vite plugin order: framework plugins first, react() last

When a framework plugin (TanStack Router/Start, etc.) generates routes or transforms code, it must run before @vitejs/plugin-react so React's Fast Refresh transform sees the final output. Wrong order causes route-generation failures and broken HMR.

plugins: [
  tanstackStart(),   // or tanstackRouter() for SPA - framework first
  tailwindcss(),
  react(),           // React plugin last among framework plugins
]

React Compiler replaces manual memoization - and changes how you wire Vite

React Compiler 1.0 auto-memoizes components, computations, and callbacks at build time. Write plain components; do not reach for useMemo/useCallback/memo. The catch lives at the Vite seam: @vitejs/plugin-react v6 removed the inline babel option, so the old react({ babel: { plugins: [...] } }) wiring no longer works. The compiler now runs through a separate Babel plugin:

import react, { reactCompilerPreset } from '@vitejs/plugin-react'
import babel from '@rolldown/plugin-babel'

plugins: [react(), babel({ presets: [reactCompilerPreset()] })]

Install: pnpm add -D @rolldown/plugin-babel @babel/core babel-plugin-react-compiler @types/babel__core.

This also ripples into Biome: useExhaustiveDependencies can't tell the compiler is handling deps for you, so most compiler users turn it off (see biome.md).

Tailwind v4 is CSS-first - there is no tailwind.config.js

Tailwind v4 configures everything in CSS via @theme, @utility, @plugin, @source. Never create or look for tailwind.config.js/.ts. The Vite integration is the @tailwindcss/vite plugin (no PostCSS config either). If you find a tailwind.config.js in a v4 project, it is leftover - delete it and migrate the values into CSS. Full details in tailwind.md.

Style with semantic tokens, never raw palette or dynamic class names

\x3Cdiv className="bg-primary text-primary-foreground">   // respects theme + dark mode
\x3Cdiv className="bg-blue-500 text-white">               // breaks theming - avoid

And never assemble class names from fragments (bg-${color}-500) - Tailwind's scanner only sees complete literal strings, so dynamic names silently produce no CSS. Use a lookup map of full class strings.

TypeScript 6.0 changed the defaults - lean on them, don't fight them

TS 6.0 bakes in much of what used to be manual: strict and noUncheckedSideEffectImports are now on by default, so drop them from a fresh tsconfig. But two new defaults will break builds if you ignore them: types now defaults to [] (add "types": ["node"] if you use Node globals) and module/target shifted (module defaults to esnext, not nodenext). baseUrl is deprecated - use prefixed paths instead. See typescript.md for the full 6.0 tsconfig and migration notes.

One Biome command, and files.includes is the only include key

Run biome check (or biome ci) - it formats, lints, and organizes imports in a single pass; never split into separate lint+format calls. And in Biome 2.x the only file-selection key is files.includes (with the s); files.ignore/files.include/files.exclude do not exist and throw Found an unknown key. Exclude with negation: "includes": ["**", "!**/routeTree.gen.ts"]. More in biome.md.

End-to-end setup

A minimal but complete React + TypeScript + Tailwind + Biome project. Swap the framework plugin for your router/SSR choice (see vite.md for TanStack and Cloudflare variants).

vite.config.ts

import { defineConfig } from 'vite'
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
import babel from '@rolldown/plugin-babel'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    tailwindcss(),
    react(),
    babel({ presets: [reactCompilerPreset()] }),
  ],
  resolve: {
    alias: { '@': new URL('./src', import.meta.url).pathname },
  },
})

import.meta.url is the ESM-correct way to resolve paths - there is no __dirname in an ESM config, and Vite configs are ESM-only.

tsconfig.json (TypeScript 6.0)

{
  "compilerOptions": {
    // strict + noUncheckedSideEffectImports are ON by default in 6.0 - omitted on purpose
    "target": "es2023",
    "module": "preserve",
    "moduleResolution": "bundler",
    "moduleDetection": "force",
    "jsx": "react-jsx",
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "erasableSyntaxOnly": true,
    "skipLibCheck": true,
    "types": [],
    "paths": { "@/*": ["./src/*"] }
  }
}

module: preserve + moduleResolution: bundler is the right pairing for a Vite-bundled app; use nodenext instead only for Node-executed code. types: [] keeps ambient @types/* from leaking in globally - add ["node"] (or others) explicitly when needed.

biome.json

{
  "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
  "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
  "files": { "includes": ["**", "!**/components/ui", "!**/routeTree.gen.ts"] },
  "formatter": { "enabled": true, "indentStyle": "space", "lineWidth": 100 },
  "linter": {
    "enabled": true,
    "rules": { "recommended": true },
    "domains": { "react": "recommended" }
  },
  "javascript": { "formatter": { "quoteStyle": "double" } },
  "assist": { "enabled": true, "actions": { "source": { "organizeImports": "on" } } }
}

src/styles.css

@import "tailwindcss";

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --radius: 0.5rem;
}
.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
}

The @import "tailwindcss"; line is load-bearing: the @tailwindcss/vite plugin alone produces no styles without it - a missing import is the classic "Tailwind renders nothing" footgun. Use @theme inline (not plain @theme) for tokens that reference CSS variables, so they track dark-mode changes.

A component, the way the whole stack wants it

Plain function, ref as a regular prop (no forwardRef), native element props via React.ComponentProps, variants via CVA, data-slot for styling hooks, and no manual memoization - the compiler handles it.

import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        outline: "border border-input bg-background hover:bg-accent",
        ghost: "hover:bg-accent hover:text-accent-foreground",
      },
      size: { default: "h-9 px-4 py-2", sm: "h-8 px-3", lg: "h-10 px-8" },
    },
    defaultVariants: { variant: "default", size: "default" },
  }
)

function Button({
  className,
  variant,
  size,
  ref,
  ...props
}: React.ComponentProps\x3C"button"> & VariantProps\x3Ctypeof buttonVariants>) {
  return (
    \x3Cbutton
      ref={ref}
      data-slot="button"
      className={cn(buttonVariants({ variant, size }), className)}
      {...props}
    />
  )
}

Note the cn() order: defaults first, consumer className last, so tailwind-merge's last-wins resolution lets callers override.

Best practices

  1. Let the compiler optimize. Write plain components and computations; reserve useMemo/useCallback for the rare case where you need a value to be a stable effect dependency.
  2. Model state as discriminated unions, not loose booleans ({ status: "loading" } | { status: "error"; error }) so impossible states are unrepresentable.
  3. Extend native props with React.ComponentProps\x3C"el"> instead of re-declaring HTML attributes by hand.
  4. Use use() over useContext() - it works after early returns and inside conditionals.
  5. Semantic color tokens only, and always pair bg-* with the matching text-*-foreground.
  6. biome check --write is your one local command; biome ci in pipelines.
  7. Rolldown is the default bundler in Vite 8 - no opt-in needed; split stable vendor code with Rolldown's codeSplitting (see vite.md).
  8. Pin exact versions for tooling that rewrites code (babel-plugin-react-compiler, @biomejs/biome) to avoid surprise diffs between releases.
  9. Keep secrets off the client - only VITE_-prefixed env vars reach browser code via import.meta.env.
  10. Test through vite.config.ts - Vitest reuses your build config, so tests see the same aliases and transforms; vitest run in CI, jsdom for component tests.

Resources

安全使用建议
Install only if you are comfortable with the ClawHub-specific workflows and the autoreview helper's default full-access nested Codex mode. For safer use, run autoreview with --no-yolo or set AUTOREVIEW_YOLO=0, and keep moderation, proof publishing, Convex deploys, and migrations limited to explicit user-approved targets.
能力标签
crypto
能力评估
Purpose & Capability
The ClawHub moderation, PR maintenance, UI proof, and Convex workflow skills mostly match their stated purposes; moderation actions are high-impact but explicitly scoped to staff workflows with target, reason, auth, audit logging, and confirmation requirements.
Instruction Scope
Runtime instructions are generally explicit and task-scoped, with no hidden prompt-injection or unrelated behavior found; the main scope issue is the autoreview helper's default full-access nested reviewer mode.
Install Mechanism
Artifacts are plain skill Markdown, YAML metadata, references, and one Bash helper script under .agents/skills; no install hook, autostart mechanism, or obfuscated installer was found.
Credentials
The autoreview script adds --dangerously-bypass-approvals-and-sandbox --sandbox danger-full-access by default for nested Codex review, which grants broad local authority for a mostly read-only review purpose, though it is disclosed and has --no-yolo/AUTOREVIEW_YOLO=0 opt-outs.
Persistence & Privilege
No durable background persistence was found; expected writes include local proof artifacts, temp/output files, project setup files, and user-directed remote changes such as moderation, publishing proof artifacts, or Convex migrations.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install typescript-dev
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /typescript-dev 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v0.1.0
Initial publish of typescript-dev 0.1.0. Changes: - added `CHANGELOG.md` - moved in `skills/biome/LICENSE.txt` -> `LICENSE.txt` - added `SKILL.md` - added `references/biome.md` - added `references/react.md` - added `references/shadcn.md` - added `references/tailwind.md` - added `references/typescript.md` - added `references/vite.md` - added `references/vitest.md`
元数据
Slug typescript-dev
版本 0.1.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

typescript-dev 是什么?

Build modern TypeScript frontend apps with Vite 8, React 19, Tailwind CSS v4, shadcn/ui, Biome, and Vitest. Covers the full stack - build tooling and dev ser... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 45 次。

如何安装 typescript-dev?

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

typescript-dev 是免费的吗?

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

typescript-dev 支持哪些平台?

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

谁开发了 typescript-dev?

由 Misha Kolesnik(@tenequm)开发并维护,当前版本 v0.1.0。

💬 留言讨论