Navigating a Computer Coding Career: 10 Lessons from a Decade in Tech

In July 2011, armed with a fresh computer science degree, I stepped into my first job. Looking back, that was a pivotal moment, marking the beginning of my computer coding career ten years ago. Today, I want to reflect on this journey and share the key lessons I’ve accumulated.

My Journey into Computer Coding

Before diving into the lessons, let me briefly outline the path that led me here. If you’re primarily interested in the takeaways, feel free to jump directly to the lessons learned section.

The Unexpected Start

My initial aspirations weren’t actually in computer coding at all; graphic design was my first love. My exposure to programming before university was practically zero. In fact, my understanding of computer science was so limited, I didn’t fully grasp what I was signing up for.

My reasoning, in retrospect, was quite naive. I enjoyed mathematics and computers more than the subjects in an art degree curriculum. I mistakenly believed that computer science would involve learning software like Photoshop as part of the curriculum.

It sounds absurd now, but to my 18-year-old self, it made perfect sense. My high school computer classes focused on using programs like Microsoft Word and AutoCAD. I assumed a computer science career meant learning more advanced programs.

However, this initial misunderstanding turned out to be a happy accident. I discovered a genuine passion for programming!

2011: Launching the Career

In 2011, at 21, I completed my bachelor’s degree in computer science in just three years. While I could have extended my studies for a full degree, I had gained a solid understanding of the curriculum and felt ready for a different challenge. I was captivated by algorithms, yet still drawn to graphics. This led me to pursue a master’s degree in Artificial Intelligence and Computer Vision – a perfect blend of my interests.

However, academic life alone wasn’t fulfilling my growing ambitions. While I enjoyed my studies and assignments, I yearned for real-world experience. The concept of entrepreneurship had caught my attention, appealing to me greatly, even though, much like my initial understanding of computer science, I was largely ignorant about it. Coincidentally, a friend was starting a business and invited me to join part-time. This is how my computer coding career officially began at Ilurus. Later, we shifted focus to a new project called Veziko.

During this period, I began actively following online communities and developers. Jeffrey Way, who introduced me to CodeIgniter, was likely the first developer I followed and continue to respect. This marked my entry into the world of web development, a domain largely untouched in my university studies.

I also discovered podcasts, starting with Entrepreneur on Fire. While I no longer listen, and my perception of entrepreneurship has evolved significantly from viewing it solely through a Silicon Valley/VC lens, this phase was foundational. It helped me grasp the essence of entrepreneurship.

Then came 2012, a year of significant change.

2012: Embracing a Global Opportunity

In the summer of 2012, another friend presented an opportunity to join Toro, an international company with French roots and Asian headquarters in Taiwan. They were planning to open a Barcelona office and seeking 10 developers for a five-month training program in Taiwan, followed by the Barcelona office launch in January 2013.

While I valued my entrepreneurial experiences at Veziko, which remain cherished professionally, I felt progress was slow and craved more immediate real-world impact. Looking back, I understand that building a business takes time, but I was young and impatient. And despite enjoying my master’s program, it was still primarily academic.

Toro, on the other hand, was an established business offering international exposure and focused on mobile technologies, which I believed were the future (based on a professor’s insight, not personal foresight!).

The decision wasn’t straightforward. Ultimately, I chose to seize the opportunity (my first blog post, which I now find somewhat embarrassing!).

Following the five-month Taiwan immersion, things stabilized. We inaugurated the Barcelona office in January 2013. Fortuitously, I was able to continue pursuing my interest in graphics and UI. My primary role at Toro involved creating a UI engine for applications similar to J2ME. These applications, written in J2ME, ran on a cross-platform virtual machine. A key challenge was replicating native components as closely as possible. While it seemed unconventional then, today’s Flutter operates on similar principles, perhaps validating our approach. Beyond UI, I gained experience with assembler code and virtual machines. This role remains my most technically demanding. I even supervised a thesis on true-type font rendering.

I spent two formative years at Toro, learning significantly in my first “real job.” However, the entrepreneurial spark hadn’t faded, leading me to resign in the summer of 2014.

2014: Diving into Entrepreneurship

While Veziko represented pure entrepreneurship, Toro was my introduction to a corporate setting. It retained a startup atmosphere, but with more bureaucratic processes. I still desired autonomy and wanted to experience the full product lifecycle, not just the development stack, but from concept to launch.

