Skip to main content

Build & Deployment

Audience: End users, system administrators, technical stakeholders Last Updated: 2026-04-06 Version: 2.0.0


Table of Contents

  1. Overview
  2. Supported Platforms
  3. How Builds Work
  4. Version Management
  5. Web & PWA Build
  6. Mobile Builds
  7. Desktop Builds
  8. Offline & Caching (PWA)
  9. Build Optimizations
  10. Browser Support
  11. Technical Specifications
  12. Security Considerations
  13. Known Limitations
  14. Related Documentation

Overview

Llamafin is built as a single codebase that compiles to four different platforms: Web (as a Progressive Web App), Android, iOS, and Desktop (Windows, macOS, Linux). The build system uses Angular 16 as the core framework, Capacitor 5 for mobile bridging, and Electron 25 for desktop applications.

Why It Matters

A unified build system means:

  • Consistent Features: Every platform gets the same features and bug fixes
  • Faster Updates: A single code change propagates to all platforms
  • Shared Testing: Unit tests validate the core logic across all platforms
  • Simplified Development: Developers maintain one codebase, not four

Build Tools

ToolPurpose
Angular CLI 16Core application bundling, compilation, optimisation
esbuildBundles background workers (downloads, audio analysis, colour processing)
Capacitor 5Bridges web code to native mobile APIs (iOS/Android)
Electron 25Wraps the web app as a standalone desktop application
electron-builderCreates installers (NSIS for Windows, DMG for Mac, .deb/AppImage for Linux)

Supported Platforms

Platform Matrix

PlatformMinimum VersionBuild TypeDistribution Method
Chrome (Desktop)79+ (Dec 2019)Web/PWADirect URL, self-hosted
Firefox (Desktop)70+ (Oct 2019)Web/PWADirect URL, self-hosted
Edge (Desktop)79+ (Jan 2020)Web/PWADirect URL, self-hosted
Safari (Desktop)14+ (Sep 2020)Web/PWADirect URL, self-hosted
Chrome (Android)79+Android AppAPK (side-load), Play Store
iOS14+ (Sep 2020)iOS AppTestFlight, App Store
Windows10+Desktop AppNSIS installer
macOS10.15+Desktop AppDMG disk image
LinuxModern distrosDesktop App.deb package, AppImage

Architecture Support

PlatformArchitectures
AndroidARM64, ARMv7, x86_64
iOSARM64 (devices), ARM64e (Apple Silicon Macs via Catalyst)
Windowsx64, ia32
macOSx64 (Intel), ARM64 (Apple Silicon)
Linuxx64

How Builds Work

The Build Process

Every platform shares the same first step: building the web application.

┌─────────────────────────────────────┐
│ Source Code │
│ TypeScript, HTML, SCSS, Assets │
└──────────────┬──────────────────────┘


┌─────────────────────────────────────┐
│ Worker Bundling (esbuild) │
│ Background tasks bundled to JS │
└──────────────┬──────────────────────┘


┌─────────────────────────────────────┐
│ Angular Production Build │
│ - Compiles TypeScript │
│ - Optimises and minifies │
│ - Generates service worker │
│ - Copies assets │
└──────────────┬──────────────────────┘


┌─────────────────────────────────────┐
│ Web Output (www/ folder) │
│ Ready for web server or packaging │
└──────────────┬──────────────────────┘

┌──────────┼──────────┬──────────────┐
▼ ▼ ▼ ▼
┌───────┐ ┌────────┐ ┌────────┐ ┌──────────┐
│ Web │ │Android │ │ iOS │ │ Desktop │
│Server │ │ App │ │ App │ │ App │
└───────┘ └────────┘ └────────┘ └──────────┘

Platform-Specific Packaging

After the web app is built, each platform packages it differently:

PlatformPackaging ToolWhat It Does
Web/PWAAngular CLIServes the www/ folder as a static website with service worker for offline support
AndroidGradle + Android Gradle PluginWraps the web app in a WebView, adds native plugins, compiles to APK
iOSXcodeWraps the web app in a WebView, adds native plugins, compiles to IPA
DesktopElectron + electron-builderWraps the web app in a Chromium window, adds Node.js runtime, creates native installer

Version Management

Version Numbers

The app uses semantic versioning (MAJOR.MINOR.PATCH):

ComponentCurrent VersionNotes
Web App2.0.0Primary version
Desktop App1.8.4Separate version tracking
Android2.0.0-beta (versionCode: 8)Separate version tracking
iOSManaged by XcodeSet in Xcode project

