Skip to main content

Contributing to Refract

First off, thank you for considering contributing to Refract! It's people like you that make Refract such a great framework. We welcome contributions from everyone, regardless of experience level.

Table of Contents​

Code of Conduct​

By participating in this project, you agree to abide by our Code of Conduct. Please read it before contributing.

Our Pledge​

We pledge to make participation in our project a harassment-free experience for everyone, regardless of:

  • Age, body size, disability, ethnicity, gender identity and expression
  • Level of experience, education, socio-economic status
  • Nationality, personal appearance, race, religion
  • Sexual identity and orientation

How Can I Contribute?​

Reporting Bugs​

Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include:

  1. Clear title and description
  2. Steps to reproduce
  3. Expected behavior
  4. Actual behavior
  5. Code samples (if applicable)
  6. Environment details:
    • Refract version
    • Node.js version
    • Browser and version
    • Operating system

Bug Report Template:

## Description

Brief description of the bug

## Steps to Reproduce

1. Step one
2. Step two
3. Step three

## Expected Behavior

What should happen

## Actual Behavior

What actually happens

## Code Sample

```javascript
// Minimal reproduction code
```

Environment​

  • Refract version:
  • Node.js version:
  • Browser:
  • OS:

### Suggesting Enhancements

Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, include:

1. **Use case** - Why is this enhancement needed?
2. **Proposed solution** - How should it work?
3. **Alternatives considered** - What other solutions did you consider?
4. **Additional context** - Any mockups, diagrams, or examples

### Pull Requests

1. **Small, focused PRs** are easier to review and merge
2. **One feature/fix per PR**
3. **Include tests** for new features
4. **Update documentation** as needed
5. **Follow our coding standards**
6. **Write clear commit messages**

### Improving Documentation

Documentation improvements are always welcome! This includes:
- Fixing typos or clarifying language
- Adding examples
- Improving API documentation
- Translating documentation
- Writing tutorials or blog posts

### Contributing Examples

Share your Refract projects and examples:
1. Add to the `/examples` directory
2. Include a README with setup instructions
3. Keep dependencies minimal
4. Follow our code style

## Development Setup

### Prerequisites

- Node.js 16+ and npm 7+
- Git
- A code editor (VS Code recommended)
- Basic knowledge of JavaScript/TypeScript

### Initial Setup

