Thanks for your interest in contributing to React Grab! This document provides guidelines and instructions for contributing.
- Node.js >= 18
- pnpm >= 8
- Fork and clone the repository:
git clone https://github.com/YOUR_USERNAME/react-grab.git
cd react-grab- Install dependencies using @antfu/ni:
ni- Build all packages:
nr build- Start development mode:
nr devpackages/
├── react-grab/ # Core library
├── grab/ # Bundled package (library + CLI, published as `grab`)
├── cli/ # CLI implementation (@react-grab/cli)
├── provider-cursor/ # Cursor agent integration
├── provider-claude-code/ # Claude Code integration
├── provider-opencode/ # OpenCode integration
├── provider-codex/ # OpenAI Codex integration
├── provider-gemini/ # Google Gemini CLI integration
├── provider-amp/ # Amp SDK integration
├── provider-ami/ # AMI client
├── website/ # Documentation site (react-grab.com)
├── vite-playground/ # Vite development playground
├── next-playground/ # Next.js development playground
├── agent-playground/ # Agent testing playground
├── benchmarks/ # Performance benchmarks
└── web-extension/ # Browser extension
Test your changes in the playgrounds:
# Vite playground
pnpm --filter vite-playground dev
# Next.js playground
pnpm --filter next-playground dev
# Agent playground (for testing agent provider integrations)
pnpm --filter @react-grab/agent-playground dev:claude # Claude Code
pnpm --filter @react-grab/agent-playground dev:cursor # Cursor
pnpm --filter @react-grab/agent-playground dev:opencode # OpenCode
pnpm --filter @react-grab/agent-playground dev:codex # Codex
pnpm --filter @react-grab/agent-playground dev:gemini # Gemini
pnpm --filter @react-grab/agent-playground dev:amp # Amp
pnpm --filter @react-grab/agent-playground dev:ami # AmiThe agent playground runs at http://localhost:5174 and lets you test react-grab's agent provider API with multiple backends.
# Run CLI tests
pnpm --filter @react-grab/cli testnr lint # Check for lint errors
nr lint:fix # Fix lint errors
nr format # Format code with Prettier- Use TypeScript interfaces over types
- Use arrow functions over function declarations
- Use kebab-case for file names
- Use descriptive variable names — avoid shorthands or 1-2 character names
- Example:
innerElementinstead ofel - Example:
didPositionChangeinstead ofmoved
- Example:
- Avoid type casting (
as) unless absolutely necessary - Keep interfaces/types at the global scope
- Remove unused code and follow DRY principles
- Avoid comments unless absolutely necessary
- If a hack is required, prefix with
// HACK: reason for hack
- If a hack is required, prefix with
- Create a new branch:
git checkout -b feat/your-feature-name- Make your changes and commit with a descriptive message:
git commit -m "feat: add new feature"- Push to your fork and open a pull request
We use conventional commits:
feat:— New featurefix:— Bug fixdocs:— Documentation changeschore:— Maintenance tasksrefactor:— Code refactoringtest:— Test additions or changes
For changes that affect published packages, add a changeset:
nr changesetFollow the prompts to describe your changes. This helps maintain accurate changelogs.
Found a bug? Have a feature request? Open an issue with:
- Clear description of the problem or request
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Environment details (OS, browser, Node version)
By contributing, you agree that your contributions will be licensed under the MIT License.