Back to Blog
Mobile Development

Flutter Billing App: Building an Invoicing Tool for Kenyan SMEs

View Repository on GitHub

The Problem

Most billing software sold in Kenya is either too expensive, too complex, or not designed for local requirements (KRA compliance, KES formatting, M-Pesa tracking). Small business owners — tailors, salons, hardware shops — need something simple that works offline and generates proper receipts.

What I Built

A Flutter billing application that runs on Android (with iOS support coming) featuring:

  • Client management — Store customer details locally
  • Product/service catalog — Quick-add items to invoices
  • Invoice generation — Clean, printable PDFs with your business logo
  • KRA receipt format — ETR-ready formatting for VAT compliance
  • M-Pesa payment tracking — Log which invoices have been paid via M-Pesa

Tech Stack

  • Flutter + Dart — Cross-platform UI
  • Hive — Offline-first local database (no server dependency)
  • pdf (Dart package) — Programmatic PDF generation
  • printing — Share/print PDFs directly from the app
  • riverpod — State management

Offline-First Design

This was a core requirement. Many SME owners work in areas with unreliable connectivity, or they simply don't want a cloud dependency for their sensitive business data.

All data lives in Hive boxes (a key-value store optimized for Flutter). The app works fully offline. If the user wants to back up data, they can export a JSON file and restore it on a new device.

PDF Generation

Generating professional-looking PDFs entirely on-device was challenging. The pdf package gives you a low-level layout engine — you build PDFs like you would with CSS flexbox, but in Dart.

final pdf = pw.Document();
pdf.addPage(pw.Page(
  build: (context) => pw.Column(children: [
    pw.Header(text: businessName, level: 0),
    pw.Table.fromTextArray(
      data: invoiceItems.map((item) => [
        item.description,
        item.quantity.toString(),
        'KES ${item.unitPrice}',
        'KES ${item.total}',
      ]).toList(),
    ),
    pw.Divider(),
    pw.Text('Total: KES ${invoice.total}', style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
  ]),
));

Key Lessons

Building for SMEs is a lesson in restraint. Every feature I wanted to add — recurring invoices, multi-currency, analytics — would have made the app harder to use for the person it's actually for: a tailor who has never used accounting software. Simple and fast beats feature-rich and slow.

View on GitHub →