Years prior, I had resolved to prioritize learning until age 25, even while employed. At 24, upon leaving Toro with some savings, I felt this was my prime opportunity to pursue entrepreneurship. Even if unsuccessful, the learning would be invaluable.

The challenge was identifying what to build. I was a textbook “wantrepreneur,” grappling with direction, as reflected in my post In the search of value.

However, this ambiguity provided space for experimentation and curiosity. This period laid the groundwork for many of my current values. For example, I created this website. I also deepened my involvement in web development, falling in love with Laravel.

I decided to brand my projects under the name Lincoln’s Chilli, considering it my “entrepreneurial sandbox.” Most of the projects I initiated are now discontinued, but one, Quick Pick, endures. This was my first product, embodying complete self-reliance. It’s entirely handcrafted. My girlfriend sketched characters on paper, which I digitized and colored. Even the game music is me playing guitar (though it’s just a simple tune!).

Alongside these personal projects, I collaborated with a friend on a more ambitious, perhaps too ambitious, venture: an online turn-based card game for mobile. Imagine a blend of Magic the Gathering and Chess. We didn’t hold back on features. I developed from scratch: a leveling system, a backend for card management, a custom protocol for cross-device action synchronization and replay, AI bots of varying difficulty, an interactive tutorial, and more.

It might seem over-engineered, and it probably was. However, working on this project was incredibly enjoyable and insightful. We also collaborated with illustrators and sound designers, expanding beyond just coding. The game is no longer available, but screenshots and an offline-playable APK can be found on the projects page.

For two years, I worked full-time on my own projects. But let’s talk finances. My earnings? €0. Yes, zero. Not a typo. This wasn’t due to lack of monetization efforts; the card game had in-app purchases, and my later products weren’t free. I even had ads on my second product, but revenue was negligible, not worth cashing out.

My consistent mistake was launching to silence. I learned the hard way that product quality is secondary to solving a real problem. And marketing is crucial, an area I largely neglected. Not to mention time – overnight success is a myth, and most of my projects were considered “finished” at launch. My products may not have been exceptional, but the consistent lack of response, regardless of effort, was telling.

Let’s be frank: it was failure.

Yet, I don’t regret a moment. My primary goal was learning, and I achieved that immensely. The difference between working as an employee and for yourself is profound.

Just as I was about to seek employment and abandon the entrepreneurial dream… I co-founded a startup.

2016: Startup Life

After two years of unsuccessful market attempts, I was ready to return to stable employment. But before applying anywhere, another opportunity arose. A friend had rented office space in a scientific park in my hometown. The adjacent office renter had just launched their startup idea and needed a technical co-founder.

Their vision was to offer pay-per-minute access to sports facilities, eliminating subscriptions and registrations. A nearby gym had piloted the concept successfully. The project was named Geemba.

The prospects were promising: ideal location, technical challenges, and a business model that resonated with me. However, challenges existed. My savings were dwindling, and this role wouldn’t immediately guarantee a stable income. Worse, it required personal investment to co-found the company. And I was 26 – the “learning” excuse was wearing thin.

But I was driven to pursue it, joining with conditions. We pursued a government-backed loan, Enisa. If approved, combined with our funds, it would provide a year’s runway without external investment. I took out a personal loan to cover my share, expecting to repay it with a modest salary and freelancing income.

This is how I became the “CTO” of a startup. Quotation marks because “CTO” in a two-person company is somewhat comical, but startup culture embraces such titles.

The next year and a half were transformative. Freelancing to manage debt was demanding, but I wouldn’t trade the experience. We hired part-time employees and, being near a university, hosted student interns. I even gave university presentations and served on master thesis juries.

Product-wise, I was proud of our solution. Customers used a mobile app to register payment details and request gym access. Receptionists used a dashboard to approve requests, granting entry and starting a timer. Upon departure, the receptionist ended the session, and customers were charged only for their time spent.

Technically, I learned immensely. I started using Vue, now a core technology in my stack. Building the interconnected system (app, backend, receptionist dashboard, etc.) was complex, requiring real-time functionality and payment integration. Thankfully, Stripe simplified payments. We avoided major technical issues.

