IDE Setup
How to configure your IDE to get the most out of Catalyst Next
IDE-First Philosophy
In Catalyst Next, JSDoc comments are the primary documentation. They are not a supplement to external docs — they are the docs, surfaced in three places simultaneously:
| Surface | How JSDoc appears |
|---|---|
| VS Code hover tooltip | Prop descriptions, defaults, and examples appear inline as you type |
| Storybook Controls panel | @storybook/react reads JSDoc to populate ArgTypes automatically |
| Fumadocs prop tables | The docsite auto-generates API reference from TypeScript + JSDoc |
This means: if a prop is documented correctly in the source file, it is documented everywhere. You never need to maintain docs in multiple places.
The rule: If you add or change a prop and don't update its JSDoc, the documentation is broken — even if the primitive works.
JSDoc Strategy
Primitive-level JSDoc
Every exported primitive must have a JSDoc block describing its purpose, default element, and asChild behaviour if applicable:
/**
* Primary interaction element for marketing and product interfaces.
*
* Renders as a `<button>` by default. Use the `asChild` prop to delegate
* rendering to a child element (e.g. a router `<Link>`).
*
* @example
* // Default button
* <Button variant="solid" size="md">Click me</Button>
*
* @example
* // As a link
* <Button asChild><a href="/docs">Read the docs</a></Button>
*/
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(...)Prop-level JSDoc
Document every prop on the interface, not the primitive implementation. This is where VS Code, Storybook, and Fumadocs read from:
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
/**
* Controls the visual style of the badge.
* - `solid` — filled background, high contrast
* - `soft` — muted background, low contrast
* - `outline` — transparent background with border
* @default "soft"
*/
variant?: 'solid' | 'soft' | 'outline';
/**
* Controls the colour palette applied to the badge.
* Maps to design token–backed Tailwind classes.
* @default "neutral"
*/
color?: 'off-black' | 'accent' | 'neutral' | 'info' | 'danger' | 'warning' | 'success';
/**
* When `true`, merges props onto the child element via Radix UI Slot
* instead of rendering its own DOM node.
* @see {@link https://www.radix-ui.com/primitives/docs/utilities/slot Radix UI Slot}
* @default false
*/
asChild?: boolean;
}JSDoc tags used in this project
| Tag | Usage |
|---|---|
@default | Default prop value — required for all props with defaults; Storybook and Fumadocs rely on it |
@example | Inline code example shown in hover tooltip and Storybook Controls |
@see | Links to related primitives, external docs, or Radix primitives |
@deprecated | Marks a prop or primitive as deprecated — include migration guidance |
@internal | Marks utilities not intended for consumer use |
@param | Documents function parameters (utility functions and hooks only) |
@returns | Documents return values (hooks only) |
Tags to avoid
- Do not duplicate the prop type in
@param— TypeScript already carries this - Do not use
@type— redundant with TypeScript annotations - Do not omit
@defaultfor props with defaults — this breaks Storybook ArgTypes and Fumadocs prop tables
Recommended VS Code Extensions
A correctly configured VS Code is what makes the IDE-first approach work. Without Tailwind IntelliSense and TypeScript hover, JSDoc docs are invisible to the developer.
Essential
| Extension | ID | Purpose | Notes / Recommended Settings |
|---|---|---|---|
| ESLint | dbaeumer.vscode-eslint | Lint feedback inline as you type | Recommended: "eslint.validate": ["javascript", "typescript", "typescriptreact"] in .vscode/settings.json. Works well with Prettier. |
| Prettier | esbenp.prettier-vscode | Auto-format on save | Enable "editor.formatOnSave": true. Make sure ESLint and Prettier rules are aligned to avoid conflicts. |
| Tailwind CSS IntelliSense | bradlc.vscode-tailwindcss | Autocomplete for Tailwind utility classes and design tokens | Can enable experimental.classRegex for CSS Modules support. Do not install "IntelliSense for CSS class names in HTML" alongside this — they conflict. |
| GitHub Copilot | github.copilot | AI-assisted code completion inline as you type | Requires GitHub account with Copilot access. Core part of the Catalyst development workflow. |
| GitHub Copilot Chat | github.copilot-chat | Inline AI chat for refactoring, questions, and explanations | Pairs with GitHub Copilot. Use for primitive, test, and JSDoc generation. |
| TypeScript (built-in) | — | Use the workspace TypeScript version instead of VS Code's bundled one | No installation required. Configure "typescript.tsdk" in .vscode/settings.json to use the project version. |
Recommended
| Extension | ID | Purpose | Notes / Recommended Settings |
|---|---|---|---|
| MDX | unifiedjs.vscode-mdx | Syntax highlighting and IntelliSense in .mdx files | Useful for Fumadocs docsite pages. |
| GitLens | eamodio.gitlens | Git blame, history, and PR annotations inline in the editor | Especially useful in a monorepo with Azure DevOps PRs and multi-package history. |
| Jest | orta.vscode-jest | Run and debug Jest tests inline without leaving the editor | Project uses Jest + React Testing Library — enables inline test status and snapshot review. |
| Error Lens | usernamehakobyan.error-lens | Shows inline errors and warnings next to the offending line | Colors and font can be customized via errorLens.fontWeight and errorLens.fontSize. Can be used with Pretty TypeScript Errors. |
| Pretty TypeScript Errors | yoavbls.pretty-ts-errors | Makes TypeScript errors more readable | Helps especially in large projects. Can be used alongside Error Lens, but you may choose one if preferred. |
| Headwind | heybourn.headwind | Enforces consistent Tailwind class ordering | Works only with Tailwind. Enable "headwind.sortOnSave": true in .vscode/settings.json for automatic sorting. |
| SVG Preview | jock.svg | Preview SVG files directly in VS Code | Useful when working with the Catalyst icons package. |
Nice to have
| Extension | ID | Purpose | Notes / Recommended Settings |
|---|---|---|---|
| Mermaid Markdown Syntax Highlighting | bpruitt-goddard.mermaid-markdown-syntax-highlighting | Syntax highlighting for Mermaid diagrams in Markdown and MDX | Useful if architecture or primitive hierarchy diagrams are added to docsite MDX pages. |
Storybook
| Extension | ID | Purpose | Notes / Recommended Settings |
|---|---|---|---|
| Storybook Snippets | dineug.vscode-storybook-snippets | Boilerplate for stories and args | Supports JSX/TSX, suitable for Storybook 7+. Speeds up story creation. |
Workspace Extension Recommendations
The project includes a .vscode/extensions.json file. VS Code will automatically prompt you to install all recommended extensions when you open the workspace:
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss",
"github.copilot",
"github.copilot-chat",
"unifiedjs.vscode-mdx",
"eamodio.gitlens",
"orta.vscode-jest",
"usernamehakobyan.error-lens",
"yoavbls.pretty-ts-errors",
"heybourn.headwind",
"jock.svg",
"bpruitt-goddard.mermaid-markdown-syntax-highlighting"
]
}TypeScript Config
Catalyst Next uses TypeScript 5.6+ with strict mode enabled. Key settings to be aware of:
Use the workspace TypeScript version
VS Code defaults to its own bundled TypeScript version, which may differ from the project's. Always use the workspace version:
- Open any
.tsor.tsxfile - Press
Cmd/Ctrl + Shift + P→ TypeScript: Select TypeScript Version - Choose Use Workspace Version
Or add this to your .vscode/settings.json:
// filepath: .vscode\settings.json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}tsconfig.json highlights
The root tsconfig.json enables strict type checking across all primitive packages:
{
"compilerOptions": {
"strict": true, // Enables all strict type checks
"exactOptionalPropertyTypes": true, // Distinguishes undefined from missing props
"noUncheckedIndexedAccess": true, // Array/object access returns T | undefined
"moduleResolution": "bundler", // Aligns with Parcel + Vite build pipeline
"jsx": "react-jsx", // No need to import React in every file
"paths": {
"@catalyst-next/*": ["./src/components/*"]
}
}
}