-
-
Notifications
You must be signed in to change notification settings - Fork 638
Open
Labels
Description
Add RBS Type Signatures to Improve Developer Experience
Problem
Currently, both shakapacker and react_on_rails lack static type information for their Ruby APIs. This means:
- IDEs cannot provide accurate autocomplete or type hints
- Type errors are only caught at runtime, not during development
- API documentation is limited to comments and external docs
- Refactoring is riskier without type checking
Proposal
Adopt RBS (Ruby Signature) files to provide static type information for our public APIs, following the pattern successfully used in the package_json gem.
What is RBS?
RBS is Ruby's official type annotation system that:
- Lives in separate
.rbsfiles (usuallysig/directory) - Keeps Ruby code clean without inline type annotations
- Provides machine-readable type information for tools
- Enables static type checking with tools like Steep or TypeProf
- Powers IDE features like autocomplete and error detection
Benefits
For Users
- Better IDE Support - Accurate autocomplete and inline type hints
- Catch Errors Earlier - Type checker catches issues before runtime
- Self-Documenting - Types are explicit and machine-readable
- Safer Refactoring - Type checker catches breaking changes
For Maintainers
- Clearer Interfaces - Types document expected inputs/outputs
- Reduce Bugs - Catch type mismatches during development
- Easier Onboarding - New contributors understand APIs faster
- Consistent with Ecosystem - Many gems adopting RBS
Proposed Phased Rollout
Phase 1: Core Public APIs (Week 1-2)
-
react_on_rails:
ReactOnRails.configureand configuration classesReactOnRails::Helpermodule (react_component, etc.)- Component registration methods
-
shakapacker:
Shakapacker.configand configuration classesShakapacker::Helpermodule- Manifest and compiler interfaces
Phase 2: Helper Modules & Utilities (Week 3-4)
- View helpers and rendering methods
- Internal utilities with public interfaces
- Error classes and exceptions
Phase 3: Internal APIs (Optional, as needed)
- Private methods used across multiple files
- Complex internal data structures
- Integration points
Example
Before (no type information):
# lib/react_on_rails/helper.rb
def react_component(name, props = {}, options = {})
# ...
endAfter (with RBS):
# lib/react_on_rails/helper.rb (unchanged)
def react_component(name, props = {}, options = {})
# ...
end# sig/react_on_rails/helper.rbs (new)
module ReactOnRails
module Helper
def react_component: (
String name,
?Hash[untyped, untyped] props,
?Hash[Symbol, untyped] options
) -> String
end
endImplementation Checklist
- Create
sig/directory structure - Add RBS to development dependencies
- Document RBS usage in CONTRIBUTING.md
- Start with Phase 1 APIs
- Set up type checking in CI (optional, can defer)
- Add examples to documentation
Resources
Questions for Discussion
- Should we start with
shakapackerorreact_on_railsfirst? - Do we want to enable type checking in CI, or just provide signatures?
- Should we include type signatures for internal/private APIs?
Success Criteria
- Core public APIs have complete RBS signatures
- IDE autocomplete works for main methods
- No negative impact on existing users (backward compatible)
- Documentation updated to reference type signatures
Note: This is a non-breaking enhancement. RBS files are optional and don't affect runtime behavior for users who don't use them.