Skip to content

Contributing

Guide for contributing to React Native Tailwind.

Terminal window
git clone https://github.com/mgcrea/react-native-tailwind.git
cd react-native-tailwind
pnpm install
Terminal window
pnpm build # Full build
pnpm build:babel # Compile TypeScript
pnpm build:babel-plugin # Bundle Babel plugin
pnpm build:types # Generate type declarations
Terminal window
pnpm test # Run all tests
pnpm lint # ESLint
pnpm check # TypeScript type check
pnpm spec # Jest tests
Terminal window
pnpm dev # Run example app
# or
cd example && npm run dev -- --reset-cache

The project uses a dual-build system:

  1. Main Package (ESM): src/dist/ via Babel

    • Compiled as ES modules
    • Excludes src/babel/ directory
  2. Babel Plugin (CommonJS): src/babel/dist/babel/index.cjs via esbuild

    • Must be CommonJS (Babel requirement)
    • Bundled into single self-contained file
    • Includes all parser code inline (~25KB)
src/
├── babel/
│ ├── plugin.ts # Main Babel plugin
│ ├── config-loader.ts # Tailwind config discovery
│ └── utils/ # Utility functions
│ ├── attributeMatchers.ts
│ ├── componentSupport.ts
│ ├── dynamicProcessing.ts
│ ├── modifierProcessing.ts
│ ├── styleTransforms.ts
│ ├── styleInjection.ts
│ └── twProcessing.ts
├── parser/
│ ├── index.ts # Parser orchestrator
│ ├── spacing.ts # Spacing utilities
│ ├── colors.ts # Color utilities
│ └── ... # Other parsers
├── utils/
│ └── styleKey.ts # Style key generation
└── index.ts # Main export
  1. Determine category: Does it fit in an existing parser or need a new one?

  2. Edit/create parser in src/parser/:

export function parseYourCategory(cls: string): StyleObject | null {
if (cls === 'your-class') {
return { yourStyle: 'value' };
}
return null;
}
  1. Register parser in src/parser/index.ts:
import { parseYourCategory } from './your-category';
const parsers = [
parseSpacing,
parseColor,
parseYourCategory, // Add here
// ...
];
  1. Export constants (if applicable) in src/index.ts

  2. Add tests in src/parser/__tests__/your-category.test.ts

  3. Rebuild: pnpm build

  1. Edit src/babel/plugin.ts or utilities in src/babel/utils/
  2. Run pnpm build (runs esbuild bundler)
  3. Test in example app
  4. Add/update tests
  1. Unit tests:
Terminal window
pnpm spec
  1. Example app:
Terminal window
cd example
npm run dev -- --reset-cache
  1. Type checking:
Terminal window
pnpm check
  1. Linting:
Terminal window
pnpm lint
  1. Fork the repository
  2. Create a feature branch:
Terminal window
git checkout -b feature/your-feature-name
  1. Make your changes
  2. Add tests for new functionality
  3. Run all checks:
Terminal window
pnpm test
  1. Commit your changes:
Terminal window
git commit -m "feat: add your feature"

Follow Conventional Commits:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • refactor: - Code refactoring
  • test: - Test changes
  • chore: - Build/tooling changes
  1. Push to your fork:
Terminal window
git push origin feature/your-feature-name
  1. Create a Pull Request on GitHub
  • Use TypeScript for type safety
  • Follow existing code patterns
  • Add comments for complex logic
  • Keep functions focused and small
  • Use meaningful variable names
  • Write tests for new features
  • Ensure existing tests pass
  • Test edge cases
  • Use descriptive test names

Example:

describe('parseSpacing', () => {
it('should parse margin classes', () => {
expect(parseSpacing('m-4')).toEqual({ margin: 16 });
});
it('should return null for invalid classes', () => {
expect(parseSpacing('invalid')).toBeNull();
});
});
  • Update README.md for new features
  • Add JSDoc comments for public APIs
  • Include examples in documentation
  • Update type definitions

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

Thank you for contributing! 🎉