Version Bumping

Developers use three commands to increment versions:

CommandEffectExample
Patch bumpBug fixes only2.0.02.0.1
Minor bumpNew features, backward-compatible2.0.02.1.0
Major bumpBreaking changes2.0.03.0.0

The -dev suffix is automatically added to the version during development builds (e.g., 2.0.0-dev), and removed for production builds.

Database Version

A separate "database version" (dbVersion: 49) tracks the IndexedDB schema version. This is incremented when the app's local storage structure changes, triggering cache invalidation and data migration on the next app launch.


Web & PWA Build

What You Get

The web build produces a standard Progressive Web App (PWA) that can be:

  • Hosted on any web server (Nginx, Apache, static hosting)
  • Installed on your device like a native app (Chrome, Edge, Safari)
  • Used offline with cached data and downloads

Output Structure

The build output (www/ folder) contains:

File/DirectoryPurpose
index.htmlEntry point
main.[hash].jsApplication code (content-hashed for caching)
polyfills.[hash].jsBrowser compatibility code
styles.[hash].cssCompiled CSS styles
ngsw-worker.jsAngular Service Worker (handles offline caching)
ngsw.jsonService worker configuration (auto-generated)
manifest.webmanifestPWA manifest (name, icons, theme colours)
assets/Images, translations, workers
app/workers/Bundled background task workers

Content Hashing

Every JavaScript and CSS file gets a content hash in its filename (e.g., main.a1b2c3d4.js). This ensures:

  • Browser caches are invalidated when files change
  • Old versions don't accidentally serve stale code
  • Service worker updates only when content actually changes

Mobile Builds

Android

Build Command: npm run build-android

Minimum Requirements:

  • Android 6.0 (API level 23) or later
  • Target: Android 15 (API level 35)

Build Process:

  1. Web app is built to www/ folder
  2. Capacitor syncs web assets to the Android project
  3. Android Studio opens for final build, signing, and testing

Key Settings:

  • ProGuard (code shrinking/obfuscation): Disabled
  • File sharing: Enabled
  • Keyboard handling: Resizes the app body when keyboard appears

Output: APK file for sideloading, or AAB for Play Store submission.

iOS

Build Command: npm run build-ios

Minimum Requirements:

  • iOS 14 or later

Build Process:

  1. Web app is built to www/ folder
  2. Capacitor syncs web assets to the iOS project
  3. Xcode opens for final build, signing, and testing

Key Settings:

  • All screen orientations supported (portrait, landscape)
  • File sharing enabled
  • Documents can be opened in place
  • Minimum device capability: ARMv7

Output: IPA file for TestFlight or App Store submission.


Desktop Builds

Electron Architecture

The desktop app wraps the web app inside a Chromium browser window with a Node.js backend. This provides:

  • Native window management (frameless, always-on-top, custom sizing)
  • Node.js access (file system, system tray, native menus)
  • Audio device management (switch audio outputs natively)

Window Management

The desktop app features two player sizes:

ModeDimensionsPurpose
Small (default)268 × 513 pxCompact music player (Plexamp-style)
Expanded412 × 660 pxFull player with Visualisations

Window Properties:

  • Frameless (no title bar)
  • Always on top
  • Resizable via player controls, but not manually
  • Not maximizable (designed for compact size)

Installer Types

PlatformInstallerUser Experience
WindowsNSISCustom installer with directory selection, creates Start Menu shortcut
macOSDMGDisk image — drag app to Applications folder
Linux (.deb)Debian packageInstalls via apt or Software Centre
Linux (AppImage)AppImageSingle file, runs without installation

Desktop-Specific Features

FeatureDescription
Audio Output SelectionChoose which audio device to play through (speakers, headphones, DAC)
Global Keyboard ShortcutsMedia keys (play/pause, next, previous) work from any app
System TrayApp runs in background with tray icon and controls
File System AccessDirect access to local files for downloads and library management

Auto-Update

Status: Not configured. The desktop app does NOT currently have automatic updates. Users must manually download and install new versions.


Offline & Caching (PWA)

How Offline Works

The web app uses Angular's Service Worker to cache files and API responses for offline use.

Caching Strategies