However, the business didn’t succeed long-term. Customers loved the concept, but convincing gyms was difficult. Many perceived it as a threat to their subscription-based model, reliant on consistent payments even from infrequent users.

Initially focused on “gym by hours,” we pivoted to address gym needs, developing a CRM for all customers (beyond app users) and a personal training plan editor. Eventually, funds dwindled, and external investment was our only option. We chose not to pursue it.

After validating the idea for a year and a half, we concluded it was time to stop. Could persistent effort have changed the outcome? Perhaps. Could we have executed better? Definitely. Do I regret trying or stopping? Not at all.

You can find more about Geemba on the projects page.

After nearly four years of self-employment, I re-entered the traditional workforce.

2018: On the Wrong Path

Having been self-employed for so long, job searching was a new and daunting experience. My job-hunting skills were essentially non-existent. Compounding this, I lacked clarity on what I sought. Management? Technical lead? Startup CTO? Full-stack, front-end, or mobile developer?

Ultimately, I prioritized hands-on coding and looked for developer roles. However, narrowing options remained challenging. My preferred tech stack was clear, but organizational values and mission became paramount. Job boards lacked filters for these criteria. After a lengthy, unfocused search, I joined a startup called MusicList.

Initially, I was optimistic, being the first employee, hoping to influence company values. But quickly, a values mismatch became apparent. The founders’ values differed significantly from my own, a shift that occurred during my four years of entrepreneurship.

Their values weren’t inherently negative or unethical, but they were deeply entrenched in the Venture Capital Startup hamster wheel, which I had grown weary of. My priorities had evolved towards privacy and sustainability over hyper-growth. Reading Seth Godin’s blog provided a new perspective. His post, The wrong bus, resonated deeply. I felt on the wrong bus, headed to startup land, a destination I no longer desired. Reading it on a bus during my hour-long commute in August, while friends enjoyed summer holidays, amplified its impact.

Soon after joining, I resumed my job search, but without urgency. I had financial stability, no debt, and had recently moved out of my parents’ home (at 28!). The work itself was decent – using Laravel and learning React, completing my experience with the “big 3” front-end frameworks (React, Vue, Angular). Yet, a persistent unease remained, knowing I was on the wrong path.

The following year and a half involved a slow transition from acceptance to near-resignation. I was transparent with colleagues, even publishing a blog post announcing my job search and seeking career advice. I learned that job boards are often ineffective for finding truly fulfilling roles, especially the kind I sought.

The entrepreneurial drive persisted. I joined Seth Godin’s The Bootstrapper’s Workshop, which inspired me to start working in the open. This period also introduced me to Cypress, TailwindCSS, and Solid, completing my current tech stack.

While these side projects were fulfilling, my dissatisfaction with my day job grew. I considered quitting without a plan. A conversation at an event sparked an idea: the mythical 4-day workweek. Dedicating one day a week to side projects seemed like a way to satisfy my need for purpose, at least temporarily. I proposed it, prepared for rejection, ready to quit if denied.

To my surprise, it was approved. This marked the start of my 4-day workweek, a decision I haven’t regretted. Ironically, two of my best career decisions – working in the open and the 4-day workweek – emerged from a period of feeling most misplaced.

Months later, my job search efforts finally yielded a positive result. I received an offer I was excited about: a Mobile Developer position at Moodle.

2020: The Right Direction?

In November 2019, I joined Moodle. My unemployment was brief, but my active job search spanned most of 2018.

You might imagine countless applications. In reality, I sent only 21, roughly one per month. Of these, 9 rejections, 7 no responses, 3 ambiguous replies, and 2 acceptances (MusicList and Moodle). Three of the 21 were Moodle applications. First, for MoodleNet Technical Architect (pre-MusicList), rejected. Second, PHP developer, no response. Finally, Mobile Developer, accepted.

Job seeking, especially with specific criteria, is challenging. But I succeeded in joining a company with values I align with.

Am I now on the right path?

Time will tell, but I believe so. I’m no longer a “startup guy,” though I still consider myself an entrepreneur. The term feels slightly awkward, but I haven’t found a better descriptor. “Developer” is accurate, but I enjoy broader product involvement. “Maker” is close, but not quite right. “Entrepreneur” it is, for now, despite my projects not being profit-driven. Regardless of labels, I feel aligned with my direction.

