Module 5: Competition And Market

Mini-project: Mercado's complete competitive map

Description

It's time to bring the whole module together into a single artifact: Mercado's competitive map, complete and projected forward. You learned to map the competition without stopping at the obvious rival (L2), to categorize direct, indirect, and substitutes with the same rigor (L3), to give the most underrated competitor —"doing nothing"— a name and a size (L4), to project the map forward instead of treating it as a fixed snapshot (L5), to choose axes that truly discriminate (L6), and to recognize when a map measures the wrong war (L7). In this project you run competitiveMap on Mercado's complete roster —five players, all three categories represented— at two points in time, and close with the recommendation that result demands.

Your deliverable has three parts, and all three are verified with code, not just written up: (1) Mercado's complete roster, categorized by type; (2) today's competitive landscape, verified with competitiveMap; and (3) the same landscape, projected three years out per the technology trend you already saw in lesson 5, showing whether today's open space is still open tomorrow.

Connection to the module. This project doesn't introduce any new concept — it brings together, in a single verified map, everything you built lesson by lesson. It's also the bridge to the rest of the guide: the landscape you build here is the same one module 6 will use to ask how defensible Mercado's open space is against any of these players —moats, not just position—, and the same one module 7 will cross against Mercado's backlog to decide which bets to build first.

An analogy: the command bridge, with the complete navigation chart

The module opened with a captain's radar, sweeping 360 degrees instead of only looking forward. This project is the moment that captain leaves the radar and goes up to the command bridge, where the complete navigation chart is spread out on the table: not just the ships around right now, but the marked routes, the known currents, and a second chart —transparent, laid over the first— showing where those currents are expected to move over the next few years. A captain who only watches the radar navigates the present minute well. A captain who goes up to the bridge with both charts spread out can plot a course that's still good three years from now, not just today.

This mini-project is exactly that command table: everything the module taught, in one place, ready for anyone on the Mercado team —not just whoever wrote it— to look at and answer, in minutes, the question that opens any strategy conversation: where are we standing, and for how much longer is it going to keep being a good place?

The reference solution, verified

Part 1 — Mercado's complete roster, categorized

This is the complete roster you built, piece by piece, throughout the module: two direct competitors (L2), two indirect ones and a substitute (L3), with the substitute identified as the player with the highest attentionShare of all (L4).

const rosterToday = [
  { name: 'MegaStoreGenerico', type: 'direct', scores: { breadth: 9, curation: 2 } },
  { name: 'SuperTiendaExpress', type: 'direct', scores: { breadth: 6, curation: 3 } },
  { name: 'TiendasLocalesOnline', type: 'indirect', scores: { breadth: 3, curation: 4 } },
  { name: 'NicheHandmadeMarketplace', type: 'indirect', scores: { breadth: 3, curation: 8 } },
  { name: 'JustSearchOnGoogle', type: 'substitute', scores: { breadth: 10, curation: 1 } },
];

Check the roster against the module's criteria before continuing: all three categories are represented (L3), it didn't stop at the most famous direct competitor (L2), and it explicitly includes the "doing nothing" substitute instead of dismissing it for lacking the shape of a recognizable company (L4).

Part 2 — Today's landscape and the three-year projection, run in Node

We run competitiveMap on the complete roster twice: with today's data, and with lesson 5's projection —AI shopping assistants raising JustSearchOnGoogle's curation from 1 to 7—, always using Mercado's strategy's correct axes (L6), not those of the war it already decided not to fight (L7).

// Pedagogical model: places each player on a 2x2 map along two
// STRATEGIC axes (not objective market metrics) and flags whether
// "our" quadrant is open -- the space where Mercado can win without
// running head-on into another player.
function competitiveMap(us, players, axes) {
  const [xAxis, yAxis] = axes;
  const place = (player) => {
    const xSide = player.scores[xAxis.key] >= xAxis.midpoint ? xAxis.high : xAxis.low;
    const ySide = player.scores[yAxis.key] >= yAxis.midpoint ? yAxis.high : yAxis.low;
    return `${ySide} / ${xSide}`;
  };
  const usQuadrant = place(us);
  const placed = players.map((p) => ({
    name: p.name,
    type: p.type,
    quadrant: place(p),
    sharesQuadrantWithUs: place(p) === usQuadrant,
  }));
  const openSpace = !placed.some((p) => p.sharesQuadrantWithUs);
  return { us: { name: us.name, quadrant: usQuadrant }, players: placed, openSpace };
}

