Skip to main content

Build and Production

This document describes how to build each part of the Qprint project, what options to pass (including --dart-define and environment variables), and the difference between debug, profile, and release builds.


Build types (Flutter apps)

Flutter supports three build modes:

ModeCommandUse caseOptimizationsAssertions
Debugflutter run (default) or flutter run --debugDevelopment, hot reloadNoneEnabled
Profileflutter run --profile or flutter build apk --profilePerformance profilingYes (no debug symbols)Disabled
Releaseflutter run --release or flutter build apk / flutter build windowsProduction, distributionFull (minified, tree-shaken)Disabled
  • Debug: Slower, larger binary; assertions and kDebugMode == true; certificate pinning is disabled in the apps for easier dev.
  • Profile: Like release but with profiling tools; use for measuring performance.
  • Release: Smallest, fastest; certificate pinning enabled; use for production and store builds.

Backend (Go API)

Location: backend/

How to run (development)

cd backend
go run cmd/api/main.go

How to build (production)

cd backend
go build -o bin/api ./cmd/api
./bin/api

Configuration

The backend has no --dart-define. All configuration is via environment variables, typically from a .env file or host (e.g. Render).

VariableRequiredDescription
PORTYes (production)Server port (e.g. 8080 local, 10000 on Render)
DATABASE_URLYesPostgreSQL connection string
JWT_SECRETYesAt least 32 characters
ALLOWED_ORIGINSYes (production)Comma-separated CORS origins
ENVIRONMENTRecommendeddevelopment or production
USE_LOCAL_STORAGEOptionaltrue for local uploads dir
AWS_S3_BUCKET, AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYOptionalS3 file storage
RAZORPAY_*, RESEND_API_KEY, etc.OptionalSee Environment Variables

See Environment Variables and Deployment for full lists.


Frontend (Next.js)

Location: frontend/

How to run (development)

cd frontend
npm run dev

How to build (production)

cd frontend
npm run build
npm run start # optional: serve built app

Configuration

The frontend uses build-time env vars. Values are baked in at next build.