What's CachedStrategyHow It Works
App Code (JS, CSS, HTML)Cache-firstAlways served from cache; updated in background when new version available
Assets (images, fonts, icons)Lazy + update prefetchCached when first requested; updated in background
Album Art & Images (/Items/**/Images)Cache-first (3 days, 100 entries)Served from cache if available; falls back to network. Cached for 3 days, up to 100 images.
Library Data (/Users/**/Items)Network-first (3 days, 100 entries)Tries network first (10 second timeout); falls back to cache if network fails. Fresh data preferred.

Why Two Strategies?

  • Cache-first is used for images because they rarely change and look fine when slightly stale. This saves bandwidth and speeds up loading.
  • Network-first is used for library data because you want to see the latest albums, playlists, etc. If the network fails, the cached data keeps the app usable.

What Works Offline

FeatureOffline Support
Browse cached library✅ Yes
Play downloaded music✅ Yes
View cached album art✅ Yes
Search cached library✅ Yes
Play streaming music❌ No (requires network)
Browse uncached library❌ No (requires network)
Settings changes✅ Yes (stored locally)

Build Optimizations

What Happens in Production Builds

optimisationWhat It DoesUser Benefit
AOT CompilationCompiles templates ahead of timeFaster app startup
Tree-ShakingRemoves unused codeSmaller download size
MinificationCompresses codeSmaller download size
Output HashingAdds content hash to filenamesBetter browser caching
Build OptimizerRemoves Angular decorators and metadataSmaller bundle

Size Budgets

The build enforces size limits:

WhatWarningError
Initial load4 MB5 MB
Any CSS file16 KB18 KB

If the build exceeds these limits, it will warn (or fail) to alert developers that the app is getting too large.

Development vs Production

FeatureDevelopment BuildProduction Build
OptimisedNoYes
Source MapsYes (for debugging)No
Readable NamesYesNo (minified)
Build SpeedFastSlow
File SizeLargeSmall

Browser Support

Supported Browsers

BrowserMinimum VersionRelease Date
Chrome (Desktop)79December 2019
Chrome (Android)79December 2019
Firefox70October 2019
Edge (Chromium)79January 2020
Safari (Desktop)14September 2020
Safari (iOS)14September 2020

What This Means

  • Modern JavaScript: The app uses ES2022 features (optional chaining, nullish coalescing, top-level await)
  • Modern CSS: Uses CSS custom properties, grid, flexbox
  • Web APIs: Uses Web Audio API, IndexedDB, Service Workers
  • No IE11 Support: Internet Explorer is NOT supported

Technical Specifications

Build Configuration

PropertyValue
FrameworkAngular 16
TypeScript TargetES2022
Module SystemES2020
Strict ModeEnabled (full strict, plus additional checks)
AOT CompilationAlways enabled

Dependency Counts

CategoryCount
Production Dependencies~80 packages
Development Dependencies~60 packages
Local/Custom Dependencies8 packages (from sibling directories or private registry)

Worker Files

WorkerPurposeBundler
Transcode DownloadTranscodes downloaded musicesbuild
Concurrent ChunksDownloads chunks in parallelesbuild
Colour ThiefExtracts dominant colours from imagesesbuild
Alpha/Beta TestFeature testing workersesbuild
Sonic AnalysisAudio fingerprintingManual concatenation

Service Worker Caching

ResourceMax EntriesMax AgeStrategy
Images1003 daysCache-first
Library API1003 daysNetwork-first (10s timeout)

Security Considerations

Content Security Policy (Desktop)

The Electron desktop app uses a very permissive Content Security Policy:

script-src * 'unsafe-inline' 'unsafe-eval';
default-src * blob: data:;

Implications: This allows scripts from any source, inline scripts, and eval() execution. While functional, this is less secure than a locked-down CSP.

Recommendations for Users

  1. Download from trusted sources only: Only install Llamafin from official channels
  2. Keep the app updated: Manual updates mean you should check for new versions regularly
  3. Use HTTPS for web access: When accessing the web version, ensure the server uses HTTPS

Known Limitations

LimitationImpactWorkaround
No automatic desktop updatesUsers must manually download new versionsCheck for updates periodically
Separate version trackingWeb, desktop, and Android have different version numbersCheck the About page in the app for the actual running version
ProGuard disabled on AndroidLarger APK size, no code obfuscationNone currently
No E2E testingComplex user flows are not automatically testedManual testing before releases
No CI/CD pipelineBuilds are run manually, not automaticallyFollow the build scripts in package.json
Hardcoded credentials in configGitLab token for private packages is in .npmrcRepository access should be restricted


Last Updated: 2026-04-06 Version: 2.0.0