Full stack and the learning science of crossing fields
I really have noticed lately that full-stack development does let you see more, especially the traps and landmines that are different on the frontend and the backend. Sometimes a frontend bug is purely the backend taking the fall, like when something errors out and all it says is that it errored, with nothing at all about why, and frontend debugging can’t move an inch. Or the other way around, the frontend throws an error, the backend has no idea what’s going on, but it “feels” like a backend problem, and you spend ages looking before finding out the direction was wrong. You only know these things if you’ve spent time on both sides, and the domain knowledge in them takes actually doing the work to understand. Read about it without ever going through that pain yourself and there’s always a layer of gauze in between. That goes double when I’m the one paying a real cost to weigh up both ends of development. Only after you’ve been through that pain do you deliberately optimize while you develop, and spend the extra energy on problems that might not be “yours”.
Passing the buck isn’t a good habit. Maybe the developer himself means no harm, but laziness makes you skip things that should have been there without noticing, and then whoever works with you pays for it. Holding that laziness back usually takes either a process that mandates certain development rules, or self-discipline, and the second one is the hard one. That’s the biggest bonus of getting burned. It makes you self-disciplined without thinking about it, not because I want to do it this way, but because not doing it will genuinely make me miserable. Only someone who has debugged to exhaustion knows the feeling of wanting to curse out eighteen generations of the frontend/backend guy’s ancestors: just add a log, it’s a few lines of code, why won’t you put it in for me. Both sides think this, and the result is each side making it harder on the other. Some of it may come down to company process, of course, but from an individual’s angle, internalizing the standard practice beyond what the process demands is one of the ways technical ability shows.
Setting flexibility aside, the other thing I’d point to is insight, the way knowledge reappears across fields. Right now I use strongly typed languages on both ends, and the TS plus C# combination has shown me a lot of shared design principles. DI, for instance, where the way TS does it is almost identical to C#, which also means I can use the pattern on both ends. Or generics, which are consistent for any strongly typed language. Some people might feel this isn’t really about full-stack work and is more of a language thing. But when the languages and frameworks on the two ends are all different, full-stack work is exactly what gave me an environment for understanding across languages. Otherwise anyone sitting in his comfort zone by default probably wouldn’t switch deeply between several languages every day. Only the job forces me to finish a TS frontend and then go look at a C# backend. On my personal projects I run TS end to end, React on the front and NestJS on the back. Who’d swap in another language and make trouble for himself.
Reappearance across fields sometimes gives a distinct feeling of sudden insight, and I enjoy it quite a bit. We often say “the mountain is no longer the mountain”, but how you actually experience that is treated as something you can’t seek out, only stumble into. I think that feeling is entirely something you can produce on purpose, and the key is deliberately trying things and crossing fields, looking at the new field through the content of the one you already have, and hunting for knowledge that transfers. From the learning science angle, this is the process of rebuilding the brain’s neural connections and building your own knowledge network. Unlike a textbook, most real knowledge is never linear, cleanly structured, or neatly systematized (math might be the exception), and it tends to jump back and forth instead. Textbook knowledge might go A B C D E, but in practice it can perfectly well go A to C to E and only come back to B at the end. Because in engineering we only go and consider what a thing actually is after we’ve run into a problem. Application runs ahead of theory, and the problems in application become the motive and the starting point for me to touch theory. And the purpose of my ending up with the theory is to feed it back into my engineering, not to get through an exam like at school.
Another concept is tacit knowledge, or implicit knowledge. It’s exactly the kind of knowledge that’s hard to pin down and lives mostly in a person’s feel for things. Hard to put into writing, graspable only through an engineer’s experience or intuition. Knowledge like that, to me, is the knowledge network itself showing through, a form of knowledge that exists as structure rather than as logic. Tacit knowledge is a grasp of the structure of knowledge. That structure is sometimes hard to say out loud, but it really is stored in my head. When it’s needed, starting from one entry point (a signal), I light up the whole network bit by bit, and it pushes that feeling out to the front. And this network has to be acquired through constant interaction and through getting burned in practice. Beyond that, the other effective way to build the network is transferring knowledge across fields.
Through transfer, knowledge builds connections in a different, new field (physiologically that could be a new neural arrangement), and out of it emerges new content you hadn’t noticed before. When two previously separated bodies of knowledge collide and interact, new knowledge gets generated in between, and not all of it can be put into words; some of it does exist as “feel”.
At the same time, through all that transferring my own meta-ability for “how to learn” gets trained. Each transfer makes me a bit more used to crossing fields, and my thinking gets less confined by the knowledge structures and systems I already have. Each transfer, what I learn might collide with some part of my existing structure I didn’t see coming, and that keeps producing new things I couldn’t have known about myself. Only crossing fields gives you that frequent experience of “the mountain is no longer the mountain”, and it’s hard to get from soaking in one field for years.
The usual objection to crossing fields is the trade-off between depth and breadth. But I don’t think the two are strictly in conflict, since depth and breadth can feed each other. Energy is limited, so of course I can’t cover both. But having extremely broad knowledge trains another ability in me, which is the ability to learn. And frontend and backend both belong to one field anyway, computer science. As subfields they really are separate, but they both lean on the knowledge themes of computer science, the larger field. So the structure of the knowledge here shows up as big things nesting smaller ones and smaller ones nesting smaller still. Frontend and backend, at the level of the knowledge itself, share quite a lot. And that shared part also speeds up how fast I learn the knowledge of whatever specific field I want to learn.
Take the frontend. Some people think depth of knowledge shows up as using frameworks and tools, or as frontend optimization, the standard solutions for specific operations in practice. But hard frontend work obviously isn’t only slicing layouts. Performance tuning, network protocols, even some of the backend’s high concurrency and data structures and algorithms; those aren’t all of it, but each of them is part of what makes up depth on the frontend too. Everyone says the frontend changes every year, and even so some knowledge survives, like design principles shared across frameworks, and once I’ve digested those I can get down into depth fast. When I switch frameworks I’ve in fact already done one “cross-field” knowledge transfer inside the frontend. The jump is just small enough that it’s sometimes hard to notice.
But if I already have experience crossing fields regularly, I’m bound to notice where the common ground is very fast. The first-principles things tend to be the common things. If crossing fields over a long time has trained my insight into first principles and my ability to learn, then how fast I pick up so-called “deep” knowledge will also be far ahead of someone who’s soaked in a single field for years. A frontend engineer of many years might have dug extremely deep into some specific specialty, and I do think people like that are worth respecting and are essential. But for most of us, I don’t need to know what some deep detail of the V8 framework is, what I need is fast engineering ability, depth that’s usable in engineering, which is what companies need. So if I have that fast-learning ability, the efficiency with which I reach depth also lets me switch states when I need to, from breadth straight into “usable depth”. So rather than worrying that “breadth hurts depth”, it’s better to flip the view and think about this: do I really need that much depth?
The people who say that line are usually looking at experts, not at usable engineers with depth. By volume, companies need the second kind more. Unless it’s genuinely an industry that demands expert knowledge, or you’ve set your heart on a role with an explicit requirement for expert-level depth, breadth is always a plus for a person, and not the thing the world sneers at as “knowing many things and mastering none”. Because they only saw the “many” and skipped the more essential layer, which is how did he get to many? What separates people is learning ability. Someone with “many” must have his own fast-learning methodology, or he couldn’t have picked up that much. And someone who can learn fast, who has the meta-learning technique, is better placed to switch into a state of “depth” when he needs to, and it can even be depth in several fields. The reason he can’t reach expert level is that energy and time are limited. But if he decides partway to switch roads or go deep in one field, the speed and efficiency with which he catches up and becomes an expert will beat the people who’ve only ever been in a single field. At least here, “many” is never automatically the “weakness” it gets mocked as. How you got to many is what counts.
If I have the ability to become that kind of person fast, I naturally have more opportunities. Crossing fields being mocked the way it is, when it’s an advantage, wipes out an ability that can actually create value. An effective tool being “considered” ineffective is, from an engineering standpoint, plain waste. And the reason it gets considered that way, I think, is precisely that most of the people making that judgment lack cross-field knowledge. I’m arguing this from the angle of learning science, for example, and if someone had never touched learning science he obviously couldn’t see that angle. Which at least shows the side effect of widening your knowledge. Sometimes the angle itself is what matters.
Translation note. I wrote this in Chinese. This English version is an LLM translation, so the wording is not mine even though the thinking is. Original: 全端與跨領域的學習科學.