Picking the feature

What ships well across surfaces.

5 mineasy

Before diving into four implementations, pick the right feature to build. Not every feature ships well on every surface β€” some are web-first, some are mobile-first, some only make sense on desktop. The wrong pick wastes the chapter.

Our pick β€” Bookmarks

Bookmarks: let the user save products to a personal list, view them, remove them. It's our running example for the next three lessons. Why?

  • Simple data model. One table: bookmarks(id, user_id, product_id, created_at).
  • Cross-surface obvious. Users expect to bookmark on phone, see it on web. Multi-platform is the value.
  • Trivial offline story. Save bookmark offline β†’ push when online. Good for chapter 4.
  • Shows the shared layer. One type, one Zod schema, three frontends.

The decision rubric

For any feature, ask:

  • Where do users START? If 90% of usage is on mobile, build mobile first. Don't force a desktop UI for a feature nobody opens desktop for.
  • Where do users FINISH? "Quick-add on mobile, manage on web" is a common pattern. Lean into it; don't replicate the full UX on every surface.
  • What HARDWARE matters? Camera β†’ mobile-first. Keyboard shortcuts β†’ desktop/web. Push notifications β†’ mobile + web; not desktop (usually).
  • Can it survive offline? If yes, mobile + desktop need a sync story. If no, fail fast with a clear error.

Examples by category

  • Web-first / mobile read-only: Admin panels, billing, settings. Power-user features. Heavy form work.
  • Mobile-first / web view-only: Photo capture, location check-in, "quick action" flows.
  • Desktop-first: File I/O at scale (batch import / export), offline-tolerant tools, long-running tasks (PDF generation), shortcuts-heavy workflows.
  • Equal across all: Bookmarks, comments, notifications, profile. Light data, mostly read.
Don't force feature parity. The dangerous trap is "every feature on every surface". That triples cost without tripling value. Each surface should have its strengths; the API just needs to support all of them.

What we'll build over the next 3 lessons

Bookmarks, end to end:

  • API β€” POST /api/bookmarks, GET /api/bookmarks, DELETE /api/bookmarks/:id. (We'll touch this briefly β€” the focus is the four frontends.)
  • Web β€” bookmark button on a product page, /bookmarks list page.
  • Mobile β€” heart icon on product card, dedicated Bookmarks tab.
  • Desktop β€” keyboard shortcut (Cmd/Ctrl+D), bookmarks sidebar.

Same backend, three different presentations playing to each surface's strengths.

Quick API scaffold (we'll trust this and move on)

Use the resource generator so we can focus on the frontends:

  • Run grit generate resource Bookmark user_id:uint product_id:uint
  • That gives us model + handler + routes + Zod schemas + TS types.
  • Add an auth gate so users can only see their own bookmarks (we'll show the snippet next lesson).

Quick check

A teammate proposes adding a 12-step KYC form to the mobile app because 'we should have feature parity'. The same form exists on web. What's the recommended approach?

Try it

Set up for the next three lessons:

  1. Run grit generate resource Bookmark user_id:uint product_id:uint
  2. Edit the generated handler so the LIST endpoint only returns bookmarks for the authed user (filter by user_id = c.GetUint("user_id")).
  3. Add a unique index on (user_id, product_id) so a user can't bookmark the same product twice.
  4. Run grit sync to update shared types.
  5. Use Postman / curl to POST a bookmark and GET the list. Confirm the auth gate works.

Once that's green, you're ready for the implementation lessons.

What's next

Next lesson β€” Web implementation. Bookmark button, list page, optimistic UI updates with React Query.

Spot a typo? Have an idea?

Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled β€” suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.

Suggest an improvement on GitHub