I’ve found a healthy balance between employment and personal projects. Entrepreneurship for me was never about wealth, but meaningful work. Being an employee is fulfilling when contributing to a worthwhile cause. However, some aspirations require independent pursuit, making the 4-day workweek essential for sustainable side projects, independent of salary.

2021 and Beyond

Future plans?

Simply to continue. I’m happy at Moodle with no immediate plans to leave. My side projects continue to excite me, with no shortage of ideas.

Much has changed in a decade, making the next ten unpredictable. I feel fortunate to be in this field. Despite industry concerns, I love software development.

Lessons Learned

Having shared my journey, let’s focus on what might be most beneficial to you: the lessons I’ve learned over ten years in a computer coding career. Here are 10 key takeaways.

1. Values > UX > DX

If you expected purely technical insights, apologies. While I am a developer and these are lessons from a software engineer’s career, I can’t separate my professional life from my values. As engineers and humans, we are accountable for our work’s impact.

This wasn’t always clear. Now, it’s a core principle. In any work, employed or personal, the primary question is: what is its purpose? If it doesn’t align with my values, regardless of aesthetics or coding enjoyment, I won’t pursue it.

Consequently, and influenced by my design interest, User Experience (UX) is also vital. I consider it through the Kano model, focusing on impactful features.

While not a designer, Developer Experience (DX) is also important. My preference for Laravel and Vue reflects this; I want development to be enjoyable, focused on problem-solving, not battling accidental complexity or cumbersome tools.

These three – Values, UX, and DX – are hierarchical and achievable in concert. It might mean short-term delays, but I believe it’s a long-term advantage. I’d rather reduce scope than compromise quality.

2. Write Good Code

Every developer appreciates good code. But defining “good” code is subjective. Metrics could include problem-solving effectiveness, crash frequency, or extensibility. However, honestly, the best measure of code quality is WTFs/minute. Good code is simple code.

Simplicity is challenging. Rich Hickey argues simplicity is objective. But that’s simplistic. The simplest code might be isolated and useless. Over-engineered, highly flexible code becomes complex and unwieldy. The balance is crucial. I aim for conceptual compression: simple externally, powerful internally.

Concepts influencing my “good code” definition include: SOLID principles, YAGNI, First principles, code katas, etc. But there’s more. “Good code” isn’t purely measurable; it’s recognizable, often called “taste” by some, or “elegance” by me. Programming is not just science; it’s an art. That’s why I love it.

Write good code, create good art.

3. Be Opinionated

Developers are often taught to “use the right tool for the job.” While generally sound, often, the specific tool is less crucial than perceived.

Framework comparisons are common: Vue vs React vs Angular vs [new JS framework]. Truthfully, they achieve similar outcomes. Comparisons aren’t useless, but their project impact is often minimal. Ultimately, choose what you enjoy most.

React is popular, but I find Vue more enjoyable and intuitive. Writing React feels cumbersome (throwing a Promise as a valid approach?!), while Vue is seamless and enhances my development. This applies to my preferred tools: Laravel, Vue, TailwindCSS, Cypress. Coincidentally, they all have excellent documentation.

Misunderstandings often arise when I discuss this. I’m emphasizing personal preference. In team settings, other factors are more important, and I’m happy to use existing tools. Even if I had the choice, team projects might warrant different tool selections.

This doesn’t mean resisting new technologies. I embrace learning. But my preferred tools make development joyful. Patterns learned in these tools often transfer elsewhere, like porting Laravel facades to other languages.

“Tools” extend beyond frameworks. Your programming environment matters. Caleb’s course highlighted this for me.

4. Never Stop Learning

My preferred technologies were self-taught. And my greatest developer growth likely came from personal projects, not just “real jobs.”

As mentioned, the difference between employee and personal project work is significant. Conference talks, books, and blogs are valuable, but nothing matches building something independently from scratch. Deliberate self-improvement is crucial, not just expecting it as a job side effect.

Many developers avoid coding outside work hours, which is fine. The issue arises when companies don’t support professional development. Even when they do, it’s often limited to company-relevant technologies. Exciting new technologies or paradigms might be ignored due to project irrelevance or deadlines. However, pursuing that curiosity fuels long-term developer growth.

