agentsclimarketplace

Hook

Skill darkroomengineering/cc-settings/skills/hook

Create reusable React hook (useX pattern). Triggers "create hook", "new hook", "custom hook", "useAuth"/"useScroll"-style names, extracting logic from a component.From its SKILL.md

Install
npx -y skills add darkroomengineering/cc-settings --skill hook

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

3.5 KB, as published. Nobody here has run it

Create Custom Hook

Create a custom React hook following Darkroom conventions. The hook itself is stack-agnostic — what differs between satus and novus is the path alias.

Step 1 — Detect stack

Read package.json:

  • dependencies.next → satus / Next.js (path alias @/, no lib/hooks/ requires 'use client' boundary)
  • dependencies["react-router"] → novus / React Router (path alias ~/, components isomorphic)

Step 2 — Choose location

StackHook path
satuslib/hooks/<name>.ts
novushooks/<name>.ts (novus puts hooks/ at the project root)

Confirm by checking the existing lib/hooks/ or hooks/ directory structure if either pattern is unclear from package.json alone.

Step 3 — Emit template

satus / Next.js

// lib/hooks/<name>.ts
'use client'

import { useState, useEffect } from 'react'

interface Use<Name>Options {
  // Hook configuration options
}

interface Use<Name>Return {
  // Return type definition
}

export function use<Name>(options?: Use<Name>Options): Use<Name>Return {
  // Implementation
  return {
    // Return values
  }
}

novus / React Router

// hooks/<name>.ts
// No 'use client' — RR components are isomorphic; the hook runs wherever
// it's called from. If the hook touches browser APIs, guard with
// `typeof window !== 'undefined'` or call from inside `useEffect`.

import { useState, useEffect } from 'react'

interface Use<Name>Options {
  // Hook configuration options
}

interface Use<Name>Return {
  // Return type definition
}

export function use<Name>(options?: Use<Name>Options): Use<Name>Return {
  // Implementation
  return {
    // Return values
  }
}

Conventions (both stacks)

  1. Type everything — options interface, return interface.
  2. Named export — export function useX, not default.
  3. Prefix with use — React hook naming convention.
  4. No memoization — React Compiler handles it automatically.

Stack-specific

satusnovus
Directive'use client' (hooks live in client boundary)None (isomorphic)
Browser API guardOnly runs after hydration anywayGuard with typeof window or use useEffect
Path alias@/~/

Before you start

If this hook uses an external library, fetch docs first:

  1. Use Context7 MCP (mcp__context7__resolve-library-id → get-library-docs) in Claude or when the user configured it in standalone Codex. Otherwise use official docs through native browsing or inspect the pinned local package. cc-settings does not auto-run unpinned registry MCP packages in Codex.
  2. Run bun info <package> to check the latest version.

Consider Using Hamo

For common use cases, prefer hamo hooks (fetch hamo docs via Context7 first):

import { useWindowSize, useRect, useIntersectionObserver } from 'hamo'

Only create custom hooks when hamo doesn't cover the use case.

Example

User: "create a useLocalStorage hook" (in satus repo)
→ Creates lib/hooks/use-local-storage.ts with 'use client' directive

User: "create a useLocalStorage hook" (in novus repo)
→ Creates hooks/use-local-storage.ts, no directive, browser-API-guarded

Arguments

  • $ARGUMENTS — Hook name (e.g., "useAuth", "useLocalStorage")

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.