Your digital companion for board game nights
Features β’ Screenshots β’ Installation β’ Getting Started β’ Tech Stack β’ Contributing β’ License
BoardPocket is a comprehensive Flutter application designed for board game enthusiasts. It helps you manage your game collection, track plays, maintain a wishlist, and make game nights more fun with built-in randomizers and decision-making tools.
Whether you're a casual player or a serious collector, BoardPocket provides everything you need to enhance your board gaming experience.
- Digital Collection: Keep track of all your board games in one place
- Game Details: Store comprehensive information including title, player count, play time, category, and complexity
- Cover Images: Upload high-resolution cover images for each game
- Cover Search: Type a game name and pick a cover from Openverse / Wikimedia Commons when you don't have the image handy
- Statistics: Track total plays, win rates, and last played dates
- Categories: Organize games by category with easy filtering
- Search: Quickly find games with the built-in search functionality
- Dice Roller: Pick exactly which dice you need (d4, d6, d8, d10, d12, d20, d100), roll them together and see every result plus the total
- Random Game Picker: Can't decide what to play? Let the app choose for you!
- Finger Picker: Interactive tool to randomly select who starts by touching the screen
- Name Draw: Draw random names from your player groups
- Challenge Mode: Built-in mini-games and challenges to decide the winner
- Track Desired Games: Keep a list of games you want to buy
- Filter Options: Organize by category or priority
- Easy Management: Add, edit, and remove items seamlessly
- Dark/Light Mode: Choose your preferred theme
- Multi-language Support: Available in English, Portuguese, and Spanish
- Responsive Design: Works beautifully on phones and tablets
- Export/Import: Backup your entire collection as JSON
- Cross-Platform: Works on Android, iOS, and Web
- Local Storage: Your data stays on your device (with SQLite)
BoardPocket is local-first. There is no account, no server, and no telemetry: your collection never leaves the device. The only outbound request the app ever makes is the optional cover image search, and even that goes to public, key-less APIs (Openverse and Wikimedia Commons) that return Creative Commons / public domain images. Nothing about your collection is ever sent.
- Flutter SDK (^3.47.0) / Dart SDK (^3.13.0)
- Android Studio / Xcode (for mobile development)
- Chrome (for web development)
- Java 17 (for Android builds)
- Xcode + a configured signing team (for iOS release builds)
git clone https://github.com/Oda2/boardpocket.git
cd boardpocketflutter pub getOr, with the Makefile:
make deps# For Android
flutter run
# For iOS
flutter run -d ios
# For Web
flutter run -d chromeOr:
make run # or: make run ARGS="-d chrome"Everything is wrapped in a Makefile. Run make help for the full list.
| Command | What it does |
|---|---|
make deps |
flutter pub get |
make outdated |
Show dependencies with newer versions available |
make doctor |
Check the local Flutter / Android / iOS toolchain |
make format |
Format lib/ and test/ |
make format-check |
Fail if anything is unformatted (used by CI) |
make lint / make analyze |
flutter analyze |
make test |
Run the full test suite |
make test-watch |
Run tests in watch mode |
make coverage |
Run tests with coverage into coverage/lcov.info |
make ci |
analyze + test β the same checks CI runs |
# Android: debug APK + release App Bundle (Play Store)
make build-apk
make build-appbundle
make build-android # both of the above
# iOS (requires macOS + Xcode + signing configured)
make build-ios
# Web
make build-web
# Everything
make build-allOr straight from Flutter:
flutter build apk --debug # build/app/outputs/flutter-apk/app-debug.apk
flutter build appbundle --release # build/app/outputs/bundle/release/
flutter build ios --release # build/ios/iphoneos/
flutter build web --release # build/web/| Platform | Artefact |
|---|---|
| Android APK | build/app/outputs/flutter-apk/app-debug.apk |
| Android App Bundle | build/app/outputs/bundle/release/app-release.aab |
| iOS | build/ios/iphoneos/Runner.app |
| Web | build/web/ (serve it with any static file server) |
Release signing reads its credentials from android/.env (git-ignored) or from
environment variables:
# android/.env
BOARD_KEY_ALIAS=...
BOARD_KEY_PASSWORD=...
BOARD_STORE_FILE=... # path to the .jks keystore
BOARD_STORE_PASSWORD=...iOS builds need a normal Xcode signing setup (flutter build ios --release will
fail without a configured team and provisioning profile).
Every direct dependency is on its newest release, verified with:
make outdated # should report "all up-to-date"Upgrading Flutter generally unblocks newer majors of several packages, because
they gate on the Dart SDK version. Check make outdated after a Flutter upgrade
and bump whatever it lists.
Pushing a v* tag runs .github/workflows/release.yml, which:
- builds a release APK and App Bundle and attaches them to the GitHub Release for that tag;
- builds the web app and deploys it to GitHub Pages;
- rewrites the GitHub Release notes if the release already exists (so re-running is safe).
# 1. bump the version in pubspec.yaml
# version: 0.1.5+12
# 2. commit, tag and push
git add pubspec.yaml
git commit -m "chore: release 0.1.5"
# both tag styles work: v0.1.5 and 0.1.5
git tag 0.1.5
git push origin main --follow-tagsImportant: the workflow file has to be on the default branch before the tag is pushed, otherwise GitHub has nothing to run. If a tag was pushed too early, delete it on the remote and push it again:
git push origin :refs/tags/0.1.5 && git push origin 0.1.5You can also trigger a release by hand from the Actions tab using the Run workflow button.
The APK and AAB land under the tag's Assets on the GitHub Releases page.
Add these under Settings β Secrets and variables β Actions:
| Secret | Value |
|---|---|
KEYSTORE_BASE64 |
base64 -i boardpocket.keystore | pbcopy |
KEY_ALIAS |
The keystore alias, e.g. boardpocket |
KEY_PASSWORD |
Key password |
STORE_PASSWORD |
Keystore password |
Create the keystore once and keep it safe:
keytool -genkey -v \
-keystore ~/boardpocket.keystore \
-alias boardpocket \
-keyalg RSA -keysize 2048 -validity 10000
base64 -i ~/boardpocket.keystore | pbcopy # paste into the secretKeep this keystore forever, and back it up. Android only accepts an update when it is signed with the same key as the installed version. If the key changes, the app cannot be updated in place and the user has to uninstall it β and because BoardPocket keeps the collection in a local database with no server, uninstalling deletes their data. This is also why the release job fails loudly when the secrets are missing instead of quietly generating a throwaway key.
Without the secrets you can still run the workflow manually with
allow_unsigned: true. The artifacts are then named
*-UNSIGNED-do-not-distribute.* so they are never mistaken for a real release.
The web deploy pushes the build to the gh-pages branch, which is what
Pages serves in the usual Settings β Pages β Source: Deploy from a branch
configuration. Nothing needs to be changed in the repository settings.
The site is served from https://<owner>.github.io/<repo>/ and the build sets
--base-href automatically.
If you ever switch Pages to Source: GitHub Actions, this workflow will stop updating the site β that source ignores the
gh-pagesbranch. Let me know and I will swap the deploy job toactions/deploy-pagesinstead.
- Open the app and explore the Collection tab
- Tap the + button to add your first board game
- Fill in the game details and pick a cover (upload or search)
- Explore the Randomizer tab for game night tools
- Add games to your Wishlist for future purchases
- Tap the + button in the Collection tab
- Enter the game title
- Pick a cover: upload one from your device, or tap Search online to look one up
- Set player count (min and max)
- Select play time and complexity
- Choose a category
- Save!
- Dice Roller: Go to Randomizer β Dice Roller, tap the dice you need (e.g.
d20,d20,d6), then roll - Random Game Picker: Go to Randomizer β Random Game and tap the button
- Finger Picker: Everyone touches the screen, the app selects randomly
- Name Draw: Add player names and draw to see who goes first
- Challenge: Try the built-in challenges for extra fun
flutter test
# or
make test# Generate coverage report (creates coverage/lcov.info)
make coverageflutter test test/your_test_file_test.dartmake ci # analyze + testFormatting is checked with make format-check. The Dart formatter changes style
between SDK releases, so run make format once after a Flutter upgrade and commit
the result rather than mixing it into a feature change.
- Framework: Flutter
- Language: Dart
- State Management: Provider
- Navigation: go_router
- Database: SQLite (sqflite)
- Web Fallback: SharedPreferences
- Storage: path_provider
- Image Handling: image_picker
- File Operations: file_picker, share_plus
- Networking: http (cover image search only)
- UI Components: Material Design + Google Fonts
- Internationalization: intl
When you tap Search online on the cover picker, BoardPocket queries two public APIs that need no API key and no account:
| Source | Endpoint | Notes |
|---|---|---|
| Openverse | https://api.openverse.org/v1/images |
Creative Commons images, ~20 req/min anonymous |
| Wikimedia Commons | https://commons.wikimedia.org/w/api.php |
Public domain / CC images |
Results are meant as a visual reference, not an official box scan. Only the image URL is stored β nothing is downloaded, re-encoded, or tracked, and the app sends no information about your collection. If you'd rather stay fully offline, just don't use the search and keep uploading your own images.
We love contributions! Here's how you can help:
- Check if the bug has already been reported in Issues
- If not, create a new issue with a clear description and steps to reproduce
- Open an issue with the label
enhancement - Describe the feature and why it would be useful
- Fork the repository
- Create a new branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow the existing code style
- Run
flutter analyzebefore committing - Ensure all tests pass (
flutter test)
- Board game statistics and analytics dashboard
- Player profiles and win/loss tracking
- Dice roller with selectable dice types
- Cover image search (free, key-less APIs)
- Game recommendations based on collection
- Social features (share collections)
- Game session timer
- Score keeping tools
- Barcode scanner for quick game addition
Why there is no BoardGameGeek integration here: the BGG XML API is now paid and requires an authenticated token. BoardPocket is deliberately local-first with no account, no server, and no third-party ownership of your data, so a paid, account-gated catalog service does not fit the project's goals. The free cover search above is the piece that actually helps at the moment you are adding a game.
If you find this project helpful, please consider:
- β Starring the repository
- π Reporting bugs
- π‘ Suggesting features
- π§ Contributing code
This project is licensed under the MIT License - see the LICENSE file for details.
- Thanks to all contributors who helped make this project better
- Flutter community for amazing packages and support
- Board game enthusiasts worldwide for the inspiration
- GitHub Issues: Create an issue
Made with β€οΈ for board game lovers