This isn’t inherently wrong from a company perspective; employment is labor exchange for money in capitalism. It can be humane and fair, but that’s the core. Living outside capitalism is an option, though challenging.

However, developers are privileged. Job availability is high, salaries are competitive, and remote work offers flexibility. Leveraging this privilege allows continuous improvement while maintaining work-life balance within the capitalist system.

My 4-day workweek is my approach. It’s not a 4-day week, but a 4-day main project week and 1-day side project week. If this sounds extreme, perhaps you haven’t tried it. Sabbaticals or freelancing are other options.

I understand financial independence, cost of living, etc., are factors. But if you lack a financial buffer over your lifetime, you have larger concerns. Developers are privileged enough to address this. For further reading, explore JLCollins and Mr. Money Mustache blogs.

5. Think Long Term

Code is read more than written. Written once, read countless times. Looking at my old code, I appreciate prioritizing readability and best practices (though “best practices” can be misleading). If it benefits me, imagine the impact on others reading your code.

Early in my computer coding career, I questioned the value of meticulousness. Spending time on variable names or code structure felt excessive. I did it instinctively, even enjoying it, but doubted its efficiency. Over time, the long-term payoff became clear. Some code is disposable, never committed. But how you do anything is how you do everything. There’s a balance between necessary detail and nitpicking.

Broadly, separate urgent from important tasks. Urgent and important tasks are naturally prioritized. The issue is prioritizing urgent, unimportant tasks over important, non-urgent ones. We rush to completion, but quality work takes time. Give it the time it deserves. When stuck on a problem, time is often the solution. Stepping away, working on something else, brings fresh perspective and easier solutions.

Apply this long-term thinking to mental bandwidth. Mindlessly task-list ticking is reactive, limiting progress. Proactive, reflective time, pursuing curiosity, leads to breakthroughs. It may seem slow short-term, but it compounds into long-term success.

Zooming out further, apply this to your computer coding career. Being lost for a while is okay; persistence leads to deserved outcomes. Short-term, luck is a factor. Interview rejections or project failures don’t necessarily reflect personal failings. Conversely, success isn’t always due to perfect execution. Long-term, luck evens out.

Crucially, “long term” can extend beyond your career, even your lifetime. Be comfortable not always getting what you want. Don’t compromise yourself hoping for future rewards. I’ve had ups and downs, but never pursued work I disliked. Plan for the future, live for today.

6. Use Systems and Processes

Regardless of experience, human error is inevitable. Our brains aren’t wired for long-term thinking; gut feelings can be erratic. Discipline and practice help, but perfection is unattainable. Systems are essential.

Peer reviews, schedules, workflows, linting rules – these reduce errors and improve consistency. However, systems shouldn’t become obstacles. Bureaucracy is universally disliked for a reason. While some structure is necessary, minimize it.

Systems are not static. Create, evaluate, and refine your processes continuously. This iterative improvement is itself an ongoing system. I constantly experiment and reflect on my systems’ effectiveness.

I’ve written about this previously; see Rigid-Flexible Planning and Order vs Chaos.

7. Remember Nothing

Years ago, I wrote about the power of ignorance, still a controversial idea. Five years later, I largely stand by it.

In computer coding, “remember nothing” seems counterintuitive due to extensive jargon. But “remember nothing” truly means “remember nothing on purpose.” When learning a technology, pattern, or paradigm, the name is least important. Knowing the name isn’t the same as understanding. Understanding naturally leads to name acquisition, which then compresses ideas. Names become shorthand for complex concepts, avoiding lengthy explanations.

Early in my computer coding career, I revisited basics. Things I knew, but enjoyed reinforcing through courses and reading. I continued until boredom set in, which I believe is crucial for internalizing principles.

Problem-solving offers another perspective. When project issues arise, I often create a minimal “hello world” application to isolate and reproduce the problem. This removes project baggage, providing fresh perspective. I consciously avoid remembering the rationale behind past decisions (hence minimal comments). If I later struggle to understand code or find unexpected method behavior, it’s a valuable newcomer’s perspective. If it’s not immediately clear, it’s likely flawed.

8. TDD Is the Way

Initially, like many, I was hesitant about Test Driven Development (TDD). Having experienced its benefits, I can’t revert.

I don’t advocate dogmatic TDD. Code coverage, for example, is a classic example of Goodhart’s law. But now accustomed to frequent testing, I feel restricted without it. Let’s call it TDD-ish.

