Skip to content
Native Flutter

Your CRM in your pocket

One Flutter codebase for iOS and Android, talking to the same API as the web app. Sixty-eight screens, every module, and you build it and ship it from your own developer account.

MIT licensed. No store listing to wait on, and no per-seat fee on the phone either.

The same product, held in one hand

Not a companion app that shows you what happened. The one that lets you do something about it.

  • Depth Tickets, in full The approvals inbox, the per-ticket approval panel, merge and unmerge, the macro picker and the close-with-children dialog are all on the phone, not just the queue and a comment box.
  • Proof A test holds the phone to 390px A widget test renders at 390 by 844 at three times density and fails on any overflow, checks tap targets are 44 pixels, then runs it all again with the system font scaled up.
  • Flat Borders, never shadows The design system's do-not list says it outright. Every card is a one-pixel border on white, which is why screen forty looks like screen one.
Clone to pocket

Four steps, and none of them involve us

You build it, you sign it, you distribute it. That is the same operational model as the rest of BottleCRM.

Build

Clone the repository, run flutter pub get, run flutter run. One codebase produces both the iOS and the Android build, and there is no paid tier gating any of it.

  • MIT licensed source
  • Flutter, one codebase
  • iOS and Android
  • Hot reload while you work

Point it somewhere

Set the backend URL for the install. That is the whole configuration step, and it is why the app works against your own deployment rather than ours.

  • Server URL per install
  • Any deployment
  • No vendor account needed
  • Nothing phones home

Sign in without a password

Google Sign-In, or a six-digit code emailed to you that you type into the app. Tokens land in the iOS Keychain or the Android Keystore and refresh themselves.

  • Google Sign-In
  • Six-digit emailed code
  • Keychain and Keystore
  • Automatic token refresh

Work the day

Tickets, leads, deals, approvals, goals and the timesheet, from the device. Someone in more than one organisation switches tenant without signing in again.

  • Approvals inbox and panel
  • SLA, time tracking, mentions
  • Goals and the timesheet
  • One-tap org switch
Read this before you adopt

Four things to know before you build it

Three of these are deliberate trade-offs with a reason behind them. The fourth is simply not built yet.

It is not on the App Store

Not under our publisher account. The repository ships the Flutter source so you, or whoever hosts for you, build and distribute under your own developer account. One binary that talks to many different self-hosted backends is a review problem we would rather you did not inherit from us.

It does not work offline

A live connection is required for everything: list, detail, create, edit. The backend runs the tenant scoping and the field validation on every request, and buffering offline writes would produce merge conflicts that quietly corrupt customer data. Correctness over offline editing, deliberately.

One device, one person

Each install signs in as one user and there is no fast account switch. For a shared device, a tablet on a sales floor for instance, use the web app and let the browser session do the work.

No biometric lock, and no board

Opening the app does not ask for Face ID or a fingerprint; the tokens are in the platform secure store, but the app itself is not gated behind a biometric check. And there is no kanban board on the phone, though that is not a mobile gap: the web app does not have one either.

What is built

Sixteen modules, sixty-eight screens

Every module, not a viewer

Leads, contacts, accounts, deals, tasks, tickets, invoices, estimates, documents, solutions, goals, the timesheet, notifications, team and the whole settings tree. Sixty-eight screens, and creating and editing works on all of them.

  • Sixteen modules
  • Create and edit, not read-only
  • Filter and search per list
  • Activity timeline on records

The ticketing depth is genuinely there

Not a stripped view of the queue. SLA panel, public and internal comment tabs, parent and child links, merge and unmerge, time tracking, mentions, macros, the close-with-children dialog and the approvals inbox all ship on the phone.

  • Approvals inbox and per-ticket panel
  • Merge and unmerge
  • Macro picker
  • Close with children
  • Analytics, read-only
  • Business hours and routing in settings

Tokens live where the platform keeps secrets

The JWT pair goes into the iOS Keychain or the Android Keystore through the platform secure store, never into shared preferences. Every request carries the org, and the backend enforces the tenant boundary whatever the app sends.

  • Platform secure store
  • Refresh on expiry
  • Org on every request
  • Sign-out clears local state
  • No biometric gate, by omission

It is checked at 390 pixels, by a test

A widget test renders screens at a 390 by 844 viewport at three times density, fails if Flutter reports a single overflow, asserts tap targets of at least 44 pixels, and runs the whole thing again with the system font scaled up.

  • 390 by 844 at 3x
  • Overflow is a failure
  • 44px targets asserted
  • Re-run at large text

Flat on purpose

Bordered cards with no drop shadow, Material 3 underneath, one type scale across every screen. The design system says so in its own do-not list, which is why the app looks the same on screen forty as on screen one.

  • Cards flat, borders only
  • Material 3
  • One type scale
  • Dark theme written, switched off

Your fields, your build

Custom fields your org defined render and save on the phone the same as on the web. And because the source is MIT, the app you ship can carry your name rather than ours.

  • Custom fields render and edit
  • Same API, no mobile endpoints
  • Fork it and rename it
  • Crash reporting on Android
Questions

The ones that decide it

Check for yourself

The Flutter source, the design system and the 390px viewport test are all in the open repository.

Is the mobile app on the App Store?

Not under our publisher account today. The repository ships the Flutter source so you, or your hosting partner, build and distribute it under your own developer account. This avoids the per-customer review friction of submitting one binary that talks to many different self-hosted backends.

Does the app work without internet?

No. A live connection is required for every action: list, detail, create, edit. The backend runs tenant scoping and custom-field validation on every request, and we deliberately do not buffer offline writes because the resulting merge conflicts would silently corrupt customer data. The trade-off is intentional: correctness over offline edits.

Can multiple users share one device?

No. The app is designed for personal use. Each install is signed in as one user. For shared devices, a sales floor tablet for example, use the web app instead and rely on browser sessions.

What ticketing features actually work on phone?

Nearly all of them, and this page has been checked rather than asserted. The mobile ticket detail carries the SLA panel, public and internal comment tabs, custom fields, parent and child links, time tracking, mentions, merge and unmerge, solutions, the macro picker, the close-with-children dialog and the per-ticket approval panel, alongside a dedicated approvals inbox. Ticket analytics ships too, read-only. What is missing is a board, and the web app does not have one either.

How does sign-in work?

Two passwordless paths: Google Sign-In, or a six-digit code emailed to your address, which you type into the app rather than following a deep link. Tokens land in the iOS Keychain or the Android Keystore through the platform secure store and refresh automatically when the access token expires. There is no biometric unlock on top of that.

Build it this afternoon

Clone the repository, point it at your backend, run it on a device. Nothing to buy and nobody to ask.

MIT licensed iOS and Android 100% data ownership