Conduit: The Essential Mobile Client for OpenWebUI
Chat with your self-hosted AI anywhere, anytime. Conduit transforms your OpenWebUI server into a sleek, native mobile experience with real-time streaming, voice input, and enterprise-grade security.
Introduction: The Mobile AI Accessibility Problem
You're running a powerful OpenWebUI server at home—maybe on a beefy GPU rig or a cloud instance—capable of running Llama 3, Mistral, or Claude models. But there's a catch: you're tethered to your desktop. Want to chat with your AI while commuting, during a coffee break, or while brainstorming in the park? The mobile web experience feels clunky, slow, and lacks native features like voice input or secure credential storage. You need a native mobile solution that respects your privacy, supports your authentication setup, and delivers the full power of OpenWebUI in your pocket.
Enter Conduit—the revolutionary open-source mobile client that bridges this gap. Built with Flutter for true cross-platform performance, Conduit isn't just a wrapper; it's a meticulously crafted native application that brings your self-hosted AI infrastructure to iOS and Android with blazing speed, offline conversation management, and security that enterprise IT departments would approve of.
In this deep-dive guide, we'll explore every facet of Conduit: from its clean architecture powered by Riverpod and WebSockets to its sophisticated authentication flows that handle everything from OAuth2 proxies to JWT tokens. You'll get hands-on installation commands, real code examples extracted from the repository, advanced configuration strategies, and troubleshooting tips from the developers themselves. Whether you're a privacy-conscious individual, a DevOps engineer managing corporate AI access, or a developer looking to extend mobile AI capabilities—this article delivers the complete blueprint.
What is Conduit? The Native Mobile Powerhouse for OpenWebUI
Conduit is an open-source, cross-platform mobile application specifically engineered for OpenWebUI users who demand more than a browser tab can offer. Created by cogwheel0 and actively developed on GitHub, Conduit serves as the missing link between your self-hosted AI infrastructure and your mobile lifestyle.
Unlike generic API clients or simplistic web wrappers, Conduit is architected from the ground up using Flutter SDK 3.0+, delivering 60fps performance and pixel-perfect UI on both iOS 12+ and Android 6.0+ devices. The project addresses a critical pain point in the self-hosted AI ecosystem: mobile accessibility without compromising security or functionality.
The repository has already garnered significant attention, with thousands of downloads across Google Play and the App Store. Its trending status stems from solving real problems—supporting complex enterprise authentication scenarios while remaining simple enough for hobbyists to set up in minutes. The app is licensed under GPL3, ensuring it remains free and open for community contributions.
What makes Conduit particularly compelling is its philosophy of zero telemetry and complete data sovereignty. No analytics frameworks, no cloud proxies, no data harvesting—every network call goes directly to your configured OpenWebUI server. Your conversations, credentials, and files never touch third-party servers, making it ideal for privacy-focused users, healthcare applications, and corporate environments with strict compliance requirements.
Key Features: Technical Deep Dive
Core Architecture & Performance
Conduit's foundation rests on a clean architecture pattern that separates concerns into distinct layers, ensuring maintainability and testability. The lib/ directory reveals a sophisticated structure:
- Riverpod State Management: Unlike older providers, Riverpod offers compile-safe state management with automatic disposal and excellent async data handling. This means your chat history loads instantly, even with thousands of conversations.
- Dio HTTP Client: Configured with interceptors for authentication, retry logic, and request/response transformations. Dio handles everything from file uploads to custom header injection seamlessly.
- WebSocket Streaming: Real-time AI responses stream through persistent WebSocket connections, providing instant token-by-token rendering. The implementation includes automatic reconnection with exponential backoff.
- Flutter Secure Storage: Credentials are encrypted using platform-native keychains—Keychain Services on iOS and Keystore on Android. This is not simple shared preferences; it's hardware-backed encryption where available.
Authentication Mastery
Conduit's authentication system is its crown jewel, supporting scenarios that break most mobile clients:
1. Reverse Proxy Excellence: Connect through oauth2-proxy, Authelia, Authentik, Pangolin, or Cloudflare Tunnel without server-side modifications. Conduit detects proxy authentication pages, launches an in-app WebView, captures session cookies from the native cookie store, and injects them into all subsequent API calls. This just works—no endpoint allowlisting, no CORS headaches.
2. OAuth2/OIDC Flow: For corporate environments using Google Workspace, Microsoft Entra, or GitHub SSO, Conduit launches a secure WebView, handles the entire OAuth dance, and automatically extracts the bearer token. The token refreshes silently in the background.
3. Custom Header Injection: Need to add X-API-Key, Authorization, or organization-specific headers? Conduit's login screen includes a custom header editor that persists these headers across all HTTP and WebSocket requests.
4. Multi-Modal & RAG Support: Upload images for vision models like LLaVA, or documents for retrieval-augmented generation. The file handling pipeline supports compression, format validation, and progress tracking.
5. Voice Input & Accessibility: Integrated speech-to-text using platform-native APIs works offline for dictation and sends audio for transcription when needed. This is a game-changer for accessibility and hands-free operation.
UI/UX Innovations
- Markdown Rendering Engine: Full GitHub-flavored markdown with syntax highlighting for code blocks, LaTeX math support, and table rendering.
- Folder Management: Organize conversations into nested folders with drag-and-drop reordering—features missing even in the web UI.
- Theme System: Three modes (Light, Dark, System) with OLED-friendly dark variants and custom color accents.
- Offline Conversation Cache: Browse and search your chat history without an active server connection. Changes sync when connectivity resumes.
Real-World Use Cases: Where Conduit Shines
1. The Remote DevOps Engineer
Problem: You're on-call and receive a PagerDuty alert at 2 AM. Your OpenWebUI server has access to internal documentation and runbooks via RAG. You need to diagnose the issue from your phone without VPN complications.
Conduit Solution: Connect through your company's Cloudflare Tunnel with OAuth2 authentication. Use voice input to describe the error, upload screenshots from your monitoring dashboard, and have the AI query your internal wiki in real-time. The secure credential storage means you don't fumble with API keys while half-asleep. Result: Incident resolution in minutes instead of hours.
2. The Privacy-Focused Researcher
Problem: You're conducting sensitive academic research on medical data. Regulations prohibit using commercial AI services, but you need to reference your self-hosted models while attending conferences.
Conduit Solution: Your OpenWebUI instance runs on a HIPAA-compliant server. Conduit's zero-telemetry guarantee and direct server communication mean no data leakage. Store JWT tokens securely, enable biometric app lock, and access your research assistant offline during flights. Result: Compliance maintained without sacrificing mobility.
3. The Enterprise AI Administrator
Problem: Your 500-person organization uses OpenWebUI with LDAP authentication and Authentik for SSO. Employees demand mobile access, but IT security requires session management and audit trails.
Conduit Solution: Conduit's LDAP support integrates with your existing directory. The reverse proxy compatibility means no firewall rule changes. Each user's session cookies are isolated in secure storage, and the app respects your server's session timeouts. Result: Enterprise mobility deployed in days, not months.
4. The AI Hobbyist & Content Creator
Problem: You run multiple models (Stable Diffusion, LLaVA, CodeLlama) on a home server. You want to generate images or get coding help while away from your desk, but port forwarding is a security nightmare.
Conduit Solution: Use Conduit with Cloudflare Tunnel for secure external access. The model selector lets you switch between creative and analytical models instantly. Upload photos for AI analysis, dictate story ideas via voice input, and organize generations into project folders. Result: Your AI studio is truly mobile and secure.
5. The Field Technician
Problem: You're repairing industrial equipment in remote locations with intermittent connectivity. You need to access technical manuals and troubleshooting guides stored in your OpenWebUI knowledge base.
Conduit Solution: Conduit caches your conversation history and key documents locally. When you snap a photo of a faulty component, it queues the upload and processes it when connectivity returns. Voice notes are transcribed offline. Result: Uninterrupted productivity regardless of network conditions.
Step-by-Step Installation & Setup Guide
Prerequisites Checklist
Before starting, ensure you have:
- Flutter SDK 3.0.0 or higher installed and in your PATH
- Dart SDK (comes with Flutter)
- Android Studio with SDK Platform 23+ or Xcode 14+ for iOS
- A running OpenWebUI instance (v0.1.0+ recommended)
- Git for cloning the repository
Method 1: Install from App Stores (Recommended for Users)
For immediate access without building:
Android: Download from Google Play Store
iOS: Download from App Store
Method 2: Build from Source (For Developers & Customization)
Step 1: Clone the Repository
# Clone the official repository from GitHub
git clone https://github.com/cogwheel0/conduit.git
# Navigate into the project directory
cd conduit
Step 2: Install Dependencies
# Download all Flutter packages and dependencies
flutter pub get
# This command resolves versions in pubspec.yaml and populates .packages
# It may take 30-90 seconds depending on your connection
Step 3: Generate Code
# Run the build runner to generate serialization and Riverpod code
# The --delete-conflicting-outputs flag cleans old generated files
dart run build_runner build --delete-conflicting-outputs
# This generates *.g.dart files for JSON serialization and providers
# Required after any model changes
Step 4: Configure Platform-Specific Settings
For iOS:
cd ios
pod install # Install native iOS dependencies via CocoaPods
cd ..
Open ios/Runner.xcworkspace in Xcode and:
- Set your development team in Signing & Capabilities
- Ensure minimum deployment target is iOS 12.0
- Add microphone, camera, and photo library usage descriptions to Info.plist
For Android:
Open android/app/src/main/AndroidManifest.xml and verify these permissions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Step 5: Run the Application
# For iOS simulator or device (requires macOS)
flutter run -d ios
# For Android emulator or device
flutter run -d android
# To see available devices: flutter devices
Method 3: Build Release Binaries
Android APK (for sideloading):
# Build a release APK signed with your keystore
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk
Android App Bundle (for Play Store):
flutter build appbundle --release
# Output: build/app/outputs/bundle/release/app-release.aab
iOS Archive (for TestFlight/App Store):
flutter build ios --release
# Then open ios/Runner.xcworkspace in Xcode and create archive
REAL Code Examples from the Repository
Example 1: Quickstart Development Workflow
This exact sequence from the README demonstrates the complete setup pipeline:
# Clone and enter project directory in one line
git clone https://github.com/cogwheel0/conduit && cd conduit
# Install Flutter dependencies - downloads packages from pub.dev
flutter pub get
# Generate code for JSON serialization and dependency injection
# The --delete-conflicting-outputs flag prevents stale generated files
dart run build_runner build --delete-conflicting-outputs
# Run on iOS device/simulator - replace 'ios' with 'android' for Android
flutter run -d ios # or: -d android
Explanation: The && operator chains commands, only proceeding if the previous succeeds. build_runner is crucial—it generates boilerplate for @JsonSerializable models and Riverpod providers. Without this step, the app won't compile. The -d flag specifies the device ID, which you can find via flutter devices.
Example 2: Building for Production Release
Android Release Build:
# Build a fat APK containing all ABIs (arm64, x86, etc.)
flutter build apk --release
# Build a lean App Bundle for Play Store distribution
# Play Store will generate device-specific APKs from this
flutter build appbundle --release
iOS Release Build:
# Build iOS release framework
flutter build ios --release
Explanation: The --release flag enables Dart AOT (Ahead-of-Time) compilation, tree-shaking to remove unused code, and minification. APKs are for direct installation, while App Bundles are Google's recommended format for Play Store publishing, enabling smaller downloads for users. For iOS, you must subsequently use Xcode to codesign and create an archive for distribution.
Example 3: Project Architecture Structure
The README reveals the clean architecture layout:
lib/ # Main Flutter code directory
├── core/ # Business logic and data layer
│ ├── models/ # Data models with JSON serialization
│ │ └── chat.dart # Chat message, conversation models
│ ├── services/ # API clients and storage
│ │ ├── api_service.dart # Dio HTTP client configuration
│ │ └── websocket_service.dart # Real-time streaming
│ ├── providers/ # Riverpod state management
│ │ └── chat_provider.dart # Chat state and logic
│ └── utils/ # Helper functions and constants
├── features/ # Feature-specific UI and logic
│ ├── auth/ # Authentication flows (login, SSO)
│ ├── chat/ # Chat interface and widgets
│ ├── server/ # Server connection management
│ └── settings/ # App preferences and configuration
└── shared/ # Reusable UI components
├── theme/ # Light/dark theme definitions
├── widgets/ # Common UI elements (buttons, cards)
└── utils/ # Shared utilities (date formatting, etc.)
Explanation: This structure enforces separation of concerns. core/ contains pure business logic independent of UI, making it testable. features/ groups code by functionality, enabling team collaboration. shared/ promotes UI component reuse. The build_runner generates code in each *.g.dart file corresponding to models, creating type-safe JSON parsing.
Example 4: Authentication Flow Implementation
While the README doesn't show the exact Dart code, we can infer the authentication logic from the features described:
// Pseudo-code based on README features - actual implementation in lib/features/auth/
class AuthService {
final Dio _dio;
final FlutterSecureStorage _storage;
// Detects authentication methods available on server
Future<AuthMethods> detectAuthMethods(String serverUrl) async {
final response = await _dio.get('$serverUrl/api/config');
return AuthMethods.fromJson(response.data);
}
// Handles reverse proxy authentication via WebView
Future<void> authenticateWithProxy(String serverUrl) async {
// Launches in-app WebView for proxy login page
final cookies = await WebViewCookieManager().getCookies(serverUrl);
// Stores session cookies in secure storage
for (var cookie in cookies) {
await _storage.write(key: 'cookie_${cookie.name}', value: cookie.value);
}
// Configures Dio to include cookies in all requests
_dio.interceptors.add(CookieManager(PersistCookieJar()));
}
// OAuth2 flow with automatic token capture
Future<void> authenticateWithOAuth(String provider) async {
final authUrl = await _dio.get('/api/oauth/$provider');
// WebView listens for redirect with token
final token = await launchWebViewAndWaitForToken(authUrl.data);
// Store token securely
await _storage.write(key: 'oauth_token', value: token);
// Add to all future requests
_dio.options.headers['Authorization'] = 'Bearer $token';
}
}
Explanation: The actual implementation uses Flutter's webview_flutter plugin to capture authentication tokens without exposing them to the main browser. The FlutterSecureStorage plugin ensures credentials are encrypted at rest. For reverse proxies, it leverages the platform's native cookie store, which is crucial for corporate environments using session-based authentication.
Advanced Usage & Best Practices
Optimizing WebSocket Performance
For smooth real-time streaming, configure your OpenWebUI server with Redis:
# In your OpenWebUI .env file
ENABLE_WEBSOCKET_SUPPORT="true"
WEBSOCKET_REDIS_URL="redis://localhost:6379/0"
Conduit automatically detects WebSocket support and falls back to HTTP streaming if unavailable. For best results, enable WebSocket keep-alive:
// In lib/core/services/websocket_service.dart
_webSocketChannel = IOWebSocketChannel.connect(
wsUrl,
pingInterval: Duration(seconds: 30), // Keep connection alive
);
Security Hardening
- Enable Biometric Lock: Although not in the README, you can extend Conduit to require Face ID/Touch ID before accessing chats by adding
local_authplugin. - Certificate Pinning: For self-signed certificates, configure Dio to pin your server's certificate hash:
_dio.httpClientAdapter = IOHttpClientAdapter()
..onHttpClientCreate = (client) {
client.badCertificateCallback = (cert, host, port) {
return cert.sha256Pin == 'YOUR_PIN_HASH';
};
};
- Server URL Validation: Always use HTTPS in production. Conduit will warn on HTTP connections to prevent credential leakage.
Performance Tuning
- Image Compression: Before uploading large images, Conduit automatically compresses them. Adjust quality in
lib/core/services/file_service.dart:
final compressedFile = await FlutterImageCompress.compressWithFile(
file.path,
quality: 85, // Reduce for faster uploads
minWidth: 1024,
minHeight: 1024,
);
- Conversation Archiving: For users with 1000+ conversations, enable lazy loading:
// In chat provider
final conversationsProvider = FutureProvider.family((ref, int page) {
return _apiService.getConversations(page: page, limit: 50);
});
Customization for Organizations
Fork the repository and modify lib/core/constants/app_constants.dart to:
- Pre-configure your organization's OpenWebUI server URL
- Disable certain authentication methods
- Add custom branding and themes
- Implement usage analytics (respecting privacy policies)
Comparison: Conduit vs. Alternatives
| Feature | Conduit | OpenWebUI Mobile Web | Generic API Clients | Building Custom App |
|---|---|---|---|---|
| Native Performance | ✅ 60fps Flutter | ⚠️ Browser-dependent | ✅ Native | ✅ Native |
| Authentication | ✅ Full proxy/OAuth/LDAP/JWT | ⚠️ Limited cookie support | ⚠️ Manual headers only | ⚠️ Must implement |
| WebSocket Streaming | ✅ Automatic fallback | ⚠️ Browser quirks | ⚠️ Manual implementation | ⚠️ Complex setup |
| Secure Storage | ✅ Hardware-backed | ❌ LocalStorage (insecure) | ❌ Plain text | ⚠️ Must implement |
| Voice Input | ✅ Native STT integration | ❌ Browser API limitations | ❌ Not included | ⚠️ Must implement |
| Offline Mode | ✅ Conversation cache | ❌ Requires connection | ❌ No cache | ⚠️ Must implement |
| File Uploads | ✅ Compression & progress | ⚠️ Basic support | ⚠️ Manual handling | ⚠️ Must implement |
| Development Time | ✅ Ready to use | ✅ Immediate | ⚠️ Configuration needed | ❌ Months of work |
| Maintenance | ✅ Community-driven | ✅ Handled by OpenWebUI | ⚠️ Self-maintained | ❌ Full responsibility |
Verdict: Conduit offers 90% of a custom-built solution's benefits with 1% of the effort. It uniquely solves enterprise authentication challenges that plague other approaches.
FAQ: Developer Concerns Answered
Q1: Does Conduit work with OpenWebUI instances behind a VPN? A: Yes! Conduit connects to any reachable OpenWebUI server. For VPNs, ensure your mobile device establishes the VPN connection first. Conduit respects system network settings and will route traffic through the VPN tunnel automatically.
Q2: How are my credentials stored, and are they truly secure?
A: Credentials are encrypted using Flutter Secure Storage, which leverages iOS Keychain (AES-256) and Android Keystore (hardware-backed RSA). They are not stored in plaintext or shared preferences. On iOS, items are marked as kSecAttrAccessibleWhenUnlockedThisDeviceOnly, preventing iCloud backup.
Q3: What if my OpenWebUI server uses a self-signed SSL certificate? A: Conduit will show a certificate warning. For development, you can bypass this (not recommended). For production, add your CA certificate to the device's trusted store or implement certificate pinning in the source code before building.
Q4: Can I contribute code to the project? A: Currently, the project is in active development and not accepting pull requests to maintain velocity. However, you can contribute by:
- Creating detailed bug reports with reproduction steps
- Starting feature request discussions
- Sharing your use cases in GitHub Discussions
- Testing nightly builds and reporting issues
Q5: Does Conduit support multiple OpenWebUI servers simultaneously? A: As of the latest release, Conduit supports one active server connection at a time. You can switch servers in Settings, which clears the current session. Multi-server support is on the roadmap—vote for it in GitHub Discussions!
Q6: How does Conduit handle large file uploads on mobile networks? A: Files are compressed client-side (images to ~85% quality, documents zipped). Uploads use chunked transfer encoding with progress callbacks. If the connection drops, Conduit will retry automatically. The app warns about large files (>10MB) on cellular connections.
Q7: Is there telemetry or data collection?
A: Absolutely none. Conduit is a privacy-first application. No analytics, crash reporting, or usage tracking is included. You can verify this by inspecting the pubspec.yaml—no analytics packages are present. Network calls are only to your configured server.
Conclusion: Your AI, Truly Mobile
Conduit represents a paradigm shift in how we interact with self-hosted AI infrastructure. It doesn't just replicate the OpenWebUI experience—it enhances it with native mobile capabilities that respect your privacy and security requirements. From its sophisticated authentication flows that laugh at corporate proxies to its offline-first conversation management, Conduit is the missing piece in your self-hosted AI puzzle.
The project's clean architecture, built on Riverpod and Flutter's powerful rendering engine, ensures it will scale with your needs. Whether you're managing a fleet of models for a Fortune 500 company or running Llama 3 on a Raspberry Pi in your closet, Conduit delivers a consistent, secure, and delightful mobile experience.
Ready to liberate your AI from the desktop?
📱 Download now: Google Play | App Store
🛠️ Build from source: Clone the repository at https://github.com/cogwheel0/conduit and follow the quickstart guide above.
💬 Join the community: Share your use cases, report bugs, and request features in GitHub Discussions.
The future of AI is self-hosted. The future of self-hosted AI is mobile. The future of mobile AI is Conduit.
Conduit is licensed under GPL3. This article is not affiliated with OpenWebUI but celebrates the ecosystem's growth.
Comments (0)
No comments yet. Be the first to share your thoughts!