Contributing
July 10, 2026 · View on GitHub
Getting Started
- Setup Flutter
- Make sure
flutteranddartare both in your PATH. Rundart --versionandflutter --versionto check. - Clone this repository and
cdinto it. - Install Melos by running:
dart pub global activate melos. Melos is used to manage the Monorepo structure and links all packages. - Run
melos bootstrapdownload all other dependencies (usuallyflutter pub getis used). If you use Android Studio or VS Code, the files for your IDE are also set up. - Run
dart pub getto initialize the StudyU root project. This will apply a consistent lint style to all packages.
If you use Android Studio or VS Code, open the root folder of the project. You
should have new run-configurations/tasks added for running the Flutter apps or
executing Melos scripts. Use melos <script> to run scripts from the
pubspec.yaml file. You can find more information about Melos in
the Melos documentation
Repository Overview
We have different Flutter/Dart packages all contained in this monorepo. The StudyU platform consists out of the following packages:
- StudyU App: Participate in N-of-1 trials
- StudyU Designer v2: Design and conduct your own N-of-1 trial
Dependency packages:
- Core: shared code for all applications
- Flutter Common: shared code for all Flutter apps (App, Designer)
Environments
We use .env (environment) files, to specify the environment variables such as
Supabase instance and other servers. We have multiple configurations stored
under flutter_common/lib/envs/. By default .env (see below) is used, which
is our production environment. We can specify the other files by using e.g.
--dart-define=STUDYU_ENV=.env.local. This can also be added to the run
configuration in Android Studio or VS Code.
flutter build/run android/web/... --dart-define=STUDYU_ENV=.env.dev/.env.prod/.env.local/...
Below is an example for an environment file such as
flutter_common/lib/envs/.env.
STUDYU_SUPABASE_URLS=https://project-id.supabase.co,https://backup-database-url.supabase.co
STUDYU_SUPABASE_PUBLIC_ANON_KEY=your-public-anon-key
STUDYU_PROJECT_GENERATOR_URL=https://studyu-project-generator-2zro3rzera-ew.a.run.app
STUDYU_APP_URL="https://app.studyu.health/"
STUDYU_DESIGNER_URL="https://designer.studyu.health/"
Additionally, we have the following environment files:
.env: Production database used by default.env.dev: Development database used by dev branch.env.local: Local database for a custom Supabase instance (used by the Supabase CLI)
Ideally, we should only use the development database or a local one for all our development work.
Coding on core
Changes to the models in the core package requires to perform a re-generation
of the JSON IO code. The toolchain we use for this consists of build_runner
and json_serializable.
After you made changes to the models, update the generated IO code by running melos generate.
Contrary to most recommendations, we commit those generated files (*.g.dart) to Git. This
is needed, because core is a dependency of the StudyU App and the StudyU Designer
and dependencies need to have all files generated, when being imported.
Code Style
We use the Effective Dart
guidelines for Dart and Flutter. Run fvm exec melos qualitycheck to
format, analyze, and regenerate code.
Optional RTK output filtering
This repository includes .rtk/filters.toml for RTK, a CLI proxy that compresses noisy command output. RTK is optional; without it, run the documented commands normally.
If RTK is installed, prefix Flutter, Dart, FVM, or Melos commands with rtk for shorter output:
rtk fvm exec melos qualitycheck
Frontend
We use Flutter's Material Design with a custom light theme defined in app/lib/theme.dart.
Prefer Theme.of(context).colorScheme over hardcoded colors. For responsive layouts, use
LayoutBuilder and MediaQuery. Localization is handled via flutter_localizations with
ARB files in app/lib/l10n/.
Commits
We use Conventional Commits for all commit messages. The format is:
<type>(<scope>): <description>
Common types: feat, fix, chore, docs, refactor, test, style.
Scopes match the package name: app, designer, core, flutter_common, db.
Examples from this repo:
fix: remove redundant fitbit labelfeat(designer): move fitbit credentials to study-levelchore: update deps + ios deps
Pull Requests
For any new features or bug fixes, create a new branch and open a pull request. Every pull request should include the following:
- Clear title using Conventional Commits format (e.g.,
fix(designer): resolve drag-and-drop issue) - Description explaining the change, motivation, and any related issues
- Screenshot or video demonstrating the changes — this is required for all PRs. Use a screen recording for interactive changes and a screenshot for static ones.
- Testing steps so reviewers can verify the change locally
PR Checklist
-
fvm exec melos qualitycheckpasses - Screenshot or video of the changes attached
- Description links related issues
Code Reviews — Conventional Comments
We use Conventional Comments for all review feedback. This standard makes the intent behind each comment clear and actionable.
Format
<label> [decorations]: <subject>
[discussion]
Labels
| Label | Purpose |
|---|---|
| praise: | Highlight something positive. Leave at least one per review. |
| nitpick: | Trivial preference-based request. Non-blocking by nature. |
| suggestion: | Propose an improvement. Be explicit about what and why. |
| issue: | Highlight a specific problem. Pair with a suggestion when possible. |
| todo: | Small, necessary change that must be done before merging. |
| question: | Ask for clarification when you're unsure if something is a problem. |
| thought: | Share an idea that came up during review. Non-blocking. |
| chore: | A process-related task needed before acceptance (e.g., run CI job). |
| note: | Non-blocking observation the reader should be aware of. |
Decorations
Add decorations in parentheses for extra context:
- (non-blocking) — should not prevent merging
- (blocking) — must be resolved before merging
- (if-minor) — resolve only if the fix is trivial
Examples
suggestion (non-blocking): Consider extracting this into a helper method.
It appears in three places and the logic is identical.
issue (blocking): This query fetches all rows without pagination.
On tables with 10k+ rows this will timeout. Can we add a LIMIT clause?
praise: Great use of the builder pattern here — very readable.
Flutter Version Management
The StudyU monorepo uses the FVM tool to manage the Flutter
SDK version. This allows us to have a consistent Flutter version across all
packages. The Flutter SDK version is specified in the .fvmrc file in the root
directory. To install the Flutter SDK version, run fvm install in the root directory.
You might also want to integrate FVM within your IDE. For Android Studio you can change the Flutter
SDK path in the settings for the Flutter plugin. Open the Android Studio settings and navigate to
Languages & Frameworks -> Flutter -> Flutter SDK path and set the path to the FVM Flutter SDK
(<path to the studyu repository>/.fvm/flutter_sdk). The Dart SDK path should be changed
respectively to (<path to the studyu repository>/.fvm/flutter_sdk/bin/cache/dart-sdk). For VS
Code, have a look at the FVM documentation.
Using FVM with melos requires setting the MELOS_SDK_PATH environment variable to the path of the
FVM Flutter SDK. This can be done by running export MELOS_SDK_PATH=.fvm/flutter_sdk in the
terminal. This is needed to ensure that melos uses the correct Flutter SDK version.
Database and Backend
We are using a self-hosted instance of Supabase as a Backend-as-a-Service provider. Supabase provides different backend services such as a database, API, authentication, storage service all based around PostgreSQL and other FOSS. Since Supabase is open-source, we are hosting our own instance to ensure data privacy and security. For development purposes, Supabase can be self-hosted by using the Supabase CLI. Have a look into the /supabase/README.md file for a guide on how to run the Supabase CLI for StudyU.
Create new database migrations with the Supabase CLI (supabase migration new <name>) and commit the generated SQL under supabase/migrations/. Legacy migration files in database/migration-legacy/ are documented in supabase/README.md.