const axesDiscovery = [
  { key: 'breadth', label: 'catalog breadth', low: 'niche', high: 'broad', midpoint: 5 },
  { key: 'curation', label: 'curation depth', low: 'raw-search', high: 'curated', midpoint: 5 },
];
const us = { name: 'Mercado', scores: { breadth: 8, curation: 8 } };

const rosterToday = [
  { name: 'MegaStoreGenerico', type: 'direct', scores: { breadth: 9, curation: 2 } },
  { name: 'SuperTiendaExpress', type: 'direct', scores: { breadth: 6, curation: 3 } },
  { name: 'TiendasLocalesOnline', type: 'indirect', scores: { breadth: 3, curation: 4 } },
  { name: 'NicheHandmadeMarketplace', type: 'indirect', scores: { breadth: 3, curation: 8 } },
  { name: 'JustSearchOnGoogle', type: 'substitute', scores: { breadth: 10, curation: 1 } },
];
const rosterIn3Years = rosterToday.map((p) =>
  p.name === 'JustSearchOnGoogle' ? { ...p, scores: { ...p.scores, curation: 7 } } : p
);

const today = competitiveMap(us, rosterToday, axesDiscovery);
const in3Years = competitiveMap(us, rosterIn3Years, axesDiscovery);

console.log('=== PART 1: Mercado\'s competitive landscape, TODAY ===\n');
console.table(today.players);
console.log(`openSpace today: ${today.openSpace}`);

console.log('\n=== PART 2: the same landscape, projected 3 years out ===\n');
console.table(in3Years.players);
console.log(`openSpace in 3 years: ${in3Years.openSpace}`);

const directCount = rosterToday.filter((p) => p.type === 'direct').length;
const indirectCount = rosterToday.filter((p) => p.type === 'indirect').length;
const substituteCount = rosterToday.filter((p) => p.type === 'substitute').length;
console.log(`\nRoster summary: ${directCount} direct, ${indirectCount} indirect, ${substituteCount} substitute(s).`);

What to expect. Running the file with Node produces exactly this output:

=== PART 1: Mercado's competitive landscape, TODAY ===

┌─────────┬────────────────────────────┬──────────────┬──────────────────────┬──────────────────────┐
│ (index) │            name            │     type     │       quadrant       │ sharesQuadrantWithUs │
├─────────┼────────────────────────────┼──────────────┼──────────────────────┼──────────────────────┤
│    0    │    'MegaStoreGenerico'     │   'direct'   │ 'raw-search / broad' │        false         │
│    1    │    'SuperTiendaExpress'    │   'direct'   │ 'raw-search / broad' │        false         │
│    2    │   'TiendasLocalesOnline'   │  'indirect'  │ 'raw-search / niche' │        false         │
│    3    │ 'NicheHandmadeMarketplace' │  'indirect'  │  'curated / niche'   │        false         │
│    4    │    'JustSearchOnGoogle'    │ 'substitute' │ 'raw-search / broad' │        false         │
└─────────┴────────────────────────────┴──────────────┴──────────────────────┴──────────────────────┘
openSpace today: true

=== PART 2: the same landscape, projected 3 years out ===

┌─────────┬────────────────────────────┬──────────────┬──────────────────────┬──────────────────────┐
│ (index) │            name            │     type     │       quadrant       │ sharesQuadrantWithUs │
├─────────┼────────────────────────────┼──────────────┼──────────────────────┼──────────────────────┤
│    0    │    'MegaStoreGenerico'     │   'direct'   │ 'raw-search / broad' │        false         │
│    1    │    'SuperTiendaExpress'    │   'direct'   │ 'raw-search / broad' │        false         │
│    2    │   'TiendasLocalesOnline'   │  'indirect'  │ 'raw-search / niche' │        false         │
│    3    │ 'NicheHandmadeMarketplace' │  'indirect'  │  'curated / niche'   │        false         │
│    4    │    'JustSearchOnGoogle'    │ 'substitute' │  'curated / broad'   │         true         │
└─────────┴────────────────────────────┴──────────────┴──────────────────────┴──────────────────────┘
openSpace in 3 years: false

