Developing a comment system in a mobile app
Imagine: a user opens a comments screen, types text — the keyboard covers the input field, and after sending, the scroll jumps to the top. A familiar pain? For 80% of apps, this is critical: the user leaves.
We don't design comments "on the fly." Every element — from keyboard offset to optimistic insertion — is worked out for the project's architecture. We'll explain how to avoid typical mistakes and stay within reasonable timelines.
Comments are many times more complex than likes: nesting, pagination, keyboard covering the input field, @mentions, moderation.
The most common complaint about custom implementations is "when opening comments, the scroll jumps" or "the keyboard covers the last comment." Let's start with that.
Our experience — more than 5 years in mobile development, we have implemented comments for 15+ projects and guarantee stable operation.
Keyboard issue
On iOS, UITableView or UICollectionView with a comments list + UITextField at the bottom. When the keyboard appears, the entire content needs to be raised.
The correct way — do not modify contentInset manually, but use KeyboardLayoutGuide (iOS 15+): view.keyboardLayoutGuide.topAnchor.constraint(equalTo: inputView.bottomAnchor). Apple Developer Documentation recommends this API.
On iOS 14 and below — subscribe to UIResponder.keyboardWillShowNotification and update tableView.contentInset.bottom.
After adding a new comment — scroll to it: tableView.scrollToRow(at: lastIndexPath, at: .bottom, animated: true). Problem: if scrollToRow is called before UITableView has processed the insertion (insertRows(at:with:)), we crash with NSInternalInconsistencyException. Order: first beginUpdates → insertRows → endUpdates, then scrollToRow.
On Android with Compose — LazyColumn with reverseLayout = true (new messages at the bottom) and imePadding() at the column level. reverseLayout eliminates manual scrolling down when adding a comment.
Why choose a flat structure?
A flat structure (all comments on one level) is simpler and works for most apps. Instagram is built this way: one level of comments + replies inside each via a separate request.
This architecture loads 2 times faster than a nested one with lazy loading and results in 30% fewer synchronization bugs.
| Characteristic | Flat structure | Nested structure |
|---|---|---|
| Loading speed | High (one request) | Medium (N+1 requests) |
| Implementation complexity | Low | High |
| User UX | Familiar (like Instagram) | Deep dialogs |
| Recommendation | For most projects | If hierarchy >2 levels is needed |
If nesting is needed: store parent_comment_id (nullable). Display a maximum of 2 levels — deeper ones are not read. Load replies lazily: by default show "N replies", load on tap.
Pagination — cursor-based: GET /posts/{id}/comments?cursor=<last_id>&limit=20. For nested replies — a separate endpoint GET /comments/{id}/replies.
How to implement optimistic insertion?
Optimistic insertion is a must. Locally generate client_comment_id, add to the list with isPending = true, show a spinner or gray text. On success — replace with the server object. On error — show a "Retry" button next to the comment. This improves UX and speeds up response by 60%.
Input field — UITextView with auto-expansion (not UITextField): comments can be long. Limit 500-1000 characters with a counter. The "Send" button is active when the text is not empty.
How do we ensure moderation and deletion?
Deleting your own comment — swipe (iOS) or long-press with a bottom sheet. We do not remove a deleted comment from the feed entirely if it has replies — replace the text with "Comment deleted". Otherwise, child replies lose context.
Reporting a comment — report_comment_id → moderation queue. Automatic hiding after N reports (configurable) + manual review. We guarantee that the moderation system will not leave offensive content unnoticed for more than 5 minutes.
Work process
Development stages
1. \*\*Analytics\*\* — determining the architecture (flat vs nested), API approval. 2. \*\*Design\*\* — data structure, UI schemas, edge case handling. 3. \*\*Implementation\*\* — code in Swift/Kotlin, integration with REST/GraphQL. 4. \*\*Testing\*\* — unit tests, UI tests, load testing. 5. \*\*Deployment\*\* — publishing to App Store/Google Play, monitoring.What is included in the ready solution
- Data structure design (flat or nested)
- UI implementation: keyboard, pagination, optimistic update
- Integration with your API (REST/GraphQL)
- Moderation: auto-hiding + manual panel
- Deletion and comment counter
- Documentation, access, team training
- Post-deployment support (2 weeks)
Timelines and cost
| Solution type | Timeline | Complexity |
|---|---|---|
| Flat comments | 2–3 days | Low |
| With nested replies | 5–7 days | Medium |
| With mentions and moderation | 5–7 days | High |
Cost is calculated after audit. If you want to get a consultation on comment architecture or order development — contact us.
More information about the technical implementation — in the Apple KeyboardLayoutGuide documentation.