VariableRequiredDescription
NEXT_PUBLIC_API_URLYes (production)Backend API base URL (e.g. https://qprint-72wr.onrender.com)

Where to set:

  • Local: frontend/.env.local
    NEXT_PUBLIC_API_URL=http://localhost:8080
  • Production (e.g. Vercel): Project settings → Environment Variables → add NEXT_PUBLIC_API_URL for Production.

Note: Only variables prefixed with NEXT_PUBLIC_ are available in the browser. The app uses process.env.NEXT_PUBLIC_API_URL (see frontend/lib/api.ts); default fallback is http://localhost:8080.


Shopkeeper app (Flutter – Windows)

Location: shopkeeper_app/

How to run (development)

cd shopkeeper_app
flutter pub get
flutter run -d windows

With a specific API URL:

flutter run -d windows --dart-define=BASE_URL=http://localhost:8080

How to build (production / release)

Option 1 – Use the provided script (recommended for Windows):

cd shopkeeper_app
.\build_windows.bat

This script:

  1. Ensures SumatraPDF (and optionally LibreOffice) is in windows/runner/bin/
  2. Runs flutter clean and flutter pub get
  3. Runs flutter run -d windows --release --dart-define=BASE_URL=https://qprint-72wr.onrender.com

Option 2 – Manual build:

cd shopkeeper_app
flutter clean
flutter pub get
flutter build windows --dart-define=BASE_URL=https://qprint-72wr.onrender.com

Output: build/windows/x64/runner/Release/ or build/windows/runner/Release/ (e.g. shopkeeper_app.exe).

Windows installer (MSIX and classic)

To build an installer (not just the raw exe folder):

MSIX (recommended for simple install):

cd shopkeeper_app
build_installer.bat

This creates a signing certificate (if missing) so the installer shows Publisher: Qprint, runs dart run msix:create, then patches the MSIX (white logo background, desktop shortcut). Output: build\windows\runner\Release\*.msix or build\windows\x64\runner\Release\*.msix. See Windows Installer.

Classic .exe (install directory choice + desktop shortcut checkbox):

After building the Windows app, run Inno Setup:

cd shopkeeper_app
iscc installer_script.iss

Output: build\windows\installer\QprintShop_Setup.exe. Default install dir is Program Files; user can change it and choose whether to create a desktop shortcut.

Dart-defines and config

DefineRequiredDescription
BASE_URLYes (production)Backend API base URL (e.g. https://qprint-72wr.onrender.com)

Default: If BASE_URL is not passed, the app uses https://qprint-72wr.onrender.com (see shopkeeper_app/lib/config/app_config.dart).

Examples:

# Production (or use build_windows.bat which already passes this)
flutter run -d windows --release --dart-define=BASE_URL=https://qprint-72wr.onrender.com
flutter build windows --dart-define=BASE_URL=https://qprint-72wr.onrender.com

# Local backend
flutter run -d windows --dart-define=BASE_URL=http://localhost:8080

Customer app (Flutter – Android)

Location: customer_app/

Android build config (as of Feb 2026): compileSdk = 36, targetSdk = 35, minSdk = 21. Version is set in pubspec.yaml (e.g. 1.0.5+8 for versionName 1.0.5, versionCode 8). Plugins and AndroidX require compileSdk 36; targetSdk 35 meets Google Play requirements for new releases.

How to run (development)

cd customer_app
flutter pub get
flutter run -d android

With API URL and optional Maps key:

flutter run -d android --dart-define=BASE_URL=http://10.0.2.2:8080 --dart-define=MAPS_API_KEY=your_key

(Use 10.0.2.2 for Android emulator to reach host localhost.)

How to build (production / release)

APK (installable file):

cd customer_app
flutter build apk --dart-define=BASE_URL=https://qprint-72wr.onrender.com --dart-define=MAPS_API_KEY=your_key

App Bundle (for Play Store):

flutter build appbundle --dart-define=BASE_URL=https://qprint-72wr.onrender.com --dart-define=MAPS_API_KEY=your_key

Output: build/app/outputs/bundle/release/app-release.aab. Ensure customer_app/android/app/build.gradle.kts uses compileSdk = 36 and targetSdk = 35; increment version in pubspec.yaml for each Play Store upload.

Dart-defines and config

DefineRequiredDescription
BASE_URLYes (production)Backend API base URL
MAPS_API_KEYOptionalGoogle Maps API key (can also be set in android/local.properties as MAPS_API_KEY=...)
CERT_PINSOptionalComma-separated SHA-256 certificate fingerprints for leaf pinning; if unset, app uses intermediate CA pinning

Defaults: If BASE_URL is not set, the app uses https://qprint-72wr.onrender.com. See customer_app/lib/config/app_config.dart.

Examples:

# Production
flutter build apk --dart-define=BASE_URL=https://qprint-72wr.onrender.com --dart-define=MAPS_API_KEY=your_key

# Optional: certificate pinning (leaf fingerprints)
flutter build apk --dart-define=BASE_URL=https://... --dart-define=CERT_PINS="AA:BB:CC:..."

# Emulator (local backend)
flutter run -d android --dart-define=BASE_URL=http://10.0.2.2:8080

Android-specific: MAPS_API_KEY can be set in customer_app/android/local.properties instead of --dart-define; the build injects it into the manifest (see customer_app/android/app/build.gradle.kts).


Summary: options by target

TargetBuild / runKey options
Backendgo run cmd/api/main.go or go build -o bin/api ./cmd/apiEnv only (.env): PORT, DATABASE_URL, JWT_SECRET, ALLOWED_ORIGINS, ENVIRONMENT
Frontendnpm run build (or npm run dev)NEXT_PUBLIC_API_URL in .env.local or Vercel env
Shopkeeper (Windows).\build_windows.bat or flutter build windows--dart-define=BASE_URL=https://qprint-72wr.onrender.com
Customer (Android)flutter build apk or flutter build appbundle--dart-define=BASE_URL=... and optionally --dart-define=MAPS_API_KEY=..., --dart-define=CERT_PINS=...

Scripts reference

ScriptPurpose
shopkeeper_app/build_windows.batOne-shot: SumatraPDF/LibreOffice setup, flutter clean, flutter pub get, then flutter run -d windows --release --dart-define=BASE_URL=https://qprint-72wr.onrender.com
shopkeeper_app/build_installer.batCreates Qprint signing cert (if missing), runs msix:create, then patch_and_repack_msix.ps1 (white logo, desktop shortcut); optionally runs Inno Setup if iscc in PATH. Output: .msix and optionally QprintShop_Setup.exe.
shopkeeper_app/scripts/patch_and_repack_msix.ps1Unpacks .msix, sets manifest BackgroundColor white, adds desktop shortcut, replaces Store logo assets with white background, repacks. Requires MakeAppx.exe (Windows SDK).
shopkeeper_app/scripts/create_signing_cert.ps1Creates windows/Qprint.pfx (CN=Qprint) so MSIX shows "Publisher: Qprint" instead of "Msix Testing".
run_shopkeeper_release.bat (repo root)Starts already-built shopkeeper exe: shopkeeper_app\build\windows\x64\runner\Release\shopkeeper_app.exe (run build_windows.bat or flutter build windows first)
buildscript.bat (repo root)Sets BACKEND_URL and FRONTEND_URL, updates frontend/.env.local and (legacy) shopkeeper api_service.dart, then offers to build Frontend / Windows app / Android. Note: Shopkeeper app now uses AppConfig.baseUrl from --dart-define=BASE_URL, not a hardcoded value in api_service.dart.
buildscript.sh (repo root)Linux/macOS equivalent of buildscript.bat; updates frontend env and (legacy) shopkeeper file, then builds Frontend / Linux app / Android.
startlocal.batStarts backend and frontend; can patch backend copy of customer app API URL (see script).

Production checklist

  • Backend: ENVIRONMENT=production, JWT_SECRET 32+ chars, ALLOWED_ORIGINS set to your frontend URL(s), no TEST_MODE=true.
  • Frontend: NEXT_PUBLIC_API_URL set to your production backend URL (e.g. https://qprint-72wr.onrender.com).
  • Shopkeeper Windows: Build with --dart-define=BASE_URL=https://qprint-72wr.onrender.com (or your API URL); use build_windows.bat or equivalent.
  • Customer Android: Build with --dart-define=BASE_URL=https://qprint-72wr.onrender.com (and MAPS_API_KEY if using maps); use release signing for Play Store.

For full deployment steps, see Deployment and Environment Variables.