Manage your household with your Nextcloud — lists, photos & notes.

Readme

Pantry

A Flutter mobile client for Nextcloud Pantry — household management for your self-hosted Nextcloud.

Features

  • Checklists: Shared checklists with categories, quantities, images, and recurring items.
  • Photo Board: Upload and organize shared photos in folders with captions.
  • Notes Wall: Color-coded shared notes for household reminders.
  • Drag-and-drop reordering everywhere.
  • Multi-select for bulk actions.
  • Offline caching for fast loading.
  • Material Design 3 with dark mode.
  • Self-hosted — connects directly to your own Nextcloud server via Login Flow v2.
ChecklistsPhoto boardNotes wall

Requirements

A Nextcloud server with the Pantry server app installed.

If you have issues regarding the core app for Nextcloud, please open the issue on the repo linked above. This repository is specifically for the companion mobile/desktop apps.

Installation

Google Play & F-Droid

Beta testing

Want early access to new features? Join the beta program:

  1. Visit the beta opt-in page on your Android device.
  2. Tap Become a tester.
  3. Install or update Pantry from the Play Store listing — you’ll automatically receive beta builds.

It may take a few minutes for your tester status to propagate.

Manual (APK)

Download the latest APK from the releases page and sideload onto your device.

App Store (iOS/macOS)

Install from the App Store

Development

Prerequisites

  • Flutter (stable channel)
  • Android Studio / Xcode for platform builds
  • A Nextcloud instance with the Pantry server app for testing

Quick Start

make get            # install dependencies
make i18n           # generate i18n code
make run            # run in debug mode

Common Tasks

make analyze        # analyze staged files
make format         # format staged files
make check          # analyze + format check
make test           # run tests

See make help for the full list.

Project Layout

lib/
├─ main.dart               # App entry + theming
├─ models/                 # Data models (Photo, Note, Checklist, etc.)
├─ services/               # API clients, cache, auth
├─ utils/                  # Pure utilities (rrule, icons)
├─ widgets/                # Reusable widgets (recurrence dialog, category picker)
└─ views/
   ├─ checklists/
   ├─ photos/
   ├─ notes/
   ├─ home/
   └─ login/

API

The app consumes the Nextcloud Pantry OCS API. The OpenAPI spec is kept in sync via:

make fetch-openapi

Translations

Translations live in lib/i18n/, one YAML file per language:

  • messages.i18n.yaml — the base file (English), the source of truth for all keys.
  • messages_<langCode>.i18n.yaml — one per language (e.g. messages_de.i18n.yaml, messages_fr.i18n.yaml, messages_he.i18n.yaml).

To improve an existing translation, edit the values in that language’s file. Keep the keys identical to the base file — translate only the values.

To add a new language:

  1. Copy lib/i18n/messages.i18n.yaml to lib/i18n/messages_<langCode>.i18n.yaml and translate the values.
  2. Add the locale to supportedLocales and its native name to languageNativeNames (the endonym shown in the language picker) in lib/services/locale_service.dart.
  3. Run make i18n to regenerate the Dart code.

Reuse translations from the Nextcloud app. Many strings already exist in the Pantry Nextcloud app. You can auto-populate a language file from the Nextcloud app’s translations instead of translating those strings by hand:

make i18n-from-nextcloud \
  NC_JSON=~/Dev/nextcloud-pantry/l10n/nn_NO.json \
  TARGET=lib/i18n/messages_nn.i18n.yaml

NC_JSON is the path to the language’s JSON file in the Nextcloud app’s l10n/ directory, and TARGET is the Flutter language file to fill in. It only replaces values that still match the English base (case-insensitively), so already-translated strings are left untouched. Run make i18n afterwards to regenerate the Dart code.

A few rules to keep translations working:

  • Don’t rename keys — they must match the base file exactly. Any key you don’t translate falls back to English.
  • Preserve placeholders and parameters. If a string is defined as stepLabel(int current, int total): "Step ${current} of ${total}", keep the (...) signature and the ${current} / ${total} placeholders intact — only translate the surrounding words.
  • RTL languages (like Hebrew) are supported automatically; the app mirrors its layout based on the active locale.

After editing any translation file, run make i18n to regenerate the generated Dart:

make i18n

Contributions of new or improved translations are very welcome — open a pull request.

Privacy

Pantry is a self-hosted client. Your data never leaves your Nextcloud server. See the privacy policy for details.

Contributing

I am developing this app on my free time, so any support, whether code, issues, or just stars is very helpful to sustaining its life. If you are feeling incredibly generous and would like to donate just a small amount to help sustain this project, I would be very very thankful!

Buy Me a Coffee at ko-fi.com

I welcome any issues or pull requests on GitHub. If you find a bug, or would like a new feature, don’t hesitate to open an appropriate issue and I will do my best to reply promptly.

License

This app is licensed under the MIT license.