Roster summary: 2 direct, 2 indirect, 1 substitute(s).

The result: today's landscape is open; the one three years from now is not. Of the five players on the complete roster, none occupies Mercado's quadrant today — not the two direct ones, not the two indirect ones, not the substitute. It's the numerical confirmation of everything the module built: a disciplined mapping (L2, L3), that didn't ignore the most underrated competitor (L4), on the correct axes of Mercado's strategy (L6, L7), shows a real space of its own, not an illusion.

But the second table is the one that turns this map into more than a reassuring snapshot. With a single change —JustSearchOnGoogle's curation going from 1 to 7, the same already-visible technology trend from lesson 5—, that same player moves into Mercado's quadrant, and openSpace drops to false. No new competitor entered the roster: the terrain moved under the player who was already there, exactly as lesson 5 warned. The recommendation that follows from the two tables together isn't "we're fine" or "we're in danger" — it's more precise than either one: the space is open today, and the clock to defend it before it closes has already started running. How defensible that space is once someone actually tries to occupy it —not just whether it's empty today— is exactly the question of module 6, moats, which picks up right where this project leaves off.

Common mistakes

Delivering only today's map and calling it "the complete landscape." What happens: the team puts together a careful competitiveMap, with the complete roster and the correct axes, presents it as the finished competitive analysis, and never runs the forward projection lesson 5 taught. Why it happens: today's map feels complete because it precisely answers the question "where are we standing right now?" — and that sense of completeness hides the fact that it left an equally important question unanswered: for how long. How to spot it: if your competitive analysis deliverable doesn't include any projected version of the map, with at least one reasoned trend, you're missing half of this module's work. How to fix it: never close out a competitive map without running at least one projection scenario, anchored in a real trend, as you did in Part 2 of this project.

Presenting openSpace: false in the projection as a failure of the project. What happens: seeing the space close in the three-year projection, the team treats the result as if the project had "failed" to find Mercado a good position, instead of as the most valuable finding of the entire exercise. Why it happens: there's an unspoken expectation that a good competitive analysis always ends in good news — and a result that anticipates a problem feels like a poorly done analysis, instead of a well-done analysis that found a real problem. How to spot it: if the team's reaction to openSpace: false in the projection is to discard the model instead of planning a response, they're confusing the quality of the map with the comfort of its result. How to fix it: remember lesson 5's exact point — a projection that anticipates a problem with plenty of runway to spare is the most valuable version of competitive analysis, not the least.

Treating the competitive map as the final decision, without connecting it to moats or the roadmap. What happens: the team closes the project with the conclusion "we have an open space today, which closes in three years" and stops there, without translating that finding into any concrete action about what to build or defend. Why it happens: the map answers "where" very clearly, but doesn't answer "what to do about it" — and without that next step, the analysis stays pure diagnosis, disconnected from real decisions. How to spot it: if nobody on the team can name a single concrete action that follows from this project's result, the map stayed an academic exercise. How to fix it: use this project's result as the input to module 6 —what makes Mercado's curation hard to copy, not just being there first?— and to module 7 —which backlog bets defend exactly that space before it closes?

Exercises

Exercise 1 — Add a sixth player to the roster. A new competitor enters the market: a social recommendation app where friends recommend products to each other, with no direct-sale function at all. Write its data object (name, type, scores.breadth, scores.curation) following the roster pattern, add it to rosterToday, and predict which quadrant it would fall into and whether it shares a quadrant with Mercado today.

See solution

A reasonable version:

{ name: 'FriendRecommendationApp', type: 'indirect', scores: { breadth: 4, curation: 7 } }

It's indirect because it solves the same discovery job as Mercado, without being a marketplace. With breadth: 4 (< 5 → 'niche', an implicit catalog limited to what friends recommend) and curation: 7 (≥ 5 → 'curated', social recommendations are a high form of curation), it would land in the 'curated / niche' quadrant — the same as NicheHandmadeMarketplace, not Mercado's. sharesQuadrantWithUs would return false, and openSpace would stay true: one more competitor on the radar, but still not invading Mercado's open space.

