Library / SDK
meditohq/medito-app avatar
meditohq/medito-app

Medito, a free Flutter meditation app with a mock mode that needs no credentials

The Medito app is a 100% free meditation app built with flutter. The app is available on Android and iOS.

1,329 stars171 forksDartAGPL-3.0

At a glance

What is it?
Medito is a Flutter meditation app for Android and iOS, published by the Medito Foundation on the claim that nobody should have to pay to meditate. The repository is set up for outside contributors unusually well: a mock mode intercepts every network call and returns hardcoded data, so you can run the app with no API keys, no Firebase and no Stripe, and a signed APK verification guide for anyone installing outside the stores.
Who is it for?
Adopt this repository as a reference implementation if you are building a Flutter app with native code bridges, Riverpod state and Pigeon, because the structure shows all three wired together with a working mock mode, but treat it as a codebase to learn from rather than a product to ship, since the meditation content inside it is under a custom licence separate from the AGPL that covers the app.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Dart, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The premise, stated plainly

The project description is a position rather than a feature list. Meditation can positively transform people's lives, and the foundation's belief is that no one should have to pay for it, so the Medito app is free forever, with no ads, no spam, and no need to sign up or pay. It is aimed at people who have never meditated before or want to deepen an existing practice. The app is a Flutter project for Android and iOS, maintained by the Medito Foundation and its community, and distributed through Google Play and the App Store, with an APK offered as a third route. The default branch is develop, which is a signal that the stable releases are cut from it, and the repository is not archived, with the last push on 2026-10-15. The tagged releases are older and are marked deprecated in their titles, the newest being v2.0.48 from 2022-06-21, so the app is distributed through the stores rather than through GitHub releases.

bash
git clone https://github.com/meditohq/medito-app.git
cd medito-app
flutter pub get

Mock mode, and why it is the best part of the repository

The contributor setup is the strongest argument for this codebase, and it is unusual in a way worth copying. Contributors can run the app without any API keys or Firebase setup using mock mode, where all network calls are intercepted and return hardcoded sample data, so no real credentials are needed. The run command carries a dart define that switches it on, and the documentation states what gets skipped: Firebase, the paywall webview, Stripe and the Meta SDK. The application then runs with sample content, so you can work on the UI and the logic without credentials. The remaining friction is small and specific. The Android side needs a keystore.properties file copied from the example and filled in, and the debug keystore that the Android SDK creates at ~/.android/debug.keystore has the password, key password and alias android, android and androiddebugkey, which is exactly the detail a contributor otherwise loses half an hour to.

bash
flutter run --flavor dev --dart-define=MOCK_MODE=true -d <device-id>

Pigeon and Riverpod: the two code generators

Two generators run before the app will build, and both are named in the documentation with the exact command. Pigeon generates the code required to communicate with native iOS and Android code, with pigeon_conf.dart holding the Android-only APIs and each file in pigeons/ being a separate input, one example given being watch_presence.dart, which also generates Swift. The loop runs the generator over the config file and then over every file in the pigeons directory. Riverpod's code generation is the second step, run with build_runner using the delete-conflicting-outputs flag so a stale generated file never survives a renamed annotation. The presence of a pigeons/ directory and a pigeon_conf.dart at the repository root tells you the native bridge surface is broad, and a widgetbook/ directory at the top level suggests the components are also catalogued in a component gallery for visual work.