1. **Fork the repository**
```bash
# Click "Fork" on GitHub, then clone your fork
git clone https://github.com/YOUR-USERNAME/refract.git
cd refract
  1. Add upstream remote

    git remote add upstream https://github.com/refract-js/refract.git
  2. Install dependencies

    npm install
  3. Build the project

    npm run build
  4. Run tests

    npm test
  5. Start development mode

    npm run dev

Development Tools​

VS Code Extensions​

We recommend these extensions for the best development experience:

  • ESLint
  • Prettier
  • TypeScript and JavaScript Language Features
  • Jest Runner
  • GitLens

Editor Configuration​

.vscode/settings.json:

{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}

Project Structure​

refract/
├── packages/
│ ├── core/ # Core framework
│ │ ├── src/
│ │ ├── tests/
│ │ └── package.json
│ ├── compiler/ # Compiler and build tools
│ ├── devtools/ # Browser DevTools
│ ├── router/ # Official router
│ └── testing/ # Testing utilities
├── examples/ # Example applications
├── docs/ # Documentation
├── scripts/ # Build and release scripts
├── benchmarks/ # Performance benchmarks
└── playground/ # Development playground

Key Directories​

  • packages/core/src - Core framework source code
  • packages/core/src/refraction - Reactivity system
  • packages/core/src/lens - Lens implementation
  • packages/core/src/components - Component system
  • packages/compiler - Build-time optimizations

Development Workflow​

Creating a New Feature​

  1. Create a feature branch

    git checkout -b feature/your-feature-name
  2. Make your changes

    • Write code
    • Add tests
    • Update documentation
  3. Test your changes

    npm test
    npm run lint
    npm run type-check
  4. Commit your changes

    git add .
    git commit -m "feat: add new feature"

Working on Core​

When modifying core functionality:

  1. Run core tests

    npm run test:core
  2. Test in playground

    npm run playground
  3. Check bundle size

    npm run size
  4. Run benchmarks

    npm run bench

Debugging​

  1. Enable debug mode

    window.__REFRACT_DEBUG__ = true;
  2. Use DevTools

    • Install Refract DevTools extension
    • Open browser DevTools
    • Navigate to "Refract" tab
  3. Add debug statements

    import { debug } from "@refract/core/debug";
    debug("component", "Component rendered", props);

Testing​

Running Tests​

# Run all tests
npm test

# Run specific package tests
npm run test:core
npm run test:compiler
npm run test:router

# Run tests in watch mode
npm run test:watch

# Run with coverage
npm run test:coverage

Writing Tests​

  1. Unit Tests - Test individual functions

    describe("useRefraction", () => {
    it("should initialize with default value", () => {
    const { result } = renderHook(() => useRefraction(0));
    expect(result.current.value).toBe(0);
    });
    });
  2. Integration Tests - Test component interactions

    it("should update child when parent state changes", async () => {
    const { getByText } = render(<ParentComponent />);
    fireEvent.click(getByText("Update"));
    await waitFor(() => {
    expect(getByText("Updated")).toBeInTheDocument();
    });
    });
  3. E2E Tests - Test full user flows

    test("user can complete checkout", async ({ page }) => {
    await page.goto("/shop");
    await page.click('[data-testid="add-to-cart"]');
    await page.click('[data-testid="checkout"]');
    // ... more steps
    });

Test Guidelines​

  • Write tests before fixing bugs
  • Aim for >80% code coverage
  • Test edge cases and error conditions
  • Use descriptive test names
  • Keep tests focused and isolated

Submitting Changes​

Commit Message Guidelines​

We follow Conventional Commits:

<type>(<scope>): <subject>

<body>

<footer>

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, etc.)
  • refactor: Code refactoring
  • perf: Performance improvements
  • test: Test additions or changes
  • build: Build system changes
  • ci: CI configuration changes
  • chore: Other changes

Examples:

feat(core): add support for async refractions
fix(compiler): resolve JSX transformation issue
docs(api): update useRefraction documentation
perf(core): optimize virtual DOM diffing

Pull Request Process​

  1. Update your fork

    git fetch upstream
    git rebase upstream/main
  2. Push to your fork

    git push origin feature/your-feature
  3. Create Pull Request

    • Go to GitHub
    • Click "New Pull Request"
    • Select your branch
    • Fill out the PR template
  4. PR Template:

    ## Description

    Brief description of changes

    ## Type of Change

    - [ ] Bug fix
    - [ ] New feature
    - [ ] Breaking change
    - [ ] Documentation update

    ## Testing

    - [ ] Tests pass locally
    - [ ] Added new tests
    - [ ] Updated documentation

    ## Screenshots (if applicable)

    ## Related Issues

    Closes #123
  5. Address Review Feedback

    • Make requested changes
    • Push updates
    • Reply to comments
    • Request re-review

Style Guidelines​

JavaScript/TypeScript​

  • Use TypeScript for new code
  • Follow ESLint configuration
  • Use Prettier for formatting
  • Prefer functional programming patterns
  • Avoid mutations when possible
// ✅ Good
const newArray = [...oldArray, newItem];
const newObject = { ...oldObject, key: value };

// ❌ Bad
oldArray.push(newItem);
oldObject.key = value;

Naming Conventions​

  • Files: kebab-case.ts
  • Components: PascalCase
  • Functions: camelCase
  • Constants: SCREAMING_SNAKE_CASE
  • Types/Interfaces: PascalCase

Code Organization​

// 1. Imports
import { external } from "package";
import { internal } from "@/internal";
import { relative } from "./relative";

// 2. Types/Interfaces
interface Props {
// ...
}

// 3. Constants
const DEFAULT_VALUE = 10;

// 4. Component/Function
export function Component() {
// ...
}

// 5. Exports
export { Component };

Documentation​

Writing Documentation​

  1. API Documentation

    • Use JSDoc comments
    • Include examples
    • Document parameters and return values
    /**
    * Creates a new refraction with the given initial value
    * @param {T} initialValue - The initial value
    * @returns {Refraction<T>} The refraction object
    * @example
    * const count = useRefraction(0);
    * count.set(1);
    */
  2. Guide Documentation

    • Use clear, simple language
    • Include code examples
    • Add diagrams where helpful
    • Test all code samples
  3. README Files

    • Every package needs a README
    • Include installation instructions
    • Provide usage examples
    • List API methods

Documentation Standards​

  • Use American English spelling
  • Write in present tense
  • Use active voice
  • Keep sentences concise
  • Include links to related topics

Community​

Getting Help​

Core Team​

Our core maintainers are:

  • @maintainer1 - Core architecture
  • @maintainer2 - Compiler & optimization
  • @maintainer3 - DevTools & DX
  • @maintainer4 - Documentation & community

Recognition​

Contributors are recognized in:

  • Our Contributors page
  • Release notes
  • Annual contributor spotlight
  • Special Discord role

License​

By contributing to Refract, you agree that your contributions will be licensed under the MIT License.



Thank you for contributing to Refract! Together, we're building the future of reactive UI development.