Testing is valuable because we all do it. Developing a feature involves some form of testing: running scripts, browser checks, etc. This is essentially manual TDD. Automating these tests is the “TDD way.” Initially, it slows you down, hence developer resistance, including my own. But persistence leads to a point where writing tests becomes as natural as manual checks. Testing becomes an essential tool.

Short-term, it provides faster feedback during development. I often use Cypress instead of a browser for automated, time-travel debugging.

Long-term, it ensures peace of mind, enabling fearless refactoring without breaking existing functionality. Refactoring is vital; I likely refactor more than write new code. Without tests, refactoring fear leads to stagnation.

Testing is crucial for maintenance. Bug fixes are temporary without a test replicating the bug. It’s only fixed if there’s a test.

I don’t strictly adhere to the testing pyramid (more unit tests than integration tests). I write tests based on usefulness, varying by project. Libraries often require more unit tests due to isolated unit usage. Apps rely more on integration tests.

Two heuristics guide my testing approach. First, software breakage frequency. Bugs are inevitable, especially in edge cases. Excessive obvious bugs missed by tests indicate issues. Second, test change frequency during refactoring. Functionality-related test changes are expected, but excessive test suite breakage during refactoring suggests problems. Tests shouldn’t mirror code structure.

9. Be a Team Player

My online presence often focuses on independent development. However, most of my work is collaborative, and I prefer it that way.

Individual brilliance is limited. Collective success and quality are team-driven. “You are the average of the 5 people you spend the most time with” is a common saying. It might seem simplistic, questioning individuality, but there’s truth to it. Whether we seek like-minded individuals or environment shapes us, the effect is real. Likely both.

These “5 people” can include online figures – podcast hosts, bloggers, presenters. However, often, they are your work colleagues. Naval Ravikant advised: “if you can’t see yourself working with someone for life, don’t work with them for a day.” Initially, idealistic. Increasingly, it resonates.

You often can’t choose your colleagues, but you can choose your company. Companies with strong values likely attract value-aligned individuals. Even better, diverse perspectives challenge filter bubbles.

Joining an organization requires understanding. Changing culture is difficult, as is changing people. While frustrating, it’s often for the best. Consider the four stages of competence. Unskilled individuals may underestimate complexity. You are that person in more areas than you realize. Often, things are as they are for a reason.

However, don’t abandon cultural influence. Communication and awareness are crucial for project success, even more than best practices, technical solutions, or funding. Communication is paramount. This is why I prefer smaller companies, facilitating direct communication and understanding. While sometimes tedious, 1:1 meetings, expectation management, and regular updates are vital. Over-communication is preferable to under-communication.

10. Know Thyself

If you’ve read this far (thank you!), you likely disagreed with some points. That’s perfectly fine; my experiences aren’t universally applicable. They certainly didn’t all apply to me ten years ago, and won’t all apply in ten years. But self-knowledge is universally crucial.

Early in my computer coding career, I envisioned a linear path: junior developer, senior developer, manager. Reality diverged significantly. Managerial roles were interesting, but coding remained central. I dislike distancing myself from coding or technical problem-solving. Some thrive in management, enabling others’ best work. I admire that, but it’s not my path.

Later, I questioned employee vs. self-employment. The jury is still out. Either path is viable, depending on the work and collaborators, not just the employment structure. Some prioritize technology or salary; that’s not me.

I’ve always leaned towards “doing things right,” sometimes excessively, becoming an architecture astronaut at times. My experience can be both an asset and a hindrance. I’m aware of these tendencies, good and bad, and use systems to manage them.

Working in the open is a great way to know yourself. It’s valuable even without an audience. If unsure what “working in the open” means, just write. Writing clarifies thinking.

Self-discovery is ongoing. You will evolve. We are all chameleons, adapting and changing. Experiences shape our worldview. Your current perspective is a product of your life. Learning is constant, and new experiences bring new lessons.

Onward

These are my reflections after a decade in a computer coding career. I hope they’re helpful and I’m grateful for my journey so far.

I’ll continue working in the open. To follow my ongoing learning in real-time, follow along!

2024 Update: I’m no longer at Moodle. Learn more about my reasons and next steps in The End of The Chapter.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *