RubyConf Mini 2022

Solo: Building Successful Web Apps By Your Lonesome

Solo: Building Successful Web Apps By Your Lonesome

by Jeremy Smith

In the video "Solo: Building Successful Web Apps By Your Lonesome," Jeremy Smith discusses the unique challenges and advantages of developing web applications as a solo developer. Despite the common perception that software development is a team sport, he emphasizes the effectiveness and satisfaction that can come from working independently. Here are the key points from his talk:

  • Reasons for Going Solo: Smith outlines several motivations for choosing solo work, including:

    • Holistic Competence: Emphasizing a generalist approach over specialization, akin to small-scale diversified farming as opposed to monocrop agriculture.
    • Autonomy: Working alone allows for greater personal autonomy, which is a significant motivational factor for many.
    • Pleasure of Accumulated Sophistication: The satisfaction of developing complex systems from simple beginnings over time.
  • Identifying Suitable Solo Projects: Smith provides types of projects ideal for solo work:

    • Early-stage projects like startups or side hustles.
    • Small indie products run by individuals.
    • Internal applications addressing specific organizational needs.
    • Throttled projects where time constraints are non-critical.
  • Three Keys to Successful Solo Development: Smith emphasizes three principles:

    1. Be Good: Continuously improve your own skills and application quality.
    2. Be Fast: Streamline development processes to adapt quickly to changing requirements.
    3. Don't Die: Focus on sustainability of both your project and personal workload.
  • Learning and Growth Strategies: Smith stresses the importance of:

    • Finding a Community of Practice: Engage with others in your field to fill knowledge gaps and gain different perspectives.
    • Dedicated Context Switching: Separated creative and editing phases in development to enhance quality.
  • Building and Improving Systems: To ensure a successful application, Smith suggests:

    • Clarifying optimization goals based on user needs and expectations.
    • Keeping the tech stack minimal and familiar to reduce complexity and risks.
    • Establishing strong feedback loops through automated testing and observability in production.
  • Sustainability: To manage the long-term health of a solo project:

    • Be your own manager by recognizing achievements and mitigating frustration.
    • Comprehensively document processes for easier project handover when needed.

In conclusion, Smith reinforces that, while one may work solo, they are never truly alone in their responsibilities. The success of any application hinges on the interplay with users and collaborators, making effective communication and value creation essential. This presentation serves as a guide for developers choosing the solitary path, offering insights cultivated from Smith’s extensive experience in the field.

