The most important skills I’ve developed over the past 5-10 years revolve around computing, writing, and design. Together they’ve helped me become a well-rounded digital creator and are really useful for starting your own projects– specifically 0 → 1 efforts where you need to get something off the ground quickly. You don’t have to be an expert in each, but they all complement each other and having proficiency in each can unlock lots of new things you can make.
This is intended to mostly be a self reflection on what I think about and use a lot in my practice. It’s also meant to be read by people across different skill / knowledge levels, so I tend towards over-explaining concepts that might be trivial to some of you. I also sometimes underexplain things so if something is confusing or you want more context, DM or email me. This is also not some sequence of skills you should develop since lots of these skills can be developed in parallel and some you might already have.
Build for the web
Lots of people have talked about this in the past, but the web has some amazing advantages for launching new projects, which include (but aren’t limited to):
- Super fast distribution and updates
- Cross platform
- Huge tooling ecosystems
- Enormous, worldwide community
If you’re into games, awesome! If you’re into mobile or native development, that’s cool too. There are lots of platform-specific toolkits and environments to make those. There’s also a lot of effort in creating cross platform tools and community-driven projects for both domains (like Unity and Flutter). They all have their advantages, but to me, nothing beats the portability and speed of launching new websites and using web tech to get ideas out the door.
I know non-native code has been getting a lot of heat lately, but using web tech for 80-90% of my projects has a lot of skill transfer effects. Since I’m using similar tools for lots of different projects, I can still refine my core skillset no matter what I’m making. If I’m making a drawing tool concept, a game, or a text editor— I’ll can still probably build all three with React. Of course there are specific libraries or APIs I might need to learn to make each kind of project, but there’s enough in common between all the projects that I can focus on the new content instead of yakshaving and deliberating over unnecessary details.
There are also market pressures that imply focusing on web will have long term payoff, like the rise of wasm, new browsers, and collaborative apps becoming the norm.
So, what does this mean practically?
Learn basic HTML and CSS. Not only are they low floor (easy to approach) but they also have an extremely high ceiling (you can become an expert and make really sophisticated stuff). Markup and styling languages are still at the core of digital tools, regardless of specific format or language (HTML, SwiftUI, etc).
D3.jsfor data visualization. But spinning together a simple site, or manipulating SVG, using CSS animations, etc. can all be tinkered with without any special tooling and are rendered by your browser by default. That being said:
Choose one modern UI library to get good at. React, Vue, and Svelte are all good choices. I’d also get comfortable with TypeScript if you can, once you’re past the basics.
Databases, realtime apps, etc anything backend-related I’m not really including here because tools for this stuff change all the time and are honestly secondary to the basics around frontend programming and getting simple static websites up at first. That being said, basic data modeling, interacting with REST and GraphQL APIs, understanding websockets and webhooks are all paramount if you’re going to get deeper into web dev.
As a shameless plug, I’d also say make a Replit account, check out Vercel, get acquainted with GitHub and git, or just check out MIT’s missing semester course. There are a bunch of other web-related things I could say here (like understanding HTTP, how to build and design APIs, etc) but I’m leaving it at skills that affect my day to day life the most.
Core computing concepts
Some of this is implied in
build for the web, but I’m talking about some core operating system concepts, mental models, data structures, and algorithms.
Primitives and abstractions
A lot of computing is about understanding systems, and specifically their primitives and abstractions. All systems are created with simple primitives, or building blocks, and basic abstractions, or general ways of assembling those building blocks that can also be used to build other things (I am oversimplifying here)
Good abstractions help us do things like:
- pay attention to the important parts of a system while ignoring their inner details
- make it easier to quickly build more complex things
- make it easier for more people to contribute to projects without knowing how every part of it works
With Legos, primitives are individual bricks, and you combine bricks together to form doors, houses, axels, cars, and other patterns that are reused across different Lego sets. So a lego set is an abstraction on top of individual lego bricks. We see these kinds of patterns everywhere, and it’s really useful to look at anything (a city, an app, an argument) and break it down into its core components and figure out how they interact with each other.
Domain : Primitives : Abstractions
Lego : Bricks : Buildings
Scratch : Blocks : Games
Photoshop : Layers : Designs
Music : Notes : Chords
Physics : Atoms : Molecules
School : Classes : Degrees
Language : Words : Sentences
Programming : Integers : Functions
Getting comfortable with identifying examples of primitives and abstractions in the real world helps you build intuition for how to build new ones yourself. In the software world, creating good abstractions is the foundational skill behind great API and user interface design.
Functions and input/output
A function is basically a machine that takes some kind of input, does something with it, and produces an output. Let’s take a physical machine for example: a blender takes in fruits and ice as input, chops them all up, and outputs a smoothie when it’s done.
Blend is the function that takes
fruits in as input. This all ultimately produces a
smoothie. So you’d say that a smoothie is a function of fruit.
Now take an image classifier, e.g. an app that tells you if an animal is a dog or not. Here, the input is the animal picture, the function is the app that evaluates whether it’s a dog or not, and the output is the result: yes or no.
In computing these concepts of feeding data in one end, processing it, and then using that output in more processes are ubiquitous. Some of the biggest examples are file input/output, unix pipes, the client/server model, REPLs, and even just chatbots and google search. Everyone is familiar with the concept of a little textbox where you type something, press enter, and get a list of results back. The browser itself is like this when you enter URLs, too, except the result could be any web page. All fancy ML tools you see today that do “media translation” (text-to-[image, video]) are ultimately functions at the end of the day (very complex ones).
Basically, the more you can figure out how to model processes as functions, the easier it is to model how to achieve a goal by transforming some input into a desired output.
Other topics and brainworms
There are lots of concepts that kinda always pop up in my work from time to time, so here’s a non exhaustive list of other things I haven’t mentioned (that are also not necessarily core and maybe slightly more advanced):
- Cellular automata
- Parsers and interpreters
- Type systems
- Depth-first search, breadth-first search, general search strategies
- Imperative vs declarative programming
- Graphs, trees
- State machines
- Sequence prediction: markov chains, RNNs, transformers
- Entity relationship models, figuring out 1:1, 1:many, many:many relationships in systems
- Shaders and realtime graphics
- GPGPU programming (general purpose GPU)
Basic graphic, visual, and information design
Not everybody has to be an expert at making visually stunning UIs or magazine covers. But it’s really important to have basic grasp on (among other things):
- Information hierarchy, so you can organize information in an easily digestible way
- Layout, so you can visualize your information hierarchy properly
- Color, so you can understand how to direct visual attention on print or screens and get familiar with web accessibility standards
- Typography, so you can understand how to choose different typefaces, their impact on reading, and their relationship to color and layout
A significant amount of modern UI design is based on solid graphic and information design. Lots of these skills also transfer over to writing, and specifically formatting. Knowing how to split up paragraphs, adding proper breaks in the flow of your writing, and varying your sentence structure are all core parts of good writing and are a form of information deisgn.
Drawing, diagramming, and sketching are also all equally important. Being able to express yourself visually is a table-stakes skill for designers. But making easy-to-understand diagrams, graphs, and maps is also extremely useful for any field. The interactivity component of digital tools is another added layer of complexity on top of this, but the foundations will always be important and salient. There are multiple billion dollar businesses built on top of making easy-to-use visualization, diagramming, and presentation tools. Powerpoint and Keynote did this for general presentations, BioRender did this for lots of scientific diagrams, and FigJam for collaborative brainstorming.
Not everything can be explained thoroughly purely through writing. If you’re a statistician or mathematician, communicating visually can be essential for expressing complex graphical concepts. If you’re a writer, creating flow charts or outlines of your story can help reveal plot holes and help you organize your thoughts.
Writing as a tool
I’m not going to preach that “writing is important” since that’s been done a million times by other people who can write much better than me. But I’ll still insist that writing should be one of your primary tools to prototype, validate, and flesh out ideas.
Whether you’re pitching a research idea, describing some user interaction, critiquing some feature, or trying to explain a math concept, being able to write and speak simply is probably the most important and universally transferrable skill you can develop. I know this sounds obvious, but the point is that people completely overlook basic communication skills as the foundation of being a great designer and doing great creative work.
Lots of features I design start off as docs. Or even conversations! Sometimes I just explain ideas with voice notes and then formalize them later with sketches. I’ll explain user flows using arrows, describing how events flow from one event
-> to the other
-> and back.
Or, I’ll often use bracket notation to organize lists, just like I do in code, so that I can easily distinguish
[groups, of, items]. Even figuring out how to properly structure good lists is a kind of information design, and is really useful for all kinds of communciation, like:
- writing approachable emails
- listing out steps (like directions to a place, or a recipe)
- explaining how lists work
Not all design work is done in code, prototyping tools, or sketches. Likewise, not all engineering work is done in code or technical diagrams. Natural language, text, and conversations should be some of your primary mediums for creative work. My best designing actually happens when I’m just talking to people— talking through the primitives of a system, use cases, and following the rabbit hole wherever it takes me. I’ve done this personally through making “streams” which are my personal, tiny blog posts that look like DMs.
On that note, one of the most important sub-skills for writing and conversation as a design medium is learning how to create great analogies. Douglas Hofstadter thinks that analogies are actually the core of cognition, which I buy.
Beyond the theory though, great analogies have a lot of tangible benefits to the creative process, similar to the ones I described about writing for people outside of your field. My parents don’t work in tech, my grandparents speak mostly Russian, and I have plenty of friends who aren’t engineers or designers. Being surrounded by them helps ground me and makes me explain what care about in simple ways. Of course I have friends that I can get really low-level with, but explaining myself without jargon helps me accomplish multiple things:
- I have to clarify what I’m thinking, so it helps me focus what I want to say
- My friends learn more about what I do without having to parse nonsense
- If my friends want to go lower level, we can. But there’s no pressure to dive into something complex
- Side note: I love this project called Nutshell which makes it easy to make “expandable explanations” that let people dive deeper into topics without being overwhelemed by a lot of detail at first.
- It makes it easier to relate what you’re talking about to other things and can expand the conversation. If my mom can relate number theory to her own life and contribute a unique perspective about it, I think that’s a lot more fun than lecturing her on obscure notation
We’ve seen a lot of this around the internet, mostly in the form of ELI5 (explain like I’m 5). I also like explain this like we’re at a party, but I really hope you don’t get into conversations about abstraction with random people at parties
Speaking of primitives and abstractions, whenever you’re explaining something complex, it’s usually really helpful to provide concrete, relatable (duh), and sometimes oversimplified examples of your idea. Make the abstract conrete!!! The whole point of an abstraction in the first place is generalizing from a set of real observations. Of course you can create abstractions on top of other abstractions too (and this happens in math all the time), but almost every abstract idea or rule can be reduced down into a set of approachable examples.
Say you’re explaining what
Snapchat to someone who hasn’t seen a smartphone before and might only be familiar with analog cameras. It’s probably not very helpful to say “It’s just an app for sending disappearing pictures to your friends.” What’s an app? What do you mean it disappears? How is it being sent to your friend?
It might make more sense to say “it’s like a camera that mails pictures to your friends. Just like how Polaroid pictures fade in, imagine these pictures fade out after opening them. They disappear because they’re usually meant to be private and only looked at for a moment.”
This is obviously exaggerated and there’s still a few holes in the analogy, but it makes the core concepts much more tangible to someone who isn’t familiar with Snapchat in its native digital medium. This is also where LLMs might start to help us significantly with cross-cultural communciation: effortlessly creating effective examples and analogies to explain concepts to people from different backgrounds.
So what now?
Up to you! If you’re just getting started in design or engineering, take the time to dive deep into any one of these areas. If you want to learn more informally, just write, find writing you like, read about computer science, build some projects, and have fun. These are the kinds of skills you can get good out informally if you just spend enough time doing things you like that involve them, but I’ll probably make another blog post that has a bit more formal guidance on resources / courses / curriculum around these topics.