bash
for f in pigeon_conf.dart pigeons/*.dart; do flutter pub run pigeon --input "$f"; done
dart run build_runner build --delete-conflicting-outputs

Three run configurations, defined in two places

The project supports separate development and production configurations, and the documentation explains how to use them in two IDEs. In Visual Studio Code you add entries to a .vscode/launch.json file, which is gitignored so each developer maintains their own, and the sample shows three: Flutter (Dev), which passes the dev flavor and reads its defines from a ../.staging.json file, Flutter (Prod), which passes the prod flavor, and Flutter (Mock), which combines the dev flavor with the MOCK_MODE dart define. In Android Studio you pick the same three from a dropdown next to the run button and press the run button or Shift+F10, with the configurations defined in .run/Flutter (Dev).run.xml, .run/Flutter (Prod).run.xml and .run/Flutter (Mock).run.xml. The documentation adds a requirement that is easy to miss: the flavor configurations in android/app/build.gradle have to be set up correctly for those to work. The .run/ directory at the repository root is where the XML definitions live.

json
{ "name": "Flutter (Mock)", "request": "launch", "type": "dart", "args": ["--flavor", "dev", "--dart-define=MOCK_MODE=true"] }

Real credentials, and the files you have to ask for

The full setup path is where a contributor hits the wall the mock mode exists to avoid. You clone the repository and install the dependencies, then you create .env.staging and .env.production files in the root and contact a team member for their contents. You set up Firebase, which means getting google-services.json for Android and GoogleService-Info.plist for iOS from the Firebase console, and you also need the lib/firebase_options.dart file, whose contents also have to come from a team member. So the real-key path depends on a human in the foundation, which is exactly the reason the mock path exists and is documented first. Even in mock mode you need one placeholder: a google-services.json file, because Firebase is skipped but Gradle still requires the file to be present. The Android signing section repeats the keystore.properties point and adds the rule that matters for anyone committing work: never commit keystore.properties or your .jks files to version control.

bash
cp android/keystore.properties.example android/keystore.properties

The repository as a release engineering reference

The top level of the tree describes a project with a real release process rather than a hobby app. There is a fastlane/ directory and a firebase/ directory, a firebase.json, a Runner.xcodeproj for the iOS side, a .maestro/ directory for UI testing, a widgetbook/ directory, a Gemfile with a Gemfile.lock for the Ruby tooling that fastlane needs, an l10n.yaml with an untranslated_messages.txt for localisation, a .devcontainer/ and a .tool-versions file. The build scripts are individual shell files rather than a single entry point: build_all.sh, build_android.sh, build_apk.sh, build_ios.sh and prepare_release.sh, plus an exportOptions.plist for the iOS export step and a release_notes.txt. The .claude/ and .cursor/ directories at the root indicate that the project is set up to be worked on with AI coding assistants, and devtools_options.yaml and analysis_options.yaml cover the Dart tooling. For a reader looking at how a Flutter app with native bridges is shipped to two stores, this repository is a more instructive artefact than the meditation app itself.

code
build_all.sh
build_android.sh
build_apk.sh
build_ios.sh
prepare_release.sh
fastlane/
.maestro/
widgetbook/
l10n.yaml

Two licences, and the APK question

The licensing is split in a way that matters if you plan to reuse any of it. The app itself is under the GNU Affero General Public License, with the file at the repository root, while the content available within the Medito app is subject to a custom licence documented separately at meditofoundation.org/license. The project also notes that it sometimes aggregates content from other sources that do not carry the same licence, and that this content is generally not published under Medito, with a request to respect the original copyright. So the meditation audio and text have their own terms, and some of it has third party terms again. The second licence question is the APK. The project offers an APK download alongside the store builds and asks that anyone installing it verify that the file is signed by the Medito Foundation, pointing to a VERIFY_APK document for the details. That is a sensible request, since a sideloaded APK is exactly the kind of file where a signature check matters.

code
- App: [GNU AFFERO GENERAL PUBLIC LICENSE](https://github.com/meditohq/medito-app/blob/master/LICENSE).
- The content available within the Medito app is subject to a custom license.

Editorial conclusion

Adopt this repository as a reference implementation if you are building a Flutter app with native code bridges, Riverpod state and Pigeon, because the structure shows all three wired together with a working mock mode, but treat it as a codebase to learn from rather than a product to ship, since the meditation content inside it is under a custom licence separate from the AGPL that covers the app. Verify three things before you copy anything from it: that the content licence at meditofoundation.org/license permits your use, since the app code and the content have different terms; that the mock mode still covers the feature you are changing, because the skipped components are Firebase, the paywall webview, Stripe and the Meta SDK; and the AGPL obligations, since the app licence is the GNU Affero General Public License and the repository metadata does not describe a different one.

Frequently asked questions

What is the Medito app and who maintains it?

It is a 100 percent free meditation app for Android and iOS, built with Flutter and maintained by the Medito Foundation and its community. The premise is that no one should have to pay to meditate, so the app has no ads, no spam and no sign-up.

How do I run the Medito app without API keys or Firebase?

Use mock mode. Run `flutter run --flavor dev --dart-define=MOCK_MODE=true -d <device-id>`, or pick the Flutter (Mock) configuration in VS Code or Android Studio. All network calls are intercepted and return hardcoded sample data, and Firebase, the paywall webview, Stripe and the Meta SDK are skipped, though a placeholder google-services.json is still required by Gradle.

What code generation does the Medito project need before building?

Pigeon, to generate the bridge code used to communicate with native iOS and Android code, run over pigeon_conf.dart and each file in pigeons/, and build_runner for the Riverpod API and state management code, run with the delete-conflicting-outputs flag.

What licence covers the Medito app and its content?

The app code is under the GNU Affero General Public License, while the content available within the app is subject to a custom licence described at meditofoundation.org/license. Some aggregated content comes from other sources with their own terms and is generally not published under Medito.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. meditohq/medito-app on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/meditohq-medito-app.svg)](https://hysenlabs.com/projects/meditohq-medito-app)

Was this useful?