Introduction
In the tech industry, where new frameworks, tools, and best practices emerge constantly, it’s crucial for software developers to dedicate time to learning outside of work. But with so much to explore, focusing efforts can be challenging. I follow a structured approach that balances two types of learning tasks: Theory and Practice. This balance has allowed me to explore new areas without getting overwhelmed or losing momentum, and I’d like to share this process in case it inspires you to create your own learning plan.
The Two Pillars of My Learning Process
I break my non-working learning time into two main tasks: Theory and Practice. I focus on one at a time — either studying through books and courses or diving into a hands-on project. Here’s how I approach each.
Theory: Books and Courses
Books and courses provide a solid foundation in areas I’m less familiar with or would like to explore more deeply. Topics I’ve covered this way include clean code, design patterns, software architecture, databases, testing, working with requirements, etc. I also use this approach to dive into new paradigms and methodologies like functional programming, Domain-Driven Design (DDD), and Test-Driven Development (TDD).
I often discover reading materials or courses while browsing developer websites, like dev.to, or when I come across knowledge gaps during work or side projects. This approach allows me to methodically build up knowledge in specific areas.
Practice: Pet Projects
Pet projects are where I put theory into practice and test out new technologies or frameworks. These projects usually start as solutions to problems I face in daily life, whether related to language learning, productivity, or simply experimenting with tech. But the goal isn’t to create the perfect solution; it’s to focus on learning one new technology, library, or approach per project.
By limiting myself to one new thing per project, I avoid feeling overwhelmed and can stay focused. This approach also lets me skip tasks like setting up a full devops pipeline or extensive testing unless that’s part of the focus for the project.
This brings me to an important point: many of my projects get abandoned after I feel I’ve achieved my learning goals. Some of my early projects are public because GitHub used to charge for private repos, while most of my recent projects are private. But regardless of whether they’re finished or not, each project teaches me something valuable.
Case Study: My Projects and Their Purpose
Here are examples of my pet projects, each serving as a “sandbox” for exploring new skills:
video_converter_sinatra
This tiny web app converts videos from flv to mp4. It helped me learn the basics of the Sinatra framework (Ruby)
and explore video processing with FFMpeg.
gif_message
I built this Rails app to capture webcam video and convert it into GIFs directly in the browser. This project
gave me experience with media handling, an area I hadn’t worked on before, while getting more comfortable with
Rails.
slack_template
Intended to create and reuse message templates in Slack. This project helped me get hands-on experience with
Elixir Phoenix framework and IBM Bluemix. It was also my first time using the Slack API.
football
This project was an experiment in creating a multiplayer table football game using peer-to-peer (P2P)
technology. The concept aimed to let two players play a game similar to table football in real-time. While I
never finished it, the project helped me understand web-based P2P connections and data synchronization between
players.
exoda
I developed this library to convert OData queries to Ecto queries. But my primary goal was to learn
metaprogramming in Elixir.
pom_teams
This Teams bot helps with time management by scheduling Pomodoro timer notifications. I focused on practical bot
functionality rather than on any particular tech. Still, I gained experience in the Microsoft Teams API and bot
development.
tabletop-simulator-scripts
This was a set of automation scripts for Tabletop Simulator, written in Lua. Lua was entirely new to me, and
scripting for Tabletop Simulator provided a fun way to learn the language and experiment with game automation.
instant_jwt
This browser extension, created to retrieve OAuth tokens, is helpful when testing APIs that require
authorization. This project was my introduction to browser extension development.
code_navigator
This bot was designed to answer questions about a codebase using Retrieval-Augmented Generation (RAG). It was my
first time working with LLMs, so this project was both challenging and educational.
beat_the_street
A beat-em-up game developed in Defold, this project allowed me to work with game development engines and image
generation with Midjourney. It involved everything from character design to programming mechanics, giving me
experience in creating game assets and mechanics.
aof_suite
I built this desktop app using Flutter to study a simplified poker variant. The project taught me the basics of
Dart, Flutter and cross-platform development in general.
lang_tutor
This web app helps me practice Spanish conversation by interacting with LLMs. My initial aim was to experiment
with agentic workflows, but I eventually decided on a simpler, more controlled approach that makes sequential
LLM requests. This project combined my interest in language learning with practical experience in building apps
powered by AI.
json_to_json
This is my latest pet-project. It's a Svelte-based web app that allows users to upload a JSON file and map parts
of it into a new output file. My primary goal was to learn Svelte.
Each of these projects has helped me experiment with technologies or frameworks I may use later in my professional work.
Conclusion
By dividing my learning time between Theory and Practice, I can explore new concepts, test-drive different tools, and sharpen my skills without losing sight of my learning goals. If you’re trying to grow as a developer, I’d encourage you to design a plan that plays to your strengths and keeps you motivated. Embrace experimentation, focus on the process, and let each project teach you something new.
Happy coding!