Si tu producto no habla el idioma de tu usuario, está condenado a fracasar
Tu usuario no tiene “Player”. No tiene “Actor”. No tiene “PC Sheet”. Tiene a Lyra y la partida del martes.
Cada vez que tu producto le pide elegir entre esos tres nombres para el mismo concepto, le está obligando a traducir. A hacer, en su cabeza, el trabajo que tu backend no hizo.
Es la consecuencia visible de algo que pasa antes, dentro: tu equipo lleva meses manteniendo un mapping entre cinco dominios distintos. Y eso no escala.
El ejemplo
Imagina Characters Vault — un gestor de fichas para juegos de rol de mesa — con cinco servicios independientes. Players publica los personajes del jugador. NPCs, los del director. Campaigns sabe quién juega qué. Templates guarda los arquetipos clonables. Y el Frontend, que tiene que fingir que nada de esto existe.
Cada servicio habla su propio dialecto del mismo concepto. Players los llama playerCharacter, con level calculado desde xp. NPCs, nonPlayerCharacter, con cr libre y displayName en vez de name. Campaigns ni siquiera los almacena: guarda participants con un characterRef opaco. Templates los llama characterBlueprints, sin portada — solo iconKey.
Cinco diccionarios internamente coherentes. Lo que no comparten es la palabra.
Cuando los mappings no escalan
Tres dialectos son cuatro ramas en cada lista. Cinco, una matriz de tests que se multiplica. Seis es ya un proyecto a tiempo parcial.
Cada equipo upstream va a su ritmo. Players renombra un campo el martes y tu frontend revienta el miércoles. Casi nadie tiene contract tests entre servicios. Templates deprecia iconKey y nadie sabe quién lo usa. La persona nueva no aprende un dominio: aprende cinco.
Lo que parecía un atajo se vuelve deuda compuesta. “Ya lo armonizamos luego”. El sprint de “luego” nunca llega. La velocidad del equipo decrece — lo he visto en demasiados equipos.
Y la misma divergencia se filtra a la pantalla. El NPC muestra “CR 7”, el PJ encima “Nivel 7”: significan cosas distintas. El filtro “nivel ≥ 5” oculta al NPC favorito del usuario y nadie sabe por qué.
Tres filas seguidas: Player, Actor, PC Sheet. El usuario entrecierra los ojos y construye una teoría privada de qué significan. No significan nada — son tres equipos. La unión la está haciendo él, en su cabeza, cuando la debería haber hecho tu backend.
La línea
La salida es aburrida: parar. Sentarte con producto y diseño, escribir el glosario que tu usuario ya tiene en la cabeza, y trazar la línea exactamente donde tiene que estar. Un BFF que normalice los cinco dialectos en uno solo: el del usuario.
(Una salvedad: si los dialectos reflejan distinciones reales del dominio, no las aplastes — dales contexto. Si tu equipo todavía no se ahoga, no construyas el bote.)
No has eliminado los mappings — los has centralizado. Lo que era N×M se vuelve N+M: todos los costes concentrados en un único sitio en lugar de cinco. Cuando mañana añadas la app móvil, lee del mismo sitio.
La factura de no hacerlo se paga en otra moneda: tickets que son problemas de vocabulario, onboardings que se atascan en “¿qué diferencia hay entre un Player y un PC Sheet?”, y abandono silencioso de gente que solo dice “el producto se siente desordenado”.
Tienen razón. Solo que no saben ponerle nombre.
Notas para el lector técnico:
— Alternativas razonables: GraphQL federado, un servicio de composición, contratos OpenAPI canónicos. La elección depende de quién manda en los schemas, cuántos clientes tienes y qué latencia te puedes permitir.
— Si móvil y web divergen, acabas con varios BFFs — uno por cliente, el patrón original de SoundCloud.
— El camino de escritura es más feo que el de lectura: consistencia, sagas, idempotencia, fallos parciales. No hay atajo.
— Las dos preguntas que hunden estas iniciativas en empresas reales: quién mantiene el glosario, y quién es dueño del BFF.
If your product doesn't speak your user's language, it's doomed to fail
Your user doesn’t have “Player”. They don’t have “Actor”. They don’t have “PC Sheet”. They have Lyra and the Tuesday game.
Every time your product makes them choose between those three names for the same concept, it’s making them translate. Doing, in their head, the join your backend didn’t.
It’s the visible consequence of something that’s been happening earlier, inside: your team has spent months maintaining a mapping across five different domains. And that doesn’t scale.
The example
Picture Characters Vault — a cloud-based character sheet manager for tabletop RPGs — as five independent services. Players publishes the player’s characters. NPCs, the GM’s. Campaigns owns who plays what. Templates holds the cloneable archetypes. And the Frontend, which has to pretend none of this exists.
Each service speaks its own dialect for the same underlying thing. Players calls them playerCharacter, with numeric level derived from xp. NPCs, nonPlayerCharacter, with free-form cr and displayName instead of name. Campaigns doesn’t even store characters: it stores participants with an opaque characterRef. Templates calls them characterBlueprints, no portrait — just an iconKey.
Five internally coherent dictionaries. What they don’t share is the word.
When mappings stop scaling
Three dialects in code mean four branches in every list. Five mean a test matrix that multiplies. Six is a part-time project of its own.
Every upstream team moves on its own clock. Players renames a field on Tuesday and your frontend breaks on Wednesday. Almost nobody has contract tests between services. Templates deprecates iconKey and nobody knows who’s using it. The new engineer doesn’t learn one domain: they learn five.
What looked like a shortcut turns into compounding debt. “We’ll harmonize later”. The “later” sprint never comes. Team velocity decays — I’ve seen it in too many teams.
And the same divergence leaks onto the screen. The NPC reads “CR 7”, the PC right above it reads “Level 7”: they mean entirely different things. The “level ≥ 5” filter hides the user’s favorite NPC and nobody can explain why.
Three rows in a row: Player, Actor, PC Sheet. The user squints and starts building a private theory of what the differences mean. They don’t mean anything — there are three teams. The user is doing the join, in their head, that your backend should have done.
The line
The fix is boring: stop. Sit down with product and design, write the glossary your user already speaks, and draw the line exactly where it belongs. A BFF that normalizes the five dialects into one: the user’s.
(One caveat: if the dialects reflect real domain distinctions, don’t flatten them — give them context. If your team isn’t drowning yet, don’t build the boat.)
You haven’t eliminated the mappings — you’ve centralized them. What was N×M becomes N+M: every cost concentrated in one place instead of five. When you add a mobile app next month, it reads from the same place.
The bill for not doing it gets paid in another currency: support tickets that are really vocabulary mismatches, onboardings that stall on “wait, what’s the difference between a Player and a PC Sheet?”, and churn from users who can only say “the product feels messy”.
They’re right. They just can’t name it.
Notes for the technical reader:
— Reasonable alternatives: GraphQL federation, a composition service, canonical OpenAPI contracts. Which one you pick depends on who owns the schemas, how many clients you have, and what latency budget you can afford.
— If mobile and web diverge, you end up with multiple BFFs — one per client, the original SoundCloud pattern.
— The write path is uglier than the read path: consistency, sagas, idempotency, partial failures. There’s no shortcut.
— The two questions that sink these initiatives in real companies: who owns the glossary, and who owns the BFF.