Exercise 2 — Combine the two threats from lessons 5 and 7. Run the model projecting at the same time the substitute's advance (JustSearchOnGoogle with curation: 7, lesson 5) and MegaStoreGenerico investing in curation (curation: 6, lesson 5's exercise 2). What happens to openSpace, and how many players share Mercado's quadrant in that combined scenario?

See solution

With both changes applied (JustSearchOnGoogle: curation 7 and MegaStoreGenerico: curation 6, both ≥ 5 → 'curated', and both with breadth ≥ 5 → 'broad'), both would land in the 'curated / broad' quadrant — the same as Mercado. openSpace would stay false, but now with two players sharing the quadrant instead of one: a direct competitor and a substitute, invading the same ground through different paths (deliberate investment for one, an external technology trend for the other). This combined scenario is the most severe of any you saw in the module, and it's exactly the kind of question a well-built competitive map should be able to answer before both threats become real at the same time.

Exercise 3 — Present the complete map to Mercado's founding team. Write, in a paragraph, how you'd present this project's two tables —today and in three years— to Mercado's founding team, including what concrete recommendation you'd make with the time remaining before the space closes.

See solution

A sample answer: "We mapped the complete landscape: two direct competitors, two indirect ones, and the biggest substitute of all —simply searching on Google—, all five on the axes that reflect our real strategy, not generic retail's. The good news: today, none of the five occupies our ground — we have a space of our own, real and verified, not just a feeling. The news that demands action: that space isn't guaranteed. If AI shopping assistants keep following the trajectory that's already visible today, in three years the substitute capturing the most attention of the entire landscape is going to be standing exactly where we are. We're not proposing panic or a strategy change — we're proposing using these three years to deepen what sets us apart from everyone today: our curation needs to be good enough, fast enough, that copying it isn't trivial even for an AI assistant. That's exactly the question for the next module: what makes this advantage hard to copy, not just that nobody has copied it yet."

Summary and next step

In this mini-project you brought the whole module together into a single map: Mercado's roster with all three competition categories represented, today's landscape verified with competitiveMap on the strategy's correct axes (open space, openSpace: true), and the three-year projection showing that same space closing as the roster's biggest substitute absorbs the technology trend already visible today (openSpace: false). With this you close module 5.

You now have, for any product you analyze in your own work, a complete two-question instrument: "where are we standing today, against every player —including the one with no logo?" and "for how much longer is it going to keep being a good place?" — and you know the second question is the one almost no team asks in time.

Where you go next. You now know where Mercado's open space is, and you know that space has an expiration date if nobody defends it. The next question is exactly that: what makes that space hard to occupy, even for someone who seriously tries? That's the question of module 6 (module-06-moats-and-defensibility): moats — network effects, switching costs, scale, data, brand — versus a feature that can be copied in a weekend.

Resources

  • Michael Porter, "The Five Competitive Forces That Shape Strategy" — hbr.org/2008/01/the-five-competitive-forces-that-shape-strategy. The module's complete framework —direct rivals, substitutes, and the forces that move them— read again now that you have Mercado's complete case as your own example. In English.
  • Clayton Christensen, Scott Cook, and Taddy Hall, "Marketing Malpractice: The Cause and the Cure" — hbr.org/2005/12/marketing-malpractice-the-cause-and-the-cure. The milkshake study, worth rereading now that Mercado's substitute (JustSearchOnGoogle) has been identified, quantified, and projected forward. In English.
  • Clayton Christensen, Michael Raynor, and Rory McDonald, "What Is Disruptive Innovation?" — hbr.org/2015/12/what-is-disruptive-innovation. The framework behind this project's three-year projection: a player that looks marginal today can displace the entire map without anyone attacking it directly. In English.
  • Jeff Jordan (a16z), "So You Want to Compete Against Amazon?" — a16z.com/so-you-want-to-compete-against-amazon. The natural bridge to module 6: Jordan doesn't just explain how to position against a giant, but what makes that position sustainable over time, not just a momentary advantage. In English.