Xolo API Hub is a premium open-source Flutter mobile API client, and contributions from the community are very welcome. Whether you want to fix a bug, improve documentation, or build a new feature, this guide walks you through everything you need — from cloning the repository to submitting a pull request that passes the quality gate. Found a bug first? Open an issue. Have a bigger idea? Start a discussion before writing code.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JonathanHerSa/xolo-api-hub/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Before you begin, make sure the following tools are installed and available on yourPATH:
| Tool | Minimum version | Notes |
|---|---|---|
| Flutter SDK | 3.32.0 | Pinned in CI (qa.yml). Use FVM or the official installer to pin this version. |
| Dart SDK | ^3.10.4 | Bundled with Flutter 3.32.0; declared in pubspec.yaml. |
| Git | Any recent version | Required for forking and branching. |
| Android SDK | API level 21+ | Required for running emulator tests; flutter_launcher_icons sets min_sdk_android: 21. |
Local Setup
Fork and clone the repository
Fork the project on GitHub, then clone your fork locally:Add the upstream remote so you can pull future changes:
Install Flutter dependencies
Fetch all pub packages declared in This resolves Drift, Riverpod,
pubspec.yaml:go_router, Dio, and the rest of the dependency tree.Run code generation
Xolo uses Drift for reactive SQLite persistence. Drift generates
a This writes the generated file to
database.g.dart file via build_runner. You must run this before the app or tests will
compile:lib/data/local/database.g.dart. The --delete-conflicting-outputs
flag avoids stale-cache errors during re-runs.Verify static analysis
Xolo enforces strict analysis with zero issues tolerated. Confirm your setup is clean:You should see
No issues found! before making any changes. If you see existing issues, check
that your Flutter version matches the pinned 3.32.0.Code generation (
build_runner) must be re-run any time you modify lib/data/local/tables.dart
or add a new Drift table. Forgetting this step will cause compilation errors in
database.g.dart referencing columns or queries that do not exist yet.Project Conventions
Consistency across the codebase makes reviews faster and keeps the quality gate green. Please follow these conventions for all new code.Architecture
Xolo follows a clean layered architecture:- Core — router, themes, secure storage, HTTP client, logging utilities.
- Domain — repository contracts (
XoloRepository), domain entities, and mappers that are completely independent of Drift row types. - Data — Drift database,
DriftXoloRepositoryimplementations, import and sync services. - Presentation — screens, reusable widgets, and Riverpod providers.
xoloRepositoryProvider only. Direct access to Drift tables, queries, or the AppDatabase instance from a screen, widget, or provider is not permitted. The repository layer is the single source of truth for the presentation tier.
Domain Services
New domain services (anything underlib/domain/services/ or lib/core/services/) must be pure classes — they may not import package:flutter/... or any Drift type directly. This constraint ensures every domain service is 100% unit-testable without spinning up a Flutter widget tree or a real SQLite database.
State Management
Use Riverpod providers for all shared state. AvoidsetState except for isolated, self-contained widget internals (e.g., an animation controller that does not affect external state). Providers that fetch or mutate repository data should return AsyncValue and use ref.watch / ref.read correctly according to Riverpod 3.x conventions.
Naming Conventions
| Suffix | What it applies to |
|---|---|
*Entity | Domain objects returned by the repository layer (e.g., RequestEntity, CollectionEntity) |
*Provider | Riverpod providers (e.g., collectionsProvider, requestControllerProvider) |
*Screen | Full-page route destinations (e.g., ComposerScreen, HistoryScreen) |
*Widget | Reusable sub-tree components (e.g., RunProgressList, AuthTabWidget) |
Internationalization
Xolo ships with full English and Spanish translations. Every user-visible string must be added to both locale files before a PR will be accepted.ARB Files
Locale strings live in:lib/l10n/app_en.arb— English (template locale, as declared inl10n.yaml)lib/l10n/app_es.arb— Spanish
l10n Configuration
The localization pipeline is configured inl10n.yaml:
gen-l10n tool reads these settings and writes the generated AppLocalizations class to lib/l10n/app_localizations.dart. The generated files are committed to the repository.
Using Strings in Widgets
Access localized strings viaAppLocalizations.of(context)!:
en and es, as declared in AppLocalizations.supportedLocales.
Adding a New Screen
Create the screen file
Add a new Dart file under
lib/presentation/screens/. Follow the *Screen naming convention:Register the route
Add the new route to
lib/core/router/app_router.dart. Xolo uses go_router for navigation.
Follow the existing route naming patterns — named routes use camelCase identifiers:Add Riverpod providers
If your screen needs data or actions, create a dedicated provider file under
lib/presentation/providers/. Provider files are named after the feature they support
(e.g., my_feature_provider.dart). Keep providers focused — one provider file per feature
domain keeps the codebase navigable.Write tests
Every new screen or provider requires corresponding tests before the PR can merge:
- Widget tests — place in
test/presentation/and useProviderScopewith mock overrides. - Integration tests — required for flows that involve navigation or multi-step user interactions.