Most bookmark and read-it-later tools suffer from the same pattern: bloated web dashboards, heavy cloud dependencies, and subscriptions for basic search features.
I wanted a mobile solution that prioritizes capture speed, offline performance, and complete local privacy. Here is how I designed and built Social Link Vault AI using Flutter and SQLite FTS5.
🏗️ Technical Architecture
The app is built on clean architecture principles, separating presentation, domain, and local data persistence:
-
Core Storage: Local SQLite database via
sqflite. -
Search Engine: Full-Text Search 5 (
FTS5) virtual tables for real-time, zero-latency queries across thousands of items. - State Management: BLoC / Cubit for deterministic reactive UI states.
-
AI Layer: Google Gemini API (
google_generative_ai) for automated summarization, topic tagging, and category routing.
// SQLite FTS5 Virtual Table Configuration
await db.execute('''
CREATE VIRTUAL TABLE IF NOT EXISTS links_fts USING fts5(
title,
url,
description,
ai_summary,
notes,
tags,
content='links',
content_rowid='id'
);
''');
⚡ Key Engineering Challenges
1. Zero-Friction Capture & URL Sanitization
When sharing a URL from social apps, links are often bloated with tracking parameters such as utm_*, fbclid, igshid, and ref.
The ingestion router automatically strips this query noise before writing the URL to the database:
String sanitizeUrl(String rawUrl) {
final uri = Uri.parse(rawUrl);
final cleanParams = Map<String, String>.from(uri.queryParameters)
..removeWhere(
(key, _) =>
key.startsWith('utm_') ||
{'fbclid', 'igshid', 'si', 'ref'}.contains(key),
);
return uri.replace(queryParameters: cleanParams).toString();
}
2. Zero-Permission Storage Compliance
Instead of requesting broad Android media storage permissions such as READ_MEDIA_IMAGES, the app relies strictly on:
- The native Android System Photo Picker.
- The Storage Access Framework (SAF) for exports.
This keeps the app's permission footprint minimal while still supporting backup and media-related workflows.
3. Biometrics & On-Device Security
Sensitive text snippets, such as API keys, recovery phrases, and confidential notes, are encrypted and masked with •••••••••••• by default.
Unmasking requires biometric authentication, such as Fingerprint or PIN, backed by hardware keystores through flutter_secure_storage.
🚀 Try the Open Beta
The app is currently in Open Beta on Google Play:
👉 Download / Test on Google Play
I'd love feedback from fellow Flutter developers on the capture UX, local search indexing speed, and offline backup flow

Top comments (0)