I Know What I Need, But I Don't Know How to Build It
"I know I need a shopping cart. I have no idea how to implement a shopping cart." The gap is not a missing library or a missing tutorial; it is that "cart" has not yet been turned into state, operations and rules. Once it has, the code is short.
The situation, the reflex, and why it stalls
Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.
You know exactly which feature you need and you cannot write its first line. What is actually missing, and what do you do in the next hour instead of searching for code?
The store has products on a page. The next thing is obviously a cart — you can picture the button, the badge with the count, the little list with quantities. You open a file called cart.ts and nothing comes. You know what a cart *does*; you have no idea what to *type*. It feels like a gap in programming ability.
Search "shopping cart react typescript" or ask an assistant to write the cart. Both return code in seconds, and code in the editor feels like the gap closing: there is a class, there are methods, the badge could be wired up this afternoon.
The code is there and you cannot say why any line is there. Ask "why does the cart store a product name?" and the answer is "the tutorial did". The first requirement the tutorial did not have — adding the same product twice — produces a bug you cannot locate, because you never decided what adding twice *should* do.
- The code is there and you cannot say why any line is there. Ask "why does the cart store a product name?" and the answer is "the tutorial did". The first requirement the tutorial did not have — adding the same product twice — produces a bug you cannot locate, because you never decided what adding twice *should* do.
- The assistant's cart has fifteen fields and a checkout method, so the thing you were unsure about is now bigger and still not understood. Deleting the parts you do not need requires knowing which parts those are, which is the understanding you were trying to skip.
- The reflex produced a representation before a meaning. Whether the items live in an array or a map was decided by whoever wrote the snippet, for their reasons, and you now defend a choice you did not make.
- Nothing was produced that you could test against. There is no list of what a cart must do, no example of a cart before and after an operation, no rule it must never break — so "does it work?" has no answer except "it did not crash".
The move
Precisely enough to apply it to a problem you have never seen — not a slogan.
- Name what is actually missing. It is not syntax and it is not a library: it is that "cart" is still one word. A word cannot be implemented; a description of what it remembers, what can happen to it and what must always hold can. The gap between "I need a cart" and "I can write addItem" is closed by writing that description, and the description is in plain English.
- Turn the word into a sentence about meaning: "a temporary collection of products the user intends to purchase, held between browsing and checkout" — the cart record's own definition. Then ask the three questions every concept answers before any code: what must it remember (items, each a product id and a quantity), what can happen to it (add, remove, change quantity, view, total, clear), what must always be true (every quantity is greater than zero; one entry per product).
- Write one concrete example per operation as before → operation → after. "Cart = [] · add Laptop · [ Laptop × 1 ]". "[ Laptop × 1 ] · add Laptop · [ Laptop × 2 ]". The second example is where the rule "one entry per product" is discovered; a rule you found from an example is one you can test.
- Only now choose how to represent the state and write the operation in plain English, then pseudocode, then code — one operation, not the whole cart. The code for addItem is eight lines, and every one of them traces back to a sentence you wrote before it. That is what "I know how to build it" means: not that the code came quickly, but that it came *from* something.
What the gap is made of
The reflex reads "I don't know how to implement a cart" as a gap in programming knowledge and reaches for code. Written as an unknowns board, the gap turns out to be a set of questions about the cart itself — none of which a library answers, and each of which has an experiment that takes minutes.
Notice that everything on the known side is behaviour a shopper would recognise, and nothing on the unknown side needs a framework to resolve.
- ✓A cart is a temporary collection of products the shopper intends to buy, held between browsing and checkout.
- ✓Add, remove, change quantity, view, total and clear are the six things that can happen to it.
- ✓The catalog owns products, names and prices; the cart points at products by id.
- ~One shopper, one process, one currency in V0 — written down so that "which cart?" can become a question later without surprising anyone.
? I don't know how to code the cart.
becomes What does the cart have to remember for the six operations to be possible, and which of those could be looked up instead of stored?
experiment Write the field list; for each field, name the operation that reads it. A field no operation reads is dropped.
? What happens with duplicates?
becomes When the same product is added twice, should the cart hold two entries or one entry with quantity 2 — and which operations does the answer change?
experiment Write the before/after for "[ Laptop × 1 ] · add Laptop" and check it against what a shopper would expect to see.
? Array or object or map?
becomes Which operations are frequent, does display order matter, and how large can a cart get?
experiment Annotate add, remove and view with their cost in an array and in a map; see whether the difference is visible at cart sizes.
None of these unknowns is about syntax. That is the point: the gap between "I need a cart" and "I can implement a cart" is closed in English.
The question, asked three ways
The same need, asked of a search engine, of a colleague, and of yourself. The first returns code you cannot defend; the third returns the exact thing you need to write next.
why The best form names one operation, one example and one rule, so its answer is a line of pseudocode rather than a repository. The vague form can only be answered with someone else's cart.
The first example, as a state change
Before any representation is chosen, a before/after example says what "add" means. This one is the cart record's own second example — the one where the rule "one entry per product" was discovered — and it is enough to write addItem from.
[ Laptop × 1 ]
[ Laptop × 2 ]
The implementation ladder
Concept, examples, pseudocode, code, tests, production — for the concept this lesson is about. Code is the fourth tab, not the first.
Shopping Cart = A temporary collection of products the user intends to purchase, held between browsing and checkout.
- Does a cart have identity? Yes, weakly. Two carts with the same items are still two carts, because each belongs to someone and will become a different order. It needs an id once it leaves memory; in memory the variable is the identity.
- Who owns it? A shopper — a logged-in user or an anonymous session. The owner is part of the state because "my cart" has to be findable again.
- How long does it exist? From the first add until checkout or abandonment. Whether it survives a reload, a closed browser or a login is not a property of the concept; it is a persistence decision made later, and each answer changes where the cart lives.
- Should it survive reload? Usually yes for a store, usually no for a demo. V1 in memory says no; V2 browser storage says yes on one device; V3 server storage says yes everywhere the user is logged in.
- Should it survive login? Only if an anonymous cart and a logged-in cart are merged — a rule that does not exist in V1 and appears as a modification later.
- itemscollection of CartItemkeepThe cart is its items; without them nothing else means anything.
- items[].productIdidkeepThe reference to what is being bought. The catalog owns the product; the cart only points at it.
- items[].quantityinteger > 0keepTwo laptops is one entry with quantity 2, not two entries — the rule "one entry per product" needs a quantity to hold.
- owneruser id or session iddependsSo the cart can be found again by the person it belongs to.
- items[].productNamestringderiveIt would be convenient to render the cart without a catalog lookup.
- items[].pricemoneydependsThe total needs a price per item.
- totalmoneydropEvery screen shows the total.
- currencycodedependsPrices need a currency to be added.
- createdAttimestampdropAbandoned carts might be expired or emailed about.
- update Add item — the updated cart
- delete Remove item — the updated cart
- update Change quantity — the updated cart
- read View items — the list of entries — product id and quantity — for rendering
- domain Calculate total — the sum of price × quantity over the entries
- delete Clear cart — the empty cart
- • Every quantity is greater than zero.
- • One logical entry per product.
- • The total is never negative.
- • An unknown product cannot be added.
- • Quantity cannot exceed available stock — if inventory is enforced here.
How to do it
Most important first.
- Write the concept in one sentence a shopper would agree with, before opening any file (Define the Concept).
- List what it must remember, and challenge every field: do you need the product name in the cart, or can it be loaded from the catalog? (What Must It Remember?).
- List what can happen to it, as verbs. Add, remove, change quantity, view, total, clear — six verbs are the whole cart (What Can Happen to It?).
- Write one before/after example per verb and read the rules off the examples (Examples Before Algorithms, Rules Determine Implementation).
- Pick a representation with the operations in front of you, then implement one operation and test it with the examples (Choosing a Representation, Implement One Operation).
- If a step still feels impossible, make the step smaller until it is something you can do — Make It Smaller Until You Know How to Build It is the rest of this module.
Worked on a concrete problem
The move has to produce something. This is what it produced.
- The sentence: "I need a shopping cart." Meaning: a temporary collection of products the user intends to purchase. Must remember: items — each a productId and a quantity. Challenged and dropped: a stored total (computable from the items), createdAt (no V1 operation reads it), productName (the catalog owns it). Can happen: add, remove, change quantity, view, total, clear. Must always hold: every quantity is greater than zero; one entry per product; an unknown product cannot be added.
- Examples for add: [] + Laptop → [ Laptop × 1 ]; [ Laptop × 1 ] + Laptop → [ Laptop × 2 ], not two entries; [] + Laptop × 0 → rejected, cart unchanged. The middle example produced the rule; the last one produced the validation
if quantity <= 0: reject. - Representation: an array of { productId, quantity }. Finding an existing entry is an O(n) scan, invisible for a cart with a handful of entries; the map with O(1) average lookup is the answer to a larger question. addItem in plain English: check the product exists; check the quantity is positive; look for an existing entry with this product id; if found, increase its quantity; otherwise append. The code is the same six sentences with braces.
- What changed in the hour: nothing about programming ability. "Cart" went from a word to a page of state, operations, rules and examples, and the file that was empty now has one tested function whose every line has a reason.
How you know it worked
What now exists that did not before, and what question you can now ask.
- You can say, without looking at code, what the cart remembers, what can happen to it and what must never be true of it.
- Every operation has at least one concrete before/after example, and one of those examples surprised you into a rule.
- The first implemented operation is small, tested against the examples, and you can explain why each line exists — including which rule it encodes.
- The search or the assistant is now useful in a different way: you ask it about a specific line you wrote, not for the cart.
The questions you can now ask
The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.
- ?What is this thing, in one sentence, before I decide anything about how to store it?
- ?What must it remember — and which of those fields could be derived instead of stored?
- ?What can happen to it, as verbs, and what does each verb read, change and return?
- ?What must never be true of it, and which example would show the rule being broken?
- ?Which single operation, implemented and tested first, would prove I understand the concept?
What can go wrong
- The description becomes the project. Twelve fields, a state diagram, a glossary — and no addItem. The description exists to make one operation implementable; when that operation is obvious, implement it and come back for the next.
- The examples are written and not run. A before/after that stays in a document tests nothing; it becomes a test the moment the operation exists, and until then it is a promise.
- The move is applied to a concept already understood. Someone who has written five carts does not need the hour; they need the one rule that makes this cart different — stock, or several named carts.
- The reflex is condemned rather than reordered. A tutorial's cart is an excellent thing to read *after* you have written your own state and operations, because now you can see where it differs and why.
- The hour produces a page of English and one function; the reflex produces a whole cart. If the tutorial's cart happened to be right for this store, the hour was slower.
- Writing rules down invites disagreement — should removing an absent item be an error or a no-op? — that pasted code silently decided.
- One operation at a time means the badge on the button is not wired up today.
- "So I should never look at existing cart code." Look at it after you have your own state, operations and rules — then the comparison teaches you something. Looking first replaces your understanding with someone else's.
- "The gap was that I don't know TypeScript well enough." The code for addItem uses a find, an if and a push. The gap was that "add" had not been defined precisely enough for any language to express it.
- "This is just design-up-front for a tiny feature." It is one page, written in the language of the person who wanted the cart, and it is the source of the tests. A design document describes structure; this describes behaviour.
Where this applies
Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.
- GENERALMeaning, state, operations, rules and examples before representation applies to any concept — a cart, a rate limiter, a job queue; the sizes change, the order does not.
- TEAM-SPECIFICA solo learner writes the page for themselves; on a team with a domain expert the same questions are asked of the expert, and the page is a conversation rather than a document.
- ILLUSTRATIVEThe store, the empty cart.ts and the hour are invented to show the shape of the move; Laptop and Mouse are the cart record's own examples, not real products.
Where the depth lives
This domain asks the question and hands the answer off by name.
- — The manifesto's "Don't delegate understanding" at /manifesto is this lesson in one sentence: the search and the assistant accelerate the last step; they cannot do the first four for you.