Contributing to Stati
Stati is an open-source project and we welcome contributions from the community! Whether you’re fixing bugs, adding features, improving documentation, or helping with testing, there are many ways to get involved.
Quick Start
- Fork the repository on GitHub
- Clone your fork locally
- Install dependencies with
npm install - Run the test suite with
npm test - Make your changes and add tests
- Submit a pull request
Development Setup
Prerequisites
- Node.js 22.0.0 or higher
- npm 11.5.1 or higher
- Git for version control
Local Development
# Clone the repository
git clone https://github.com/your-username/stati.git
cd stati
# Install dependencies
npm install
# Build all packages (core → cli → create-stati)
npm run build
# Run the test suite
npm test
# Lint and type-check
npm run lint
npm run typecheck
# Optional: watch core package TypeScript
npm run dev --workspace=@stati/core
Project Structure
stati/
├── packages/
│ ├── core/ # Core Stati engine
│ │ ├── src/
│ │ ├── tests/
│ │ └── package.json
│ ├── cli/ # Command-line interface
│ │ ├── src/
│ │ ├── tests/
│ │ └── package.json
│ └── create-stati/ # Project scaffolder
│ ├── src/
│ ├── tests/
│ └── package.json
├── examples/ # Example projects
│ ├── blog/
│ ├── docs/
│ └── blank/
├── docs/ # Project documentation
├── scripts/ # Build and development scripts
└── package.json # Root package.json
Monorepo Workflow
Stati uses a monorepo structure with multiple packages:
# Install dependencies for all packages
npm install
# Build all packages (required order: core → cli → create-stati)
npm run build
# Test all packages
npm run test
# Test specific package
npm run test --workspace=@stati/core
# Develop with a specific example
cd examples/blog
npm install
npm run dev
Making Changes
Code Style
Stati uses strict TypeScript and follows these conventions:
- ESLint for code linting
- Prettier for code formatting
- TypeScript strict mode
- Conventional Commits for commit messages
# Run linting
npm run lint
# Type checking
npm run typecheck
Testing
We maintain comprehensive test coverage:
# Run all tests
npm test
# Run tests with coverage
npm test -- --coverage
# Run specific test file
npm test -- packages/core/src/__tests__/build.test.ts
# Run tests in watch mode
npm test -- --watch
Test Categories
- Unit Tests - Test individual functions and classes
- Integration Tests - Test component interactions
- End-to-End Tests - Test complete workflows
- Example Tests - Validate example projects
Example test structure:
// packages/core/src/__tests__/build.test.ts
import { describe, it, expect } from 'vitest';
import { build } from '../../core/build.js';
describe('build', () => {
it('returns build statistics', async () => {
const stats = await build({ force: true });
expect(stats.totalPages).toBeGreaterThanOrEqual(0);
expect(stats.assetsCount).toBeGreaterThanOrEqual(0);
});
});
Contributing Guidelines
Types of Contributions
🐛 Bug Fixes
- Fix functionality issues
- Improve error handling
- Performance improvements
✨ New Features
- Add new Stati capabilities
- Extend plugin system
- Improve developer experience
📚 Documentation
- Fix typos and unclear sections
- Add examples and tutorials
- Improve API documentation
🧪 Testing
- Add test coverage
- Improve test reliability
- Add integration tests
🔧 Infrastructure
- Improve build process
- CI/CD improvements
- Development tooling
Pull Request Process
- Create an Issue first for significant changes
- Fork and Branch from
main - Make Changes with tests
- Update Documentation if needed
- Test Thoroughly across packages
- Submit PR with clear description
PR Template
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Refactoring
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests passing
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] No breaking changes (or properly documented)
Commit Messages
We use Conventional Commits:
# Format: <type>(<scope>): <description>
# Examples:
feat(core): add ISG aging algorithm
fix(cli): resolve build output path issue
docs(readme): update installation instructions
test(core): add markdown processing tests
refactor(templates): improve Eta helper organization
Types:
feat- New featuresfix- Bug fixesdocs- Documentation changestest- Test additions/changesrefactor- Code refactoringperf- Performance improvementschore- Maintenance tasks
Development Guidelines
TypeScript Standards
// Use strict TypeScript
interface StatiConfig {
site: SiteConfig;
markdown?: MarkdownConfig;
// ... other properties
}
// Prefer interfaces over types
interface BuildResult {
pageCount: number;
buildTime: number;
cacheHitRate: number;
}
// Use JSDoc for public APIs
/**
* Build a Stati site
* @param config - Site configuration
* @param options - Build options
* @returns Build result with statistics
*/
export async function build(config: StatiConfig, options: BuildOptions = {}): Promise<BuildResult> {
// Implementation
}
Error Handling
// Use custom error classes
export class StatiError extends Error {
constructor(
message: string,
public code: string,
public category: ErrorCategory,
) {
super(message);
this.name = 'StatiError';
}
}
// Provide helpful error messages
throw new StatiError(
`Template not found: ${templatePath}. ` + `Make sure the file exists and check the file path.`,
'TEMPLATE_NOT_FOUND',
'template',
);
Performance Considerations
// Use caching appropriately
const cache = new Map<string, CachedItem>();
function expensiveOperation(input: string): Result {
if (cache.has(input)) {
return cache.get(input)!.result;
}
const result = doExpensiveWork(input);
cache.set(input, { result, timestamp: Date.now() });
return result;
}
// Optimize for common cases
function processPages(pages: Page[]): ProcessedPage[] {
// Batch operations when possible
return pages.map((page) => processPage(page));
}
Release Process
Versioning
Stati follows Semantic Versioning:
- MAJOR - Breaking changes
- MINOR - New features (backward compatible)
- PATCH - Bug fixes (backward compatible)
Changesets
We use Changesets for version management:
# Add a changeset
npx changeset
# Version packages
npx changeset version
# Publish packages
npx changeset publish
Example changeset:
---
'@stati/core': minor
'@stati/cli': patch
---
Add ISG aging algorithm for intelligent cache TTL management. This feature automatically adjusts cache durations based on content age, improving performance for sites with mixed content freshness.
Release Notes
Each release includes:
- New Features with examples
- Bug Fixes with issue references
- Breaking Changes with migration guides
- Performance Improvements
- Documentation Updates
Documentation
Writing Style
- Clear and concise explanations
- Code examples for every concept
- Step-by-step instructions
- Real-world use cases
Documentation Structure
# Page Title
Brief description of what this page covers.
## Section 1
Explanation with code example:
```javascript
// Code example
const example = 'value';
```
Subsection
More detailed information.
Best Practices
- Tip 1
- Tip 2
- Tip 3
Next Steps
Links to related documentation.
### API Documentation
Use TypeScript interfaces for API docs:
```typescript
/**
* Configuration for Stati sites
*/
export interface StatiConfig {
/** Site metadata and settings */
site: SiteConfig;
/** Markdown processing configuration */
markdown?: MarkdownConfig;
/** Template engine settings */
templates?: TemplateConfig;
}
Community
Getting Help
- GitHub Discussions - Ask questions and share ideas
- GitHub Issues - Report bugs and request features
Code of Conduct
We follow the Contributor Covenant:
- Be respectful and inclusive
- Be patient with newcomers
- Be constructive in feedback
- Be collaborative in discussions
Recognition
Contributors are recognized in:
- Changelog for each release
- Contributors section in README
- All Contributors bot acknowledgment
Roadmap
Current Priorities
- Performance validation
- Benchmark build and cache behaviour using the bundled examples.
- Track Incremental Static Generation cache metrics.
- Developer experience
- Improve diagnostic output in the CLI.
- Expand automated test coverage for build edge cases.
- Documentation coverage
- Keep this docs-site in sync with shipped features.
- Add walkthroughs for the blank template workflow.
Getting Started Contributing
- Browse Issues - Look for “good first issue” labels
- Join Discussions - Introduce yourself and ask questions
- Start Small - Fix typos, add tests, improve docs
- Ask for Help - Don’t hesitate to ask for guidance
Good First Issues
- Documentation improvements
- Test coverage additions
- Error message improvements
- Example project enhancements
- Performance optimizations
Thank you for considering contributing to Stati! Every contribution, no matter how small, helps make Stati better for everyone. We’re excited to work with you and see what we can build together.
For questions about contributing, feel free to open a discussion on GitHub or reach out to the maintainers. We’re here to help and want to make contributing as smooth as possible for everyone.