Contribution Guidelines
Detailed guidelines for contributing to LLM4S with emphasis on code quality, testing, and documentation.
Table of Contents
- Contribution Guidelines
What Can You Contribute?
Code Contributions
- Features - New functionality aligned with roadmap
- Bug Fixes - Reported issues and edge cases
- Enhancements - Improvements to existing features
- Tests - Additional test coverage and edge case handling
Non-Code Contributions
- Documentation - Guides, examples, API docs
- Issue Triage - Help categorize and organize issues
- Community - Answering questions on Discord
The Contribution Workflow
1. Find or Create an Issue
Search first:
1
2
# GitHub Issues search
https://github.com/llm4s/llm4s/issues?q=is:issue+label:good-first-issue
Good first issues are marked with good-first-issue label.
Create if not found:
- For bugs: Use Bug Report template
- For features: Use Feature Request template
- For improvements: Use Enhancement template
Wait for response:
- Maintainers will provide guidance
- Confirm approach before coding
2. Fork and Setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Fork on GitHub (click button)
# Clone your fork
git clone https://github.com/YOUR-USERNAME/llm4s.git
cd llm4s
# Add upstream
git remote add upstream https://github.com/llm4s/llm4s.git
# Install pre-commit hook
./hooks/install.sh
# Create feature branch
git checkout -b feature/description
3. Make Your Changes
Follow conventions:
- Use
Result[A]for errors - Configure at app edge only
- Keep code immutable
- Use type-safe newtypes
- Run
sbt scalafmtAll
Write tests:
- Unit tests for new code
- Edge case coverage
- Cross-version tests if needed
Update docs:
- Scaladoc for public APIs
- User guides if needed
- Examples if appropriate
4. Test Thoroughly
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Format code
sbt scalafmtAll
# Compile
sbt +compile
# Run all tests
sbt +test
# Check coverage
sbt coverage test coverageReport
# Cross-compile everything
sbt buildAll
All must pass before submitting PR.
5. Submit Pull Request
Title format:
1
2
3
4
5
[TYPE] Brief description
[FEATURE] Add support for streaming with timeout
[BUG FIX] Fix token counting edge case
[DOCS] Update configuration guide
Include in your PR description:
- Clear description
- Issue references
- Testing approach
- Documentation updates
- Checklist verification
6. Respond to Feedback
- Be responsive to comments
- Ask for clarification if needed
- Push updates to same branch
- Conversation closes PR when satisfied
- Maintainers merge when ready
Code Standards
For detailed conventions (naming, style, import organization), see CONTRIBUTING.md.
Core principles - all code must follow:
- Error Handling: Use
Result[A]composable error handling, not exceptions - Configuration: Only read config at app edge (main, tests, samples), never in core modules
- Type Safety: Use newtypes for domain values (
ApiKey,ModelName,ConversationId) - Immutability: Prefer immutable data structures and functional updates
See CONTRIBUTING.md for detailed code pattern examples.
Testing Standards
See CONTRIBUTING.md for testing requirements and examples.
Quick checklist:
- ✅ Place tests in
modules/core/src/test/scala/org/llm4s/(mirror source structure) - ✅ Name test files with
Specsuffix (e.g.,AgentSpec.scala) - ✅ Test both happy path and error cases
- ✅ Use ScalaTest’s FlatSpec style
- ✅ Mock external dependencies with ScalaMock
- ✅ Maintain 80%+ statement coverage (excluding samples)
- ✅ Run
sbt +testbefore submitting PR
Documentation Standards
See CONTRIBUTING.md for basic format guidelines.
For advanced contributions:
- Scaladoc - Use @param, @return, @example tags; document error cases
- Guides - Add to
docs/guide/with overview, usage examples, troubleshooting - Examples - Place in
modules/samples/with clear comments - API Reference - Generated from Scaladoc; ensure code examples compile
Release Process
The LLM4S team manages releases. Your contributions will be included automatically.
Version Numbering
Pre-release (0.x.y):
- API may change between versions
- Current stable: 0.1.0-SNAPSHOT
Stable (1.0.0+):
- Follows semantic versioning
- MiMa checks for binary compatibility
- Breaking changes require major version bump
Performance Considerations
JVM Optimization
1
2
3
4
5
6
7
8
9
// Prefer immutable collections
val list: Seq[Message] = messages :+ newMessage
// Avoid unnecessary object creation
val result = messages.map(_.role) // Good
val result = messages.map(m => m.role) // Also good
// Prefer lazy evaluation where appropriate
lazy val config = Llm4sConfig.provider()
Getting Help
- CONTRIBUTING.md - Complete contributor guide
- AGENTS.md - Repository structure and build commands
- CLAUDE.md - Developer patterns and guidelines
- Discord: https://discord.gg/4uvTPn6qww
- GitHub Discussions: https://github.com/llm4s/llm4s/discussions
For help, common issues, and build problems, see CONTRIBUTING.md.