I just released my second app on the Google Play Store — Pinpoint, a privacy-focused note-taking app built with Flutter. After months of development, countless iterations, and learning a ton about encryption, cloud sync, and the freemium business model, I wanted to share the journey.
🔗 Links:
Why Another Note-Taking App?
I know what you're thinking — the world doesn't need another notes app. But here's the thing: most note apps either sacrifice privacy for features or sacrifice features for privacy. I wanted both.
The goals were simple:
- End-to-end encryption that actually works
- Beautiful, modern UI (not just functional)
- Multiple note types beyond just text
- Cloud sync without compromising privacy
- A sustainable freemium model
The Tech Stack
Here's what powers Pinpoint under the hood:
Core Framework
- Flutter 3.6+ — Cross-platform goodness
- Dart — Modern, type-safe language
- Material 3 — Latest Material Design guidelines
Local Database
- Drift 2.24 — Type-safe SQLite with reactive queries. This was a game-changer for real-time updates.
Security
-
AES-256 Encryption — Using the
encryptpackage - Flutter Secure Storage — For secure key management
- Local Auth — Biometric authentication (fingerprint/Face ID)
State Management & Architecture
- Riverpod 3.0 — Modern reactive state management
- Go Router — Declarative navigation
- GetIt — Dependency injection
Cloud & Backend
- Firebase Authentication — Google Sign-In
- Custom FastAPI Backend — For cloud sync and usage tracking
Features I'm Most Proud Of
1. Multiple Note Types
Not just plain text. Pinpoint supports:
- Rich text notes with formatting
- Audio recordings with playback controls
- Todo lists with real-time auto-save
- Reminders with timezone-aware notifications
2. The Glassmorphism UI
I spent way too much time on this, but the frosted glass effects throughout the app just feel right. Combined with 5 accent color themes (Mint, Iris, Rose, Amber, Ocean) and smooth animations, it's genuinely pleasant to use.
// Example: Glassmorphism container
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(24),
border: Border.all(color: Colors.white.withOpacity(0.2)),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: // content
),
)
3. Real End-to-End Encryption
Notes are encrypted on-device before they ever leave your phone. The encryption key is derived from your master password and stored securely — I never see your notes.
4. OCR & Voice Transcription
Using Google ML Kit, you can extract text from images. Speech-to-text lets you quickly dictate notes when typing isn't convenient.
5. The Freemium Model
I implemented a fair usage-based model:
| Feature | Free | Premium |
|---|---|---|
| Synced Notes | 50 | Unlimited |
| OCR Scans | 20/month | Unlimited |
| Exports | 10/month | Unlimited |
| Voice Recording | 2 min | Unlimited |
| Folders | 5 | Unlimited |
Usage is tracked both locally and on the backend to prevent bypassing limits.
Architecture Decisions
Clean Architecture with Service Layer
I went with a service-based architecture that keeps business logic separate from UI:
lib/
├── screens/ # UI screens
├── components/ # Reusable UI components
├── services/ # Business logic layer
├── database/ # Drift database
├── entities/ # Database tables
├── design_system/ # Colors, typography, theme
└── navigation/ # Go Router config
Database Schema (Drift)
The schema supports many-to-many folder relationships:
// Simplified schema
tables:
- notes (id, title, content, type, encryption, timestamps)
- note_folders (id, title)
- note_folder_relations (note_id, folder_id)
- note_todo_items (id, note_id, title, is_done)
- note_attachments (id, note_id, file_path, type)
Stream-Based Reactivity
Drift's watch queries made real-time updates trivial:
Stream<List<Note>> watchAllNotes() {
return (select(notes)
..orderBy([(t) => OrderingTerm.desc(t.updatedAt)]))
.watch();
}
Challenges I Faced
1. Google Play Billing Integration
Setting up in-app subscriptions was... painful. Between base plans, offers, and tags, I spent a solid week just understanding the terminology. Pro tip: read Google's docs three times before you start coding.
2. Cloud Sync Conflicts
When the same note is edited on two devices offline, which version wins? I implemented a "last write wins" strategy with timestamps, but this is still an area I want to improve.
3. Todo List Auto-Save
Getting todo items to auto-save without losing the user's cursor position or creating race conditions was trickier than expected. I ended up using debouncing with temporary IDs for unsaved items.
What's Next?
The roadmap includes:
- Collaboration — Share notes with others
- Tags System — Beyond just folders
- Markdown Editor — Full markdown support
- iOS Release — App Store deployment
- Web Clipper — Save content directly from browser
Try It Out!
If you're looking for a note-taking app that respects your privacy without compromising on features, give Pinpoint a try:
The app is open source, so feel free to poke around the code, open issues, or contribute. I'd love to hear your feedback!
Wrapping Up
Building Pinpoint taught me a lot about Flutter, encryption, cloud architecture, and what it takes to ship a real product. If you're thinking about building your own app, my advice is simple: just start. The learning happens in the doing.
Thanks for reading! Drop a comment if you have questions about the implementation or want me to dive deeper into any specific part.
Tags: #flutter #dart #mobile #opensource #privacy
Top comments (0)