Contributing to Ascendara
Thank you for your interest in contributing to Ascendara! This guide covers how to set up the project, the conventions the codebase follows, and how to submit changes. Accepted contributions are credited in the Ascendara changelog.
Getting Started
Prerequisites
- Node.js 22 (CI uses 22.14.0) and Yarn 1.x
- Python 3.12 (for the helper tools)
- Git
- Rust and Cargo (Rust 1.90 or newer, for the Downloader, Game Handler, and Crash Reporter)
- Visual Studio Build Tools with the Windows SDK (Windows, for native dependencies)
See Building from Source for the full setup, including optional Firebase configuration.
Setting Up Your Environment
-
Fork the repository on GitHub.
-
Clone your fork:
git clone https://github.com/YOUR_USERNAME/ascendara.git cd ascendara -
Install dependencies:
yarn install pip install -r requirements.txt -
Start the development app:
yarn start
yarn install also sets up a Husky pre-commit hook that runs Prettier on staged files through lint-staged.
Code Style
Formatting and Linting
- Prettier formats JavaScript, JSX, JSON, Markdown, HTML, and CSS: 2-space indentation, double quotes, a 90-character line width, and sorted Tailwind classes. Translation files in
src/translations/are key-sorted automatically. - ESLint checks
src,electron, the achievement watcher, and scripts.
yarn format # format everything
yarn format:check # check formatting without writing
yarn lint # run ESLintJavaScript/React
- Use functional components with hooks.
- Follow the existing naming conventions:
- Components:
PascalCase - Functions and variables:
camelCase - Constants:
UPPER_SNAKE_CASE
- Components:
- Prefer
async/awaitover.then()chains. - Put user-facing text in
src/translations/en.jsonand read it witht("section.key"). Don't hardcode UI strings.
Python
- Follow PEP 8.
- Write JSON state files atomically, as the existing tools do, because the app reads them while the tools run.
- Keep platform-specific paths for Windows, macOS, and Linux in sync with the other tools.
Rust
- Format with
cargo fmtand keepcargo clippyclean. - Build with
--lockedsoCargo.lockstays the source of truth. - Keep the tool's command line, game files, and log format compatible with the app, which reads them while the tool runs.
CSS/Styling
- Use Tailwind CSS utility classes and the existing shadcn/ui components in
src/components/ui/. - Use theme color tokens (such as
bg-card,text-primary,text-muted-foreground) instead of fixed colors so every theme works.
Making Changes
Branches
Active development happens on the development branch, which is merged into main for releases. Use a descriptive branch name for your work:
feature/add-game-sortingfix/download-progress-bugdocs/update-api-reference
Commit Messages
Use the conventional commit format:
type(scope): subject
# Examples:
feat(big-picture): offer to start steam before launching online-fix games
fix(index): only ask for help when the shared index is stale
ci: write release descriptions from the changelogTypes:
feat: New featurefix: Bug fixdocs: Documentation changesrefactor: Code refactoringstyle: Formatting changestest: Adding or changing testsci: Build and release automationchore: Maintenance tasks
Pull Request Process
- Create a feature branch.
- Make your changes with clear commits.
- Check your work:
- Run
yarn lintandyarn build - Run the app with
yarn startand check the DevTools console for errors - Test on Windows (the primary platform), and on Linux or macOS if your change affects them
- Run
- Update the documentation if needed. The docs live in the Ascendara docs repository.
- Submit a pull request with:
- A clear description of the change
- Screenshots for UI changes
- References to related issues
Pull requests to main run the Source checks workflow, which installs dependencies and builds the renderer.
Development Guidelines
Adding New IPC Handlers
- Choose the right module in
electron/modules/, or create one and register it fromelectron/app.js. - Add the handler:
Use
ipcMain.handle("new-handler", async (_, param1, param2) => { try { return { success: true, data: result }; } catch (error) { console.error("Error in new-handler:", error); return { success: false, error: error.message }; } });_for the event parameter when you don't need it. - Expose it in
electron/preload.js:newHandler: (param1, param2) => ipcRenderer.invoke("new-handler", param1, param2), - Call it from React with
window.electron.newHandler(...). - Document it in the IPC Reference.
Every ipcMain.handle registered after startup is wrapped by electron/modules/security.js, which rejects calls that don't come from Ascendara's own window. Don't add handlers that accept arbitrary file paths or URLs without validating them. Prefer a named preload API over the legacy window.electron.ipcRenderer bridge.
Adding New Pages
- Create the component in
src/pages/. - Add the route in
src/app.jsx. - Add navigation in
src/components/Navigation.jsxif the page needs a navigation item. - Add any searchable settings to
src/lib/settingsSearchData.js. - Follow existing page patterns for consistency.
Adding Translations
Add new keys to src/translations/en.json only. The other built-in languages are generated from the English file with machine translation, so manual edits to them are overwritten. See Language Translator.
Modifying the Helper Tools
- Make changes in
binaries/{tool}/src/. - Build and run the tool directly first. Rust tools use Cargo; Python tools run with Python:
cd binaries/AscendaraDownloader && cargo test && cargo build --release python binaries/AscendaraNotificationHelper/src/AscendaraNotificationHelper.py --help - Build the executable with the platform build script. See Creating the Tools.
- Test the built executable from a packaged build.
Testing
Automated Checks
yarn lint
yarn build
python -m unittest discover -s tests # Python tests for build and release scriptsManual Testing Checklist
Before submitting a PR, verify:
- The app starts without errors
- There are no new console errors in DevTools
- Your feature works as expected
- Existing features still work
- The UI looks correct in light and dark themes
- Settings persist after a restart
Testing Downloads and Game Launches
Note: Games can't be launched in development mode, and some API features are unavailable in source builds. Use a packaged build to test these flows.
Build the app (see Building from Source), then run it from dist/win-unpacked/ on Windows, or from the AppImage or .app on Linux and macOS.
Areas for Contribution
Good First Issues
Look for issues labeled good first issue on GitHub. These are typically:
- Documentation improvements
- Minor UI tweaks
- Bug fixes with clear reproduction steps
Feature Requests
Check the roadmap and GitHub issues for planned features. Comment on an issue before starting work to avoid duplicates.
Documentation
Documentation improvements are always welcome:
- Fix typos or unclear explanations
- Add examples
- Update outdated information
Getting Help
- Discord: ascendara.app/discord
- GitHub Issues: For bug reports and feature requests
Code of Conduct
Please follow the Code of Conduct:
- Be respectful and inclusive
- Provide constructive feedback
- Help others learn and grow
- Focus on the code, not the person
License
By contributing to Ascendara, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing to Ascendara!