Claude Code Plugins

Community-maintained marketplace

Feedback

|

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name link
description Full-stack monorepo expert for wellness-link project. Handles features spanning packages/web (React 19 + Tailwind v4) and packages/api (Bun + Elysia). Use for full-stack features, cross-package types, monorepo workflows, workspace commands. Keywords: fullstack, monorepo, wellness-link, cross-package, workspace, bun.

Wellness Link - Full-Stack Monorepo Expert

Expert for the wellness-link monorepo. Combines frontend (React 19 + Tailwind v4 + shadcn/ui) and backend (Bun + Elysia + Drizzle) development with monorepo-specific workflows.

Available Documentation

Patterns

Agent References

  • Web Agent - Quick reference to .claude/agent/web.md
  • API Agent - Quick reference to .claude/agent/api.md

Monorepo Structure

wellness-link/
├── packages/
│   ├── web/          # React 19 + Vite (port 5176)
│   └── api/          # Bun + Elysia (port 5300)
├── bunfig.toml       # Bun workspaces
└── package.json      # Root workspace

Critical Cross-Package Rules

1. Type Sharing

// API defines types, web imports via edenTreaty
// packages/api/src/index.ts
export const app = new Elysia()...

// packages/web/src/lib/api.ts
import type { App } from "@wellness-link/api"
export const api = edenTreaty<App>("http://localhost:5300")

2. Language & Theme

  • User-facing text: Spanish (buttons, forms, messages)
  • Technical docs: English (code, comments, README)
  • Theme: Always use CSS variables (bg-background, text-foreground)

3. Workspace Commands

# Run from root
bun --filter @wellness-link/web dev    # Frontend only
bun --filter @wellness-link/api dev    # Backend only

# Development (both in parallel)
bun run dev                             # Runs both packages

Web Package (packages/web)

Stack

  • React 19 + React Router 7 (file-based)
  • Tailwind CSS v4 + shadcn/ui
  • TanStack Query (server state)
  • React Hook Form + Zod (forms)

Critical Rules

// ALWAYS use @/ alias
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

// ALWAYS use cn() for classes
<div className={cn("flex", className, isActive && "bg-primary")} />

// ALWAYS Spanish UI text
<Button>Guardar Cambios</Button>
toast.success("Perfil actualizado")

Data Fetching

const { data, isLoading } = useQuery({
  queryKey: ["profiles"],
  queryFn: async () => {
    const { data, error } = await api.api.profiles.get()
    if (error) throw error
    return data
  },
})

API Package (packages/api)

Stack

  • Bun (runtime)
  • Elysia (framework)
  • Drizzle ORM (PostgreSQL)
  • Better Auth (authentication)

Critical Rules

// Table names are SINGULAR
import { profile, asset, socialLink } from "../../db/schema"

// ALWAYS register services in plugins/services.ts
export const servicesPlugin = new Elysia({ name: "services" }).derive(
  { as: "global" },
  async () => {
    const featureRepo = new FeatureRepository();
    const featureService = new FeatureService(featureRepo);
    return { services: { featureRepo, featureService } };
  },
);

// Access relations via name
const platform = click.socialLink.platform; // ✅
const platform = click.platform;            // ❌

Route Pattern

export const featureRoutes = new Elysia({ prefix: "/feature" })
  .use(errorMiddleware)
  .use(servicesPlugin)
  .use(authGuard)
  .get("/", ({ ctx, services }) => services.featureService.getAll(ctx!))
  .post("/", ({ body, ctx, services, set }) => {
    set.status = 201;
    return services.featureService.create(ctx!, body);
  }, { body: t.Object({ name: t.String() }) });

Full-Stack Feature Workflow

1. Define API Contract

// packages/api/src/api/routes/feature.ts
export const featureRoutes = new Elysia({ prefix: "/feature" })
  .get("/", () => [...])
  .post("/", ({ body }) => body, {
    body: t.Object({
      name: t.String(),
      description: t.String(),
    })
  });

2. Add Route to App

// packages/api/src/index.ts
import { featureRoutes } from "./api/routes/feature"

export const app = new Elysia()
  .use(featureRoutes)
  ...

3. Frontend Integration

// packages/web/src/hooks/use-features.ts
export function useFeatures() {
  return useQuery({
    queryKey: ["features"],
    queryFn: async () => {
      const { data, error } = await api.api.feature.get()
      if (error) throw error
      return data
    },
  })
}

// packages/web/src/components/FeatureForm.tsx
const mutation = useMutation({
  mutationFn: async (values: { name: string; description: string }) => {
    const { data, error } = await api.api.feature.post(values)
    if (error) throw error
    return data
  },
})

Common Patterns

Authentication Flow

// API: Better Auth automatic
// packages/api/src/lib/auth.ts
export const auth = betterAuth({ ... })

// Web: Use auth client
// packages/web/src/hooks/use-auth.ts
const { data: session } = useSession()

File Upload (Full-Stack)

// API: Asset service
const asset = await services.assetService.create(ctx, {
  file: request.file,
  type: "avatar",
})

// Web: Form with file input
const { mutate } = useMutation({
  mutationFn: async (file: File) => {
    const formData = new FormData()
    formData.append("file", file)
    const { data } = await api.api.assets.post(formData)
    return data
  },
})

Error Handling

// API: HTTP exceptions
throw new NotFoundException("Profile not found")     // 404
throw new ConflictException("Username exists")       // 409

// Web: React Query + toast
onError: (error) => {
  toast.error(error.message || "Error al guardar")
}

Monorepo Best Practices

1. Development Setup

# Install all dependencies
bun install

# Start both packages
bun run dev

# Type check entire monorepo
bun run typecheck

2. Database Migrations

# Generate migration
cd packages/api && bun run db:generate

# Apply migration
bun run db:migrate

# Seed data
bun run db:seed

3. Cross-Package Changes

Order: API first, then Web

  1. Add DB schema/migration
  2. Create repository + service
  3. Add API route
  4. Create frontend hook
  5. Build UI component

4. Type Safety

// API exports App type
export type App = typeof app

// Web imports and uses it
import type { App } from "@wellness-link/api"
export const api = edenTreaty<App>("http://localhost:5300")

Key Tables

  • user: Better Auth authentication
  • profile: Wellness professional info
  • socialLink: Orderable social media links
  • healthSurvey: Visitor survey responses
  • analytics: Views and clicks tracking
  • asset: File uploads (avatars, images)

Quick Commands

# Web development
cd packages/web
bun run dev          # Port 5176
bun run build
bun run lint

# API development
cd packages/api
bun run dev          # Port 5300
bun run db:seed
bun run db:reset
bun run lint

# Monorepo (from root)
bun run dev          # Both packages
bun install          # All dependencies

When to Use This Skill

  • Implementing features that span both web and api
  • Setting up new API endpoints with frontend integration
  • Working with shared types across packages
  • Monorepo workflow questions
  • Cross-package refactoring
  • Full-stack feature development