axons.at
← Alle Beitraege

Native Apps für KMU: mit Expo an einem Tag zum lauffähigen Prototyp

Thomas Hummer··native-app, expo, react-native, app-entwicklung, kmu, supabase
Smartphone mit aufgeräumter App im Vordergrund, dahinter ein Code-Editor auf einem Laptop, warme dunkle Lichtstimmung

Eine eigene App ist für viele kleine Unternehmen ein Reizthema. Der Wunsch ist da: eine Kundenschnittstelle, ein internes Werkzeug für die Mitarbeiter, etwas Eigenes statt einer Standard-Lösung. Die Vorstellung von Aufwand und Budget hat das Thema dann meist schnell wieder beerdigt. Zu Recht, lange Zeit: zwei getrennte Apps für iOS und Android, Spezialwissen, Monate Entwicklung.

Diese Woche habe ich getestet, wo dieser Aufwand heute wirklich liegt. Werkzeug der Wahl: Expo.

Was Expo ist und was es löst

Expo ist ein Framework auf Basis von React Native. Der Kerngedanke: Du schreibst den Code einmal in JavaScript beziehungsweise TypeScript, und er läuft als echte native App auf iOS und Android. Kein doppelter Code, keine zwei Teams, keine zwei Sprachen.

Den zweiten großen Schmerzpunkt nimmt der dazugehörige Cloud-Build-Dienst EAS. Wer schon einmal eine native App manuell aufs iPhone gebracht hat, kennt den Setup-Marathon mit Xcode, Zertifikaten und Provisioning-Profilen. EAS baut die App in der Cloud und liefert sie aufs Gerät. Genau diese Hürde hat native Entwicklung für kleine Projekte früher unwirtschaftlich gemacht.

Der Stack im Praxistest

Der Test war ein Kursportal als App: eine Liste, die echte Kursdaten aus der Datenbank lädt. Drei Bausteine:

  • Expo Router für die Navigation. Datei-basiertes Routing wie bei Next.js: eine Datei unter app/ wird automatisch zu einem Screen, app/kurs/[id].tsx zur Detailseite mit Parameter. Wer aus der Web-Welt kommt, ist sofort zu Hause.
  • TypeScript durchgängig. Typsicherheit von der Datenbank bis ins UI.
  • Supabase als Backend. Postgres-Datenbank plus fertige Client-Bibliothek, kein eigener Server nötig. Die App spricht direkt mit der Datenbank, abgesichert über Zugriffsregeln (dazu unten mehr).

Der Screen, der die Kurse lädt und in einer FlatList rendert, ist im Kern so kurz:

import { FlatList, Text, Image, View } from 'react-native';
import { useEffect, useState } from 'react';
import { supabase } from '../lib/supabase';

export default function Kursliste() {
  const [kurse, setKurse] = useState([]);

  useEffect(() => {
    supabase
      .from('kurse')
      .select('id, titel, beschreibung, bild_url')
      .eq('veroeffentlicht', true)
      .then(({ data }) => setKurse(data ?? []));
  }, []);

  return (
    <FlatList
      data={kurse}
      keyExtractor={(k) => String(k.id)}
      renderItem={({ item }) => (
        <View>
          <Image source={{ uri: item.bild_url }} style={{ height: 160 }} />
          <Text>{item.titel}</Text>
        </View>
      )}
    />
  );
}

FlatList ist dabei nicht einfach eine Liste, sondern rendert nur die sichtbaren Einträge und recycelt sie beim Scrollen. Das ist der Unterschied zwischen einer App, die bei 500 Kursen ruckelt, und einer, die flüssig bleibt.

Von null bis aufs Gerät an einem Tag

Der Weg vom leeren Projektordner bis zur App, die auf meinem eigenen iPhone lief, dauerte einen Tag. Grob die Schritte:

# Projekt anlegen (TypeScript-Template)
npx create-expo-app kursportal

# Im Projekt: Datenanbindung, Screens, Navigation bauen
# dann Development Build in der Cloud erzeugen
eas build --profile development --platform ios

# App aufs Gerät, Dev-Server starten
npx expo start --dev-client

Am Ende des Tages stand nicht nur eine leere Hülle, sondern das Fundament: Navigation, Datenanbindung, Login-Logik und eine Liste mit echten Inhalten. Ein Prototyp, kein fertiges Produkt, das ist ein wichtiger Unterschied. Aber das Gerüst, auf dem ein Produkt entsteht, war da.

Eine Falle vorweg: Expo Go ist nicht der Weg zur eigenen App

Wer Expo ausprobiert, landet zuerst bei der App "Expo Go" aus dem Store. Die ist gut zum Spielen, aber eine Sackgasse, sobald die App eigene native Funktionen braucht: Expo Go ist an eine feste Framework-Version (das Expo-SDK) gebunden, die selten zur eigenen passt. Ein Downgrade über mehrere SDK-Versionen, nur damit das Gerät die App öffnet, bricht früher oder später das Projekt.

Der richtige Weg ist der Development Build: eine eigene App-Hülle, die man einmal über EAS baut und installiert. Ab dann lädt sie deinen Code per expo start --dev-client, und du bist frei in der SDK-Wahl. Konfiguriert wird das in einer schlanken eas.json mit einem development-Profil plus dem Paket expo-dev-client.

Eine typische Stolperstelle: die stille leere Liste

Eine Lektion, die exemplarisch ist für solche Setups: Die App lief, der Code war fehlerfrei, die Liste blieb trotzdem leer. Kein Fehler, keine Exception, einfach null Einträge.

Ursache war die Zugriffssteuerung der Datenbank. Supabase nutzt Row Level Security: ohne explizite Regel darf der öffentliche Schlüssel der App keine Zeile lesen, und liefert eben nicht einen Fehler, sondern ein leeres Ergebnis. Die Lösung ist eine Lese-Regel, die genau festlegt, was öffentlich sichtbar sein darf:

-- der anonyme App-Zugriff darf nur veröffentlichte Kurse lesen
create policy "public read kurse"
  on kurse for select
  to anon
  using (veroeffentlicht = true);

Das ist kein Expo-Thema, sondern gehört zu jeder App, die direkt mit einer Datenbank spricht: Erst die Zugriffsregeln machen aus "die App liest alles" ein kontrolliertes "die App liest genau das, was sie soll".

Updates ohne App-Store-Wartezeit

Ein Punkt, der im Tagesgeschäft schwerer wiegt als die erste Installation: Expo kann Over-the-Air-Updates. Änderungen am JavaScript-Teil der App, also der allergrößte Teil im Alltag, landen direkt beim Nutzer, ohne den Umweg über die Store-Freigabe von Apple oder Google.

Für ein KMU heißt das konkret: Ein Tippfehler im Text oder eine kleine Anpassung an einer Liste ist in Minuten draußen, nicht erst nach Tagen Review. Nur echte native Änderungen (neue Berechtigungen, neue Geräte-Funktionen) brauchen weiterhin einen neuen Store-Build.

Wann eine eigene App sinnvoll ist, und wann nicht

Werkzeug heißt nicht automatisch Anlass. Eine App lohnt sich nicht, weil sie technisch machbar ist, sondern weil sie einen Prozess wirklich besser macht.

Sinnvoll, wenn:

  • Kunden oder Mitarbeiter regelmäßig mobil etwas tun (buchen, erfassen, nachschauen) und eine Website dafür umständlich ist.
  • Native Funktionen gebraucht werden: Push-Benachrichtigungen, Kamera, Offline-Nutzung.
  • Die App eine Verlängerung eines Systems ist, das es schon gibt (Shop, Branchensoftware, Kundenportal).

Eher nicht, wenn:

  • Eine gut gemachte mobile Website denselben Zweck erfüllt. Für reines Lesen und Anschauen ist eine App oft Overkill.
  • Es nur um ein Kontaktformular oder eine Infoseite geht.
  • Niemand die App regelmäßig nutzt. Eine App, die man einmal im Jahr öffnet, hat im App-Store-Alltag keinen Platz.

Einordnung

Werkzeuge ändern sich, die eigentliche Frage bleibt dieselbe: Welcher Prozess soll für Kunden oder Mitarbeiter einfacher werden? Neu ist nur die Antwort auf die Aufwandsfrage. Eine eigene App ist kein Großprojekt mit sechsstelligem Budget mehr, sondern für viele KMU eine realistische Option, wenn der Anwendungsfall stimmt.

Genau das ist der Punkt, an dem es sich lohnt, einmal nüchtern hinzuschauen: nicht "brauchen wir eine App", sondern "welcher konkrete Ablauf wird mobil besser". Das ist eine halbe Stunde Gespräch, kein Großprojekt.