← Back to Skills Marketplace
tenequm

typescript-dev

by Misha Kolesnik · GitHub ↗ · v0.1.0 · MIT-0
cross-platform ⚠ suspicious
45
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install typescript-dev
Description
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...
README (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

Usage Guidance
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.
Capability Tags
crypto
Capability Assessment
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.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install typescript-dev
  3. After installation, invoke the skill by name or use /typescript-dev
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
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`
Metadata
Slug typescript-dev
Version 0.1.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is 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... It is an AI Agent Skill for Claude Code / OpenClaw, with 45 downloads so far.

How do I install typescript-dev?

Run "/install typescript-dev" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is typescript-dev free?

Yes, typescript-dev is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does typescript-dev support?

typescript-dev is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created typescript-dev?

It is built and maintained by Misha Kolesnik (@tenequm); the current version is v0.1.0.

💬 Comments