Thank you for your interest in contributing to Lychee! This guide will help you get started with contributing to the project.
Before you start contributing, we recommend reviewing our documentation structure:
- Overview - High-level introduction to Lychee
- Core Concepts - Domain model and fundamental concepts
- Reference Documentation - Coding conventions, frontend architecture
- Architecture Documentation - Knowledge map and feature specs
This will help you navigate the codebase more effectively.
- Fork the repository on GitHub
- Clone your fork locally
- Set up your development environment
- Create a new branch for your feature or bug fix
- Make your changes
- Test your changes
- Submit a pull request
- PHP 8.4 or higher
- php extensions:
php-curlphp-mbstringphp-xmlphp-mysql(usually used for your local database)php-gdphp-zipphp-bcmathphp-imagickphp-exifphp-opensslphp-redisphp-intlphp-sqlite3(recommended for running the tests)
- Composer
- Node.js and npm
- make
-
Clone the repository:
git clone https://github.com/YOUR_USERNAME/Lychee.git cd Lychee -
Install PHP dependencies:
composer install
-
Install JavaScript dependencies:
npm install
-
Set up your environment configuration:
cp .env.example .env php artisan key:generate
-
Set up the database:
- Create a new database (e.g.,
lychee) - Update the
.envfile with your database credentials - Run the migrations:
php artisan migrate
- Create a new database (e.g.,
-
Start the front-end development server with hot reloading:
npm run dev
We follow strict coding standards for PHP development:
- PSR-4 coding standard is applied throughout the codebase (in practice, this means that the filename should match the class name and be in the correct directory structure)
- Variable names should be in
snake_case(rector is used to enforce this) - Use strict comparison
===instead of loose comparison==(phpstan will validate this) - Only booleans should be used in if statements, not integers or strings (phpstan will validate this)
- Use
in_array()withtrueas the third parameter for strict comparison (phpstan will validate this) - Avoid code duplication in both if and else statements
- Do not use
empty()- use explicit checks instead (phpstan will validate this) - All new files must contain the license header with a single blank line after the opening PHP tag (just take example on an existing file)
- In Request classes,
$this->useris reserved for the user making the request - In Request classes, if a user is provided by the query, it should be placed in
$this->user2 - Resource classes used for the serialization of the response should extend from Spatie Data instead of JsonResource. In the case of Collections, in order to get proper typing, use
#[LiteralTypeScriptType('...')]This will ensure that the types responses types are properly generated. - We use Vue3 instead of Blade views
- If you modify or add a Resource class, ensure that the TypeScript types are properly generated by running:
php artisan typescript:transform npm run format
- Use TypeScript in composition API for Vue3
- Use PrimeVue for UI components
- Do not use
awaitasync calls in Vue3, use.then()instead - Do not use arrow functions for function declarations: use
function functionName() {}instead ofconst function = () => {}
Read more here: Frontend Architecture
Before submitting your pull request, ensure all quality checks pass:
Run PHPStan for static analysis:
make phpstanRun the test suite (note that this will use sqlite3 as a database, so that you can have test data on your mysql database and run the tests in parallel):
make test_v2
make test_unitApply code formatting:
make formattingRun TypeScript type checking:
npm run checkRun linting:
npm run lint- Create a new branch for your feature or bug fix:
git checkout -b feature/your-feature-name-
Make your changes following the coding standards above
-
Test your changes using the quality assurance commands
-
Commit your changes with a clear and descriptive commit message:
git commit -m "Add feature: description of your changes"- Push your branch to your fork:
git push origin feature/your-feature-name- Create a pull request on GitHub with:
- A clear title describing the change
- A detailed description of what was changed and why
- References to any related issues
- Screenshots (if applicable for UI changes)
AI-assisted development is permitted and welcomed. However, contributions using AI tools must follow our Specification-Driven Development (SDD) workflow:
-
Read AGENTS.md first — This file contains the instructions that guide AI agents working on this codebase. It defines the workflow, guardrails, and expectations for AI-assisted development.
-
Follow Spec-Driven Development — AI-generated code must be anchored in explicit specifications:
- Start by creating or updating the feature specification at
docs/specs/4-architecture/features/<NNN>-<feature-name>/spec.md - Generate a feature plan (
plan.md) and tasks checklist (tasks.md) - Write tests before implementation (test-first cadence)
- Use the templates in
docs/specs/templates/for consistency
- Start by creating or updating the feature specification at
-
Understand before generating — AI tools should explore and understand the existing codebase before proposing changes. Use the documentation structure in
docs/specs/to build context. -
Quality gates still apply — All AI-generated code must pass the same quality checks as human-written code:
- PHPStan static analysis
- Full test suite
- Code formatting (php-cs-fixer, Prettier)
- TypeScript type checking
-
Review and understand all output — Contributors are responsible for understanding and validating any AI-generated code before submitting. Do not submit code you don't understand.
-
Document open questions — When AI encounters ambiguity, log questions in
docs/specs/4-architecture/open-questions.mdand wait for clarification before proceeding.
We recommend using Claude Sonnet or Claude Opus for AI-assisted contributions. Avoid free-tier models from GitHub Copilot as they tend to hallucinate heavily and struggle to follow structured task files.
When using Claude Code, reference @AGENTS.md as the first step in your conversation to guide the agent through the SDD workflow.
For SDD contributions, we recommend splitting your work into two pull requests:
- Specification PR — Submit the spec, plan, and tasks files first. This allows maintainers to review the proposed approach before implementation begins.
- Implementation PR — Once the specification is approved, submit the implementation that builds from the approved spec.
This workflow ensures that:
- The specification can be reviewed and refined before any code is written
- Time and resources are not wasted on implementations that don't align with project goals
- The spec serves as a clear contract for what the implementation should deliver
The full SDD workflow is not required for trivial changes such as:
- Typo fixes
- Single-line bug fixes with obvious solutions
- Minor documentation corrections
- Simple configuration changes
For these cases, a direct PR without specifications is acceptable. Use your judgment — if the change requires design decisions or affects multiple files, use SDD.
Specification-Driven Development ensures that AI-assisted contributions:
- Are traceable back to explicit requirements
- Follow established architectural patterns
- Maintain test coverage organically
- Don't introduce undocumented behavior or "magic" code
- Keep your changes focused and atomic
Write clear, descriptive commit messagesWe don't care about the commit messages, as our commit history is squashed when merging pull requests. Just make sure that the final diff is clean.- Include tests for new functionality
- Update documentation if necessary
- Ensure all quality checks pass (i.e., run
make phpstan,make test_v2, andnpm run check) - Be responsive to feedback during code review (if you are not responsive, we will close the pull request after 2 weeks of inactivity).
We welcome bug reports and feature requests, however we no longer allow the creation of github issues. This is to ensure that we can focus on the most important issues and features without being overwhelmed by noise.
When creating an issue, you will be proposed to create a discussion instead. We will do our best to reply to those and transform them into issues when necessary. Please make sure to follow the template provided in the discussion. If you are asked with further question to clarify, please make sure to reply within 2 weeks, otherwise we will reserve the right to close the discussion.
If you need help or have questions:
- Check the existing documentation
- Review the documentation structure to understand how Lychee is organized
- Check the already existing discussions (closed and open).
- Check the already existing issues and pull requests.
- Create a new discussion if necessary or join our discord and post into the #help channel.
Thank you for contributing to Lychee! 🌸
Last updated: January 21, 2026