{"id":51482539,"url":"https://github.com/avan1235/savvry","last_synced_at":"2026-07-07T03:01:12.621Z","repository":{"id":294758940,"uuid":"945822409","full_name":"avan1235/savvry","owner":"avan1235","description":"Shopping list app with live updates, available on all platforms thanks to Kotlin Multiplatform","archived":false,"fork":false,"pushed_at":"2026-06-17T18:03:36.000Z","size":22184,"stargazers_count":19,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-17T20:10:12.634Z","etag":null,"topics":["android","compose-multiplatform","desktop","ios","kotlin-multiplatform","kotlinx-rpc","ktor-server","shopping-list-app","web"],"latest_commit_sha":null,"homepage":"https://savvry.procyk.in/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avan1235.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-10T07:20:15.000Z","updated_at":"2026-06-17T18:04:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"5e10c03a-75c6-42ac-a445-fb73b940d6d8","html_url":"https://github.com/avan1235/savvry","commit_stats":null,"previous_names":["avan1235/bring","avan1235/savvry"],"tags_count":128,"template":false,"template_full_name":null,"purl":"pkg:github/avan1235/savvry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avan1235%2Fsavvry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avan1235%2Fsavvry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avan1235%2Fsavvry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avan1235%2Fsavvry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avan1235","download_url":"https://codeload.github.com/avan1235/savvry/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avan1235%2Fsavvry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35212581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose-multiplatform","desktop","ios","kotlin-multiplatform","kotlinx-rpc","ktor-server","shopping-list-app","web"],"created_at":"2026-07-07T03:01:11.688Z","updated_at":"2026-07-07T03:01:12.606Z","avatar_url":"https://github.com/avan1235.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🛒 Savvry - A Multiplatform Shopping List App\n\n[![Platforms](https://img.shields.io/badge/web-WebAssembly-blue)](https://savvry.procyk.in)\n[![Platforms](https://img.shields.io/badge/mobile-Android%20%7C%20iOS-blue)](https://github.com/avan1235/savvry/releases/latest)\n[![Platforms](https://img.shields.io/badge/desktop-Windows%20%7C%20macOS%20%7C%20Linux-blue)](https://github.com/avan1235/savvry/releases/latest)\n\n[![Build](https://img.shields.io/github/actions/workflow/status/avan1235/savvry/client.yml?label=Build\u0026color=green)](https://github.com/avan1235/savvry/actions/workflows/client.yml)\n[![Latest Release](https://img.shields.io/github/v/release/avan1235/savvry?label=Release\u0026color=green)](https://github.com/avan1235/savvry/releases/latest)\n[![Google Play](https://img.shields.io/endpoint?color=green\u0026logo=google-play\u0026logoColor=green\u0026url=https%3A%2F%2Fplay.cuzi.workers.dev%2Fplay%3Fi%3Din.procyk.savvry%26l%3DGoogle%2520Play%26m%3D%24version)](https://play.google.com/store/apps/details?id=in.procyk.savvry)\n[![Docker](https://img.shields.io/docker/v/avan1235/savvry?label=Docker%20Hub\u0026color=green)](https://hub.docker.com/repository/docker/avan1235/savvry/tags?ordering=last_updated)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-red.svg)](./LICENSE.md)\n[![GitHub Repo stars](https://img.shields.io/github/stars/avan1235/savvry?style=social)](https://github.com/avan1235/savvry/stargazers)\n[![Fork Mini Games](https://img.shields.io/github/forks/avan1235/savvry?logo=github\u0026style=social)](https://github.com/avan1235/savvry/fork)\n\n## 📱 Overview\n\n\u003cdiv style=\"display: flex; justify-content: center; flex-wrap: nowrap;\"\u003e\n  \u003cimg src=\"app/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.webp\" style=\"width: 32%;\"\u003e\n\u003c/div\u003e\n\nSavvry is a modern, feature-rich shopping list application built with Kotlin Multiplatform (KMP) and Compose Multiplatform (CMP). It allows users to create, manage, and share shopping lists across multiple platforms with a seamless, native-like experience.\n\nWeb version is publicly available at https://savvry.procyk.in.\n\nIf you like the project, consider supporting it by leaving ⭐.\n\n\u003cdiv style=\"display: flex; justify-content: center; flex-wrap: nowrap;\"\u003e\n  \u003cimg src=\"app/shared/screenshots/create-list-screen-custom-name.png\" style=\"width: 32%;\" /\u003e\n  \u003cimg src=\"app/shared/screenshots/create-list-screen-join-list.png\" style=\"width: 32%;\" /\u003e\n  \u003cimg src=\"app/shared/screenshots/favorites-screen-collections.png\" style=\"width: 32%;\" /\u003e\n\u003c/div\u003e\n\u003cdiv style=\"display: flex; justify-content: center; flex-wrap: nowrap;\"\u003e\n  \u003cimg src=\"app/shared/screenshots/edit-list-screen-options.png\" style=\"width: 32%;\" /\u003e\n  \u003cimg src=\"app/shared/screenshots/settings-screen-options.png\" style=\"width: 32%;\" /\u003e\n\u003c/div\u003e\n\u003cdiv style=\"display: flex; justify-content: center; flex-wrap: nowrap;\"\u003e\n  \u003cimg src=\"app/shared/screenshots/recipes-screen.png\" style=\"width: 32%;\" /\u003e\n  \u003cimg src=\"app/shared/screenshots/loyalty-cards-screen.png\" style=\"width: 32%;\" /\u003e\n  \u003cimg src=\"app/shared/screenshots/recipe-screen.png\" style=\"width: 32%;\" /\u003e\n\u003c/div\u003e\n\n\n## 🚀 Features\n\n- ✅ **Create \u0026 Manage Shopping Lists**: Intuitively organize your purchases with features like list sharing, favoriting items for quick access, and drag-and-drop reordering.\n- ✅ **AI-Powered List Generation \u0026 Recipe Extraction**: Generate curated shopping lists from plain-text descriptions or extract recipes and ingredients automatically from text and images using Gemini-powered AI agents (**Koog**).\n- ✅ **Website Recipe Import**: Seamlessly scrape and extract ingredients from external cooking and recipe sites (including *Kwestia Smaku*, *Cookidoo*, *Ania Gotuje*, and other general platforms) via server-side scraping (**Ksoup**).\n- ✅ **Loyalty Card Wallet**: Scan, extract, decode, and store all of your loyalty cards in one place with server-side QR and barcode decoding support (**ZXing**, **PNGJ**, **JpegDecoder**).\n- ✅ **Real-Time Synchronization**: Instantly sync data across all active client devices using type-safe client-server communication powered by **Kotlinx RPC** and **Ktor**.\n- ✅ **Beautiful \u0026 Highly Customizable UI**: Fully responsive interface built on modern components (**Lumo Composables**), featuring dynamic Material 3 theme generation (**MaterialKolor** \u0026 **ColorPicker**), custom shapes, and automatic dark-mode support.\n- ✅ **Offline-First Storage**: Secure local-first database/file storage capability with platform-specific engines, ensuring the app remains fully functional offline (**KStore**).\n\n## 🛠️ Technology Stack\n\n### Client\n- **Kotlin Multiplatform (KMP)** - Core business logic, networking, and data storage shared seamlessly across Android, iOS, Desktop, and Web.\n- **Compose Multiplatform (CMP)** - Shared declarative UI framework offering high-performance, fully native rendering on all target platforms.\n- **Ktor Client** - For asynchronous multiplatform HTTP networking and real-time WebSocket communication.\n- **KStore** - Local key-value and file storage utilizing CIO engines on native platforms and local storage on Web.\n- **Kotlinx RPC** - Modern type-safe client-server communication utilizing CBOR serialization for ultra-fast synchronization.\n- **Koog Agents \u0026 Google Prompt-Executor** - Custom prompt-engineering and LLM agent integration framework for structured data extraction and AI features.\n- **Lumo Composables** - Modern component and design system library tailored for Compose Multiplatform.\n- **MaterialKolor \u0026 Colorpicker** - Dynamic Material 3 theme and color palette generation.\n- **FileKit** - Cross-platform, modern file picker and directory chooser for importing/exporting files.\n- **Reorderable** - Smooth drag-and-drop list and element reordering inside Compose.\n- **Arrow Core \u0026 Arrow Serialization** - Functional programming utilities (such as `Either`) and serialization support.\n- **Kotlinx Serialization, Coroutines, \u0026 DateTime** - Type-safe JSON/CBOR serialization, structured concurrency, and multiplatform date/time handling.\n\n### Server\n- **Ktor Server** - Asynchronous web framework engine written in Kotlin.\n- **GraalVM Native Image** - Compiles the Kotlin server code into a standalone, extremely fast, and lightweight native executable.\n- **Exposed SQL ORM** - Type-safe Kotlin framework for relational database access.\n- **PostgreSQL** - Production-ready relational database with PostgreSQL JDBC Driver support (`pgjdbc-ng`).\n- **Ksoup** - Multiplatform HTML parser for web scraping and external ingredient/recipe extraction.\n- **ZXing, PNGJ, \u0026 JpegDecoder** - Server-side high-fidelity QR/Barcode parsing and image decoding.\n- **Koin** - Dependency injection framework (integrated into the Ktor server).\n- **Kotlinx RPC Server** - Type-safe RPC handler paired with Ktor server.\n- **Arrow Core \u0026 Serialization** - Functional programming patterns on the server.\n- **Kotlinx Datetime \u0026 Serialization** - Shared models compatibility.\n- **Testcontainers** - Multi-platform Docker containers helper for running database integration tests in JVM.\n\n## 💻 Supported Platforms\n\nThe client application supports:\n- 📱 **Android**: Target SDK 35, Compile SDK 37. Powered by Compose Multiplatform UI. \u003ca href=\"https://play.google.com/store/apps/details?id=in.procyk.savvry\"\u003e\u003cimg alt=\"Get it on Google Play\" height=\"32\" src=\"https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png\"/\u003e\u003c/a\u003e\n- 🍎 **iOS**: Fully native UI framework using Compose Multiplatform (requires macOS/Xcode for building).\n- 🖥️ **Desktop**: Cross-platform JVM application targeting Windows, macOS, and Linux.\n- 🌐 **Web**: Modern, high-performance Web application compiled via **WebAssembly (WasmJS)** and JavaScript.\n\n## 🏗️ Project Structure\n\n```\nsavvry\n├─ app                     # Client application code\n│  ├─ shared               # Shared client UI \u0026 business logic (Compose Multiplatform)\n│  │  └─ src\n│  │     ├─ commonMain     # Main shared Compose UI, ViewModels, and client logic\n│  │     ├─ androidMain    # Android resources and Compose UI previews\n│  │     ├─ iosMain        # iOS-specific framework implementations\n│  │     ├─ jvmMain        # Desktop-specific implementation details\n│  │     └─ wasmJsMain     # WebAssembly (WasmJS) implementation details\n│  ├─ androidApp           # Android launcher module (targetSdk 35, compileSdk 37)\n│  ├─ desktopApp           # Desktop JVM launcher module\n│  ├─ iosApp               # iOS native Xcode project (SwiftUI entry point)\n│  └─ webApp              # WebAssembly (WasmJS) launcher module and index assets\n├─ server                  # Server application module (Ktor Server with GraalVM Native Support)\n│  └─ src\n│     ├─ main              # Server implementation (routes, databases, scrapers, barcode decoders)\n│     └─ test              # Integration \u0026 unit tests (JUnit 5 with Testcontainers)\n├─ core                    # Shared data models, validation logic, and serialization protocols\n├─ rpc-client              # Client RPC proxy module using Kotlinx RPC \u0026 Ktor Client\n└─ build-src               # Gradle convention plugins for environment setup\n```\n\n## 🚀 Getting Started\n\n### Prerequisites\n- **JDK 21** or higher\n- **Docker and Docker Compose** (for running the server and database)\n- **Android Studio** or **IntelliJ IDEA** (for client and server development)\n- **Xcode** (for iOS development, macOS only)\n\n### Development Commands\n\nWe provide a convenient `Makefile` to simplify common development tasks:\n\n#### Running the Database \u0026 Server\n1. **Start PostgreSQL Database**:\n   ```bash\n   make db\n   ```\n2. **Start Ktor Server (using Docker)**:\n   ```bash\n   make server\n   ```\n3. **Start Ktor Server (locally)**:\n   ```bash\n   make server-local\n   ```\n\n#### Running the Clients\n1. **Run Desktop App (JVM)**:\n   ```bash\n   make desktop\n   ```\n2. **Run Web App (WebAssembly)**:\n   ```bash\n   make wasm\n   ```\n3. **Run Android App**:\n   Open the project in Android Studio and run `:app:androidApp`.\n4. **Run iOS App**:\n   Open the Xcode workspace inside `app/iosApp` on macOS and run.\n\n#### Quality Assurance \u0026 Screenshot Testing\n1. **Run Host Screenshot Tests**:\n   ```bash\n   make screenshots\n   ```\n   *This uses **Roborazzi** to capture and test shared Compose UI components on a host machine.*\n\n#### Cleanup\n1. **Clean build artifacts \u0026 Docker environments**:\n   ```bash\n   make clean\n   ```\n\n## 📄 License\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## 👨‍💻 Author\nMaciej Procyk","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favan1235%2Fsavvry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favan1235%2Fsavvry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favan1235%2Fsavvry/lists"}