The Features I Decide Not to Build
Scope control is product engineering: every feature adds states, maintenance, support, and decisions that must remain understandable long after the first implementation.
Independent development makes tradeoffs visible. There is no separate team that absorbs every extra setting, backend service, support question, migration, and review implication after a feature is merged. Saying no is therefore not a lack of ambition. It is part of protecting the product's core loop.
Every feature creates states
A feature that sounds small usually has more than one state:
loading -> empty -> success -> error -> offline
permission denied -> expired -> migration -> deleted -> restoredNot every feature needs every state, but each dependency enlarges the space. Add cloud sync and there are conflicts, retries, and reconciliation. Add accounts and there are authentication, recovery, deletion, and privacy obligations. Add a subscription and there are cancellation, restore, entitlement refresh, billing issues, and store review expectations.
The first question is not “can I implement this?” It is “can I explain every meaningful state, test it, and support it after release?” A feature that does not clear that bar may still be a good future idea. It is not automatically a good current commitment.
Focus is a design decision
The projects in this portfolio are deliberately bounded in different ways. PassportPlate keeps its core experience account-free and local rather than turning dinner inspiration into a cloud profile system. 100 Reps stays focused on a clear daily workout loop rather than claiming to be a complete fitness platform. Ritual Grove is intentionally limited around a calm habit experience. Spheriz keeps its gameplay centered on the puzzle rather than adding complexity merely because a game could always contain another mode or progression system.
These are product choices, but they are also engineering choices. Focus reduces UI ambiguity, data modeling, testing surface, privacy exposure, and long-term support. It gives the few features that remain room to be coherent.
Maintenance is feature cost
Implementation is only the down payment. A feature may require compatibility across releases, analytics interpretation, localization, accessibility, edge-case documentation, content moderation, dependency upgrades, customer support, and a migration when the original assumption changes. A settings screen can be especially deceptive: every toggle preserves a decision the product could have made once and asks every user to make it repeatedly.
That is why configuration can be avoided decisions. A preference is valuable when users genuinely need different outcomes. It is less valuable when it exists because the product has not chosen a sensible default. Fewer options can be a more respectful interface if they remove work without removing meaningful control.
Technical sophistication is not the goal
A backend, microservice, AI feature, or synchronization system should justify itself through a user need. A local feature does not become more professional because it makes a network request. Equally, a server-backed feature should not be faked locally when fairness, shared state, or costly server work requires authority outside the client.
The useful standard is proportionate architecture. Keep state local when the product can honestly be local. Add services when collaboration, recovery, identity, or server authority earns their complexity. Then own the new responsibilities rather than treating them as a checkbox.
Small and complete beats infinite
Working while studying has reinforced the value of finishing a focused product. A complete loop teaches release preparation, error states, maintenance, and feedback in a way an endlessly expanding backlog cannot. This is not an argument against iteration. It is an argument for creating a stable thing worth iterating on.
When I decide not to build a feature, I try to record the reason: it does not strengthen the core use case yet, it introduces unsupported states, it shifts a decision to users, or it needs infrastructure the product has not earned. That makes “not now” an intentional decision rather than a forgotten idea, and leaves a clearer path if the product later changes.
This also makes prioritization more honest. The alternative to a new feature is rarely “nothing”; it may be fixing the path that already exists, improving recovery, reducing confusion, or preparing a release. Those investments are less visible in a changelog but often more valuable to the person using the product.
The same scope discipline appears in What I Learned From Shipping Multiple Apps While Still at University. Product engineering is not only expanding capability. It is preserving a product people can understand, use, and trust.
Used In
An offline mobile app that turns "what should I cook tonight" into a spin of the globe: land on a country, get an authentic recipe, and make dinner a small adventure.
A focused mobile workout tracker for daily rep-based challenges, animated exercise progress, streaks, and simple bodyweight consistency.
An offline-first habit tracker where daily rituals grow into a calm 3D grove. Built to make consistency visible, motivating, and less stressful.
A circular puzzle game that rethinks falling-block gameplay across a radial 2D board and a fully rotatable 3D globe, with handcrafted levels, progression, online services, and a cosmetic economy.
Related Tutorials
A practical architecture for React Native apps that remain useful without a connection: local source of truth, migrations, sync queues, conflicts, and honest failure handling.
How to add in-app purchases to an Expo app with RevenueCat: entitlements over product IDs, why restore is mandatory, and why the client is the wrong place to trust a purchase.