00:00:11.540 I'm Jeremy Smith, a Ruby enthusiast living in Greenville, South Carolina. I run Hybrid, a tiny one-person web studio.
00:00:17.699 Software development may typically be a team sport, but it doesn't have to be.
00:00:24.140 I've been building web applications for over 20 years, and much of that time, I've worked alone as an employee, contractor, or technical co-founder.
00:00:31.380 I feel like I lucked out when I picked up Ruby back in 2009. I believe our community is one of the best for solo developers building on the web.
00:00:36.719 While my talk is codeless, much of what I'm sharing has come from growing up and learning my craft in this community.
00:00:52.500 Some of you may already be working on solo projects or at least have the desire to. Others may wonder why someone would choose to go it alone, given the clear advantages of working in a team.
00:00:59.460 So why go solo? Here are my reasons. The first is focusing on broad or holistic competence over narrow excellence, also known as generalization over specialization.
00:01:06.240 It's easy to appreciate the value of being a specialist—specialists are the best at what they do within a narrow frame.
00:01:12.600 However, the advantages of being a generalist are not always obvious. To illustrate this point, imagine a farmer running a small-scale diversified family farm. That farmer must be competent in constructing infrastructure, building soil, raising multiple varieties of crops, caring for animals, and marketing and selling to customers.
00:01:23.580 This is very different from large-scale monocrop commodity agriculture, which focuses solely on maximizing corn yield from any given acre. The small-scale farmer concentrates on the thriving of their entire system, regardless of how small it may be. In contrast, the large-scale commodity farmer must optimize for one aspect or outcome while disregarding other important parts.
00:01:47.460 I’m not saying that specialization is bad; it can be important and admirable work. However, when it comes to running a small, healthy family farm, you want to be a generalist. Secondly, there's the optimization for autonomy. Daniel Pink, who wrote 'Drive: The Surprising Truth of What Motivates Us,' indicates that autonomy, mastery, and purpose are three key aspects of motivation.
00:02:24.180 Working alone offers you the highest level of professional autonomy. While the importance of these three motivational aspects can vary from person to person, for some who are greatly motivated by autonomy, solo work can be an excellent choice.
00:02:43.379 This reminds me of a 90s post-apocalyptic movie, 'Waterworld.' In it, Kevin Costner pilots his trimaran on endless seas after the polar ice caps have melted. He catches his own food, defends himself against pirates, and travels where he pleases. In his character, I see the satisfaction of possessing the skills and abilities to navigate, repair, and extend a vessel that carries you on a journey. It may not be the biggest, fastest, or best, but it is yours.
00:03:16.319 The third reason I prefer solo work is what I call the pleasure of accumulated sophistication—transforming something from crude and chaotic beginnings to a more refined and ordered state over time. This concept may sound odd, but I've found joy playing Minecraft, where you start in the wilderness with basic natural materials and progressively build more sophisticated infrastructure.
00:03:38.280 You start with a crafting table and pickaxe, then build a hut, a potato patch, and eventually castles and minecart railways. Initially, the focus is on survival, but as you progress, you can enhance your surroundings, creating order and adding comfort. While this can certainly happen in a team, I’ve noticed that when you achieve this for yourself, the resulting signs are more striking, offering a profound satisfaction in both the process and the outcome.
00:04:07.200 Now, where do you find suitable solo projects? Here are the categories I look for: first, early-stage projects such as startups, side hustles, and prototypes that are often constrained by funding and time. However, if they succeed, you probably won’t be solo for long.
00:04:19.919 Secondly, there are small indie products built and run by individuals, whether that is you or as a solo founder whom you take over the development for. Third is internal or ancillary apps, where organizations have needs that off-the-shelf solutions don't meet, but those products are essential yet not a core focus for them. Finally, throttled projects—these are projects constrained by various factors where time to market is not the primary concern.
00:04:45.240 Now, I’m going to share the three keys to building and maintaining web applications on your own. It's really simple: be good, be fast, and don't die. I’ll break down each key, looking at it from both a personal perspective and from the system you're building, which includes the code base, processes, tooling, infrastructure, vendors, and other participants involved.
00:05:12.000 When I say 'be good,' I'm referring to your knowledge and skills as well as the quality of the application. 'Be fast' relates to the speed of your development and the system's adaptability to changing requirements. When I say 'don't die,' I don’t mean literally; it refers to improving your app's sustainability and increasing your odds of longevity. I will share 24 things I wish I'd known when I got started, beginning with being good.
00:05:42.960 When you're solo, there are advantages and disadvantages. There's no one telling you that you're doing it wrong or questioning your architectural decisions or technology choices, and no one is holding back your growth. On the other hand, there's also no one to point out your weak areas, to push back on your decisions, and help you improve. You don’t have someone to talk through problems with, to review your code, or to share your successes.
00:06:06.360 So how do we make you better? First, find a community of practice. Look for people doing the type of work you want to do, using the tools you want to use, who embody a strong philosophy and share their processes and learnings. Immerse yourself in their way of thinking and working—read everything they write, watch their presentations, and learn to think like they do. This can make up somewhat for a lack of mentorship.
00:06:50.160 As you learn, you’ll eventually encounter ideas and opinions that differ from those you follow, and that’s normal. When you feel you've learned all that you could from a person or company, it's okay to move on to others. It's vital to have role models to look up to. Also, be vigilant about scanning for gaps in your knowledge. When working and learning alone, it's easy to miss concepts or skills that aren’t pointed out because there’s no one to highlight them.
00:07:30.840 This distinction between informal and formal learning is important. Formal learning is systematic and closely aligns with the boundaries of a discipline, while informal learning is more organic and often comes with gaps. Pay attention to terms and concepts related to what you know that are unfamiliar—that’s your cue to explore deeper.
00:08:21.300 In creative writing classes, I learned that creating and editing are separate modes of work, both necessary but often in conflict. When creating, it’s crucial to turn off your inner editor, which can tempt you to settle for the first feasible solution. This is even easier when working in a group, where multiple members can surface different solutions. Alone, it’s tempting to simply go with the first idea.
00:08:36.540 To remedy this, separate these modes by context and time. For example, when I build a feature, I create it and create a pull request (PR). Then, I return later to review the PR as though it was submitted by someone else, ideally after a break of several hours or even a day. This switch in context from code editor to GitHub PR review allows for a fresh perspective.
00:09:22.140 When working solo, you must wear all the hats—you can’t think of yourself as merely a developer. I call this the 'dammit gym principle.' You are responsible for everything necessary to deliver a successful project. If you're creating the UI, you are the designer. And if you struggle to identify as a designer, think of yourself as the person responsible for the design.
00:09:57.700 Invest proportionally in learning the various roles you fill—design, writing, DBA, system administration, marketing, analytics, etc. People love to say what they are not: 'I’m not a runner,' 'I can’t sing,' or 'I don’t have a green thumb.' Although talent distinguishes individuals, most roles require a combination of perspectives and learnable skills applicable to problem-solving.
00:10:44.580 So how do we make your system better? Clarify what you're optimizing for. Organizations have different requirements and tolerances; what might be acceptable practice for one may not hold for another. Each app and its current lifecycle stage have distinct needs—identify what you are being asked to optimize for and try to make the implicit explicit, if not for anyone else, at least for yourself.
00:11:09.660 Are you optimizing for experimentation, rapid feature development, future optionality, stability, or fixed costs? Here are some examples of how that might be framed: we can live with occasional maintenance windows or downtime but must keep infrastructure costs below a certain threshold, or we can tolerate missing a delivery deadline but can’t afford to launch a poor user experience.
00:11:53.720 This may seem overly pragmatic, but I believe it's best to align with your organization’s priorities and build a system reflecting those. If you disagree with those priorities, address it through discussion and persuasion; don't work at cross-purposes. It's tempting to kick off problem-solving using the skills that come easiest to you—likely, those from development.
00:12:11.760 From my experience, projects progress better when you move from intent to content to form to function. It's easier to get functionality right when the form is correct; it's simpler to achieve the right form when the content is accurate, and it’s easier to nail the content when your intent is sound. Changes in the earlier stages dramatically affect the later ones.
00:12:49.200 Most of the time, starting with development leads to regrets because it results in a suboptimal user experience. My pages often resemble rows in a database when design is secondary to development. When I start with design, I better understand what I’m programming; the interfaces and flows follow suit. When design comes before content, I end up creating visual buckets to dump generic text and images into, which diminishes the user experience.
00:13:05.380 So when I have content first, and then design flows from that content, the experience improves. Learn from your failures. In cases of production incidents, there are two traps to avoid. The first is thinking you can just mentally file the lessons away—memory isn't perfect.
00:13:45.660 I have found significant value in writing post-mortem reports detailing how and why a failure occurred, what customer impact resulted, and how I responded. Regularly reviewing incidents helps identify recurring issues. The second trap is convincing yourself that you don’t have time to address any underlying problems. Over time, this leads to more time spent battling operational issues than on development.
00:14:09.300 You may have heard of the 'five whys' technique, but since it’s just you, I recommend the 'three whys' approach. Ask why the incident happened, then ask why again, repeating it three times. Each answer exposes a level that could be improved. For example, if a customer didn’t receive an important daily summary email, you might ask: why not?
00:14:48.000 If the nightly job that sends the summary email failed midway through, ask why. If it was because the job iterates over customers to send each email but there was a timeout on one delivery, ask why again. If you hadn’t anticipated or tested for failure states, you may now have a clearer path to improvement. Lastly, propose an investment that you could make on each of these levels. The investment should correlate to the severity of the incident—small for minor problems, large for significant failures.
00:15:44.800 For instance, adding alerting for job failures or switching to a fan-out approach with a separate background job for each customer’s email delivery—with a retry for failures—is a way to address the situation. Make sure to set aside personal time for research and learning.
00:16:07.800 Additionally, take actionable steps based on at least one of those investment areas. Managing everything alone can feel overwhelming, especially considering all the ways to improve your system's state. One technique that I find helpful is that of 'ratcheting up.' Establish a baseline of where you are currently, not caring if it’s bad or good, and then gradually step up over time with whatever budget you have available for improvements.
00:16:50.520 This could include introducing code formatting and style tools, increasing automated test coverage, enhancing app response times, updating or eliminating dependencies, or adopting a design system. You don’t need to implement everything at once—it's best to commit to gradual improvements in multiple areas moving in the right direction.
00:17:32.040 Look for ways to automate those ratcheting commitments, such as configuring continuous integration (CI) to fail under certain conditions or setting recurring calendar events to devote time to specific problems each month. Now, let’s discuss how to be fast. There are certain advantages and disadvantages to that, too. There’s no time wasted building consensus, no time spent in disagreement over tools or approaches, and no extended coordination with others needed.
00:18:16.800 However, there is no parallel work among team members, no momentum you benefit from, and there’s no one to assist you in getting unstuck. So how do we make you faster? When starting a project or feature, focus first on the biggest unknowns.
00:19:06.900 In project estimation, there’s the concept of the 'cone of uncertainty.' At the start of a project, there is often the most uncertainty about what you're building and how long it will take. The further you go, the clearer things become. If you tackle parts of the project you know the most about first, you merely create the illusion of progress without truly narrowing the cone of uncertainty.
00:19:43.560 As a result, you typically spend too much time on areas where you feel most familiar and comfortable. By tackling the biggest unknowns first, you unveil hidden complexities and gain clarity sooner. This clarity helps you budget your time better and sets realistic expectations for delivering the entire feature or project.
00:20:37.560 Inventing can be fun, but you need to focus on shipping when working alone. Steal as much as possible—using open-source tools is just one way to go about this. I'm also referring to UX patterns, design, copy inspiration, playbooks, processes—whatever you're aiming to accomplish, someone has likely done it before.
00:20:55.320 Life, work, and art are filled with riffing and remixing—building on the work of others is what we’re meant to do. Austin Kleon, who wrote 'Steal Like an Artist,' provides us with guidelines for good theft versus bad. Good theft means honoring instead of degrading, studying instead of skimming, stealing from many instead of one, crediting instead of plagiarizing, transforming instead of imitating, and remixing instead of ripping off.
00:21:26.400 Reduce your work in progress. When working solo, it can be tempting to multitask, and there may be pressure from your organization to juggle many things at once. However, if you want to go faster, reducing your work in progress is one of the simplest and most effective methods. As a rule of thumb, aim for just two tasks at a time—perhaps one major and one minor, like a new feature and a maintenance task.
00:22:13.200 When working on these, if one gets blocked, you can switch to the other. If you manage more than this, you'll likely lose efficiency due to context switching and suffer morale declines as it takes longer to complete each task.
00:22:56.520 I enjoy backpacking, and I've learned to consciously adjust my pace based on changing terrain. You may seek overall speed, but that doesn’t mean that your pace should always be constant. Slow down when climbing uphill or navigating rocky paths—if you rush, a fall can be serious, especially alone.
00:23:37.320 In software, this means slowing down when addressing tricky issues like data security. Consider the current landscape: what could go wrong? Pay attention to your instincts; if you feel nervous, there’s likely a valid concern. Enhance your planning of riskier moves with extra research, small incremental changes, and predefined rollback strategies.
00:24:11.640 To improve your system, keep your technology stack minimal and as ordinary as possible. Stick to tools you are familiar with, aiming to achieve multiple benefits from each one. Dan McKinley suggests a certain number of innovation tokens teams can spend for creative risks. Early in a company’s life, you may have three tokens—if you’re solo, you probably have only one, and it should be tied to your product’s core differentiator.
00:24:45.840 Every new technology demands time to learn and master, resulting in unknown downsides or limitations. Each tool carries a lasting cost—while there is a minimum set of necessary tools, be cautious with adding new ones. Technical debt can temporarily accelerate progress, but it is almost always slower in the long run.
00:25:30.480 The only situation where building something quick and dirty works out is when you discard it. The savings are the time you would have otherwise spent creating a higher-quality product. If that quick-and-dirty solution lives on, your development speed is delayed each time it requires attention until you can come back to improve its quality.
00:26:04.440 Thus, my guiding principles regarding technical debt are the following: if you’re building something speculative, if business owners and users are highly tolerant of failure, or if your product is 'default dead' (meaning the project may not survive based on its current trajectory), it may be a suitable time to utilize technical debt.
00:26:33.060 If you’re feeling pressure to deliver a specific feature faster than usual, it can also be appropriate to incur some technical debt, provided the organization understands future costs. However, if you’re always under pressure to cut corners and deliver quickly, it may signify an unhealthy environment.
00:27:07.200 To build a sustainable pace, it’s vital to create feedback loops. Working fast over the long term requires a strong confidence in your system—confidence that what you’ve already built is functioning correctly and that changes you make work as intended. Cultivate that confidence through feedback loops at multiple levels.
00:27:49.200 The first level is automated testing. I was once skeptical about automated testing, but I didn’t realize how much time I was spending on manual testing that arose from the absence of automated tests. The lack of tests led to uncertainty and anxiety about making changes, which invariably slowed me down.
00:28:22.120 The second level is production observability. You need immediate awareness of issues in production, degraded performance, or user obstacles. Utilize an exception tracker, app performance monitor, and track key metrics related to user outcomes.
00:28:56.820 The third level involves maintaining open communication lines with your customers. Collaborate with customer support when possible to help filter notable feedback and to inform users of changes affecting them.
00:29:39.480 While coding is enjoyable, it’s beneficial to minimize the amount you write. Remember that it’s not just the production costs; consider long-term maintenance costs as well. Exercise discipline to avoid building for hypothetical scenarios. Trust me, the future always differs from expectations, and I’ve wasted time designing things that later were either unnecessary or simply not right.
00:30:43.020 Make use of off-the-shelf solutions whenever possible. Can you buy a reporting tool instead of crafting one for your admin panel? Can you rent an integration until you're certain that it’s necessary to build your own? If it’s not core to your product and expenses are manageable, always prefer purchasing.
00:31:12.450 Now let’s talk about surviving. The benefits and disadvantages of working solo include the satisfaction of knowing you've built something yourself and the full ownership and responsibility that comes with it. Conversely, your project's failure hinges solely on you.
00:31:18.079 How do we enhance your sustainability? Be your own best manager. Working solo often leaves you either unmanaged or under-managed—recognize that you need to step outside your role and treat yourself as a direct report that merits care and attention.
00:32:08.220 Recognize and celebrate your accomplishments; look for barriers to progress and brainstorm ways to eliminate them. Pay attention to signs of your own frustration, fatigue, and anxiety, and take proactive steps to address them. When things go awry, be compassionate toward yourself—conducting blameless postmortems is invaluable, even if it’s just you.
00:32:52.460 Take time to communicate the value you are creating, whether to your client if you’re consulting, to your non-technical partners or investors in a startup, or to your customers and users while developing an independent app. No one else will handle this for you. Without a team lead or technical manager recognizing and conveying your contributions, it’s easy to assume your work will speak for itself.
00:33:35.800 In reality, it often doesn’t. You need to advocate for your own work, communicating the value you've generated to those you serve. Be prepared to initiate these communications independently, and think creatively about how to present your contributions. Move to progressively higher levels of consideration. I learned that there are three phases when through-hiking the Appalachian Trail, which spans over 2,000 miles and may take six months to complete.
00:34:51.340 In the first third, you focus on your gear—your pack hurts, your shoes rub, and you need to set up your tent efficiently amid incoming rain. In the second third, your attention shifts to the terrain: reading the landscape, understanding weather patterns, observing plants and animals, and learning navigation techniques. Finally, in the last third, you turn inward, asking, 'Who am I? What is my purpose?'
00:35:38.060 Similarly, during a career building products, you start by focusing on tools, learning languages, frameworks, and databases. As you progress, you learn to navigate the development process and consider what you implement. Eventually, after building many things and uncovering processes that work for you, you begin to contemplate whether you are building the right things.
00:36:05.080 At this stage, you ask yourself what you should be doing that hasn’t been requested of you and how you can better support your clients, partners, or customers. This progression is likely to occur naturally, with each phase presenting a new focus and reinforcing your commitment to stay the course.
00:36:46.440 It may become challenging to develop your knowledge and skills within a single domain or problem space. When working alone, there’s a natural push to remain on a project even when it’s no longer beneficial to you. Therefore, I recommend reevaluating your progress in relation to a project every couple of years, moving on if it no longer serves you.
00:37:12.440 Another approach that has worked for me is to work on multiple projects concurrently, which can help sustain your skills and knowledge while preventing stagnation in any single area. When technological changes arise, remain adaptable to various scenarios and stay informed about industry trends.
00:37:54.480 It's crucial to align with the majority within your community. When changes occur, it’s wise to let organizations with more resources explore new tools and environments first. They can expose rough edges and document processes, providing you valuable insights before you transition. However, avoid being the last to transition as context may be lost, and it can become harder to find assistance when most of the community has moved on.
00:38:29.660 This applies to libraries falling out of fashion, framework version changes, platforms undergoing disruptions, and third-party services shifting focus or changing pricing. I've experienced all these challenges over the past decade. It's incredibly difficult to accomplish tasks in a low-trust environment, and it’s not healthy to remain in such an environment over the long term; fostering trust builds the psychological safety necessary for all involved, including yourself, business owners, other staff members, and users.
00:39:10.960 Trust hinges upon relationships that build community among teams, organizations, tools, and processes. Instead of assessing each trust relationship individually, watch for signs of distrust—surprise, anger from unmet expectations, decisions hidden from others, hesitations to change code or processes due to past experiences, excessive verification or micromanagement, unresolved long-run debates, and a lack of collaboration.
00:39:52.400 When you notice these signs, seek opportunities to foster trust in areas where it's lacking: spend more quality time together, apologize or make amends when necessary, increase transparency or the level of detail shared, change communication mediums when needed, propose solutions that align interests, and clarify expectations while committing to follow through.
00:40:29.700 Eventually, you may consider leaving a project, so it’s essential to plan ahead. Build your project as though you were preparing to hand it off, ensuring you’re always ready for that eventuality. For example, keep all your credentials in a password manager to which a trusted person has access, maintain an updated readme, write automated tests, and document your architectural decisions, processes, and run books thoroughly.
00:41:14.920 Even if you don’t discuss this with your clients or partners upfront, develop a plan regarding who would take over your project if you were unable to continue. This can express active care and service to your clients, offering them reassurance even if it’s not a typical request.
00:41:51.580 To summarize, the reality is that you're never truly solo. No one creates solely for themselves—we create to influence or serve someone else, communicate, and ultimately connect. You might be the one responsible for maintaining a web application, but others are always nearby, whether they are clients, collaborators, or users.
00:42:14.000 Perhaps you are a consultant in a dance marathon, where your dance partner is your client. Or you could be the technical partner in a business venture, like a crew in a heist movie, and you are the specialist responsible for developing web products—the success of the entire team hinges on you. Whatever the scenario, building web applications as a livelihood requires creating value for others, leading to interactions and co-creation.
00:43:19.060 Ultimately, it's the things we create together and how we relate to our clients, partners, and users that truly matter.