<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/i-m-starting-to-think-every-developer-should-build-their-own-internal-tools-otvptdniq" -->

---
title: I’m Starting to Think Every Developer Should Build Their...
description: Building internal tools for your own real problems teaches software development more effectively than generic practice projects. When you build something you...
canonical: https://daily.dev/posts/i-m-starting-to-think-every-developer-should-build-their-own-internal-tools-otvptdniq
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: I’m Starting to Think Every Developer Should Build Their Own Internal Tools | daily.dev
og:description: Building internal tools for your own real problems teaches software development more effectively than generic practice projects. When you build something you...
og:url: https://daily.dev/posts/i-m-starting-to-think-every-developer-should-build-their-own-internal-tools-otvptdniq
og:image: https://api.daily.dev/og/posts/oTVPTDNiQ.png
og:image:alt: I’m Starting to Think Every Developer Should Build Their Own Internal Tools
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# I’m Starting to Think Every Developer Should Build Their Own Internal Tools

**[John Liter](https://daily.dev/sources/yhf9cpdgtqetokv6d8qhm)** · [@jliter85](https://daily.dev/jliter85) · 11 min read · 254 upvotes · 55 comments

## Summary

Building internal tools for your own real problems teaches software development more effectively than generic practice projects. When you build something you actually use, requirements emerge from genuine needs rather than technology choices. This forces you to care about authentication, responsive design, deployment, error handling, and performance — the parts tutorials skip. It also creates a constant feedback loop since you are your own user, making friction and poor decisions immediately apparent. The approach helps recognize overengineering, lets the project dictate what to learn next, and produces software that continues to deliver value after the learning is done.

## Content

# I’m Starting to Think Every Developer Should Build Their Own Internal Tools

### The small tools I build to solve my own problems are teaching me more about software development than another generic practice project ever could.

There is a point in learning development where another tutorial project stops being as useful as building something you genuinely need. Practice projects have their place, especially when I am trying to understand a new language, framework, database, or programming concept, but some of the projects teaching me the most now are not projects I started because I wanted more programming practice. I started them because I had a problem, and development happened to give me a way to solve it.

That difference has changed how I approach building software. When I create something I actually intend to use, getting the primary feature working is only the beginning. The application has to survive contact with my real workflow. I have to think about how quickly I can accomplish a task, whether the interface works on the devices I actually use, where the data lives, how I access it later, and what happens when something goes wrong. Instead of creating requirements to justify using a technology, the problem creates the requirements for me.

## A Real Problem Creates Better Requirements

Practice projects often begin with a technology. I might want to learn React, so I look for something to build with React. I might want more experience with SQL, so I create a project that gives me a reason to design a database. That approach can be useful because it provides a controlled environment for learning, but the requirements are usually shaped around the technology rather than an actual need.

Internal tools reverse that process. One example for me is mileage tracking. I do gig work, and I wanted a better way to record mileage without forcing my workflow into somebody else's application. That problem became **RouteLedger**, a web application I am actively building around the way I actually record and use mileage information. I did not start RouteLedger because I needed another portfolio project or wanted an excuse to use a particular framework. I wanted a mileage tracker that worked the way I wanted to work.

That immediately created practical requirements. I wanted to use it from my iPad, which meant the interface had to work properly beyond a desktop browser. The data needed to persist reliably, and entering mileage needed to be quick enough that recording it would not become an annoying task I eventually stopped doing. Those decisions were not hypothetical requirements invented for a programming exercise. They came directly from using the application for its intended purpose.

## Real Software Makes the Boring Parts Important

A tutorial can conveniently end when the primary feature works. Software I depend on cannot. Once I begin using something regularly, details that initially seemed secondary become much more important. Authentication matters because the application contains real data. Responsive design matters because I may not always use it from the same device. Database structure matters because the information needs to remain useful as the application evolves. Deployment, error handling, performance, and security become part of the project because the application has moved beyond demonstrating that a feature is technically possible.

Building internal tools also forces me to experience the consequences of my own decisions. If I create an awkward workflow, I am the person clicking through it tomorrow. If the mobile interface is frustrating, I am the person trying to use it on an iPad. If I structure part of the application poorly and later need to expand it, I experience the cost of that earlier decision instead of handing the problem to an imaginary future user.

That feedback is valuable because it shifts my attention from whether the software works to whether the software works well enough to become part of my routine. A feature can function exactly as programmed and still be inconvenient, confusing, or unnecessarily slow to use. Those problems become difficult to ignore when I repeatedly encounter them myself.

## My Development Projects Are Becoming Real Systems

I am seeing the same pattern beyond RouteLedger. I have built systems because I need somewhere to manage information, workflows, and processes that would otherwise become scattered across different tools. My CRM, for example, exists because leads, customers, appointments, quotes, invoices, payments, tasks, communications, and automation activity eventually become difficult to manage when they are disconnected. Other projects have grown from similar needs involving content, publishing, databases, websites, and automation.

Working on those systems exposes me to PHP, React, MySQL, APIs, authentication, deployment, Linux, web servers, responsive design, security, and infrastructure, but those technologies are not the reason the systems exist. They are implementation choices supporting the workflow. That distinction has become increasingly important because it changes the first question I ask when approaching a project. Instead of asking which technology I want to use, I have to understand what the system actually needs to accomplish.

Sometimes that leads to a less technically interesting solution, and I am becoming more comfortable with that. A project does not become better simply because I can make its architecture more complicated. If a straightforward implementation solves the problem reliably and leaves room for reasonable growth, complexity for its own sake only creates more work.

## Internal Tools Make Overengineering Easier to Recognize

Developers have access to an enormous number of technologies, and it is easy to make a small problem technically impressive simply because the tools are available. A relatively simple application can quickly accumulate additional services, databases, queues, containers, abstractions, and dependencies before there is a demonstrated reason for them.

Building software for myself makes the maintenance cost of those decisions more obvious. Every dependency I add is something that may eventually need to be updated, debugged, secured, migrated, or replaced. Every additional service creates another point where something can fail. Complexity can absolutely be justified when the problem requires it, but I am trying to become better at distinguishing necessary complexity from complexity that exists because I wanted to experiment with another technology.

This does not mean I want every project to remain simple forever. Some systems naturally become more sophisticated as their requirements grow. The lesson for me is that complexity should arrive because the problem demands it. If a PHP endpoint and a MySQL table reliably handle a requirement, replacing them with several additional layers does not automatically make the software more professional. Good engineering includes knowing when not to add something.

## The Project Can Decide What I Need to Learn

Building internal tools has also changed the relationship between learning and development for me. Earlier in my development journey, it was natural to study a technology first and then search for something I could build with it. Increasingly, I prefer allowing the project to expose the gaps in my knowledge and using those gaps to determine what I should study next.

If I encounter a database problem, I suddenly have a concrete reason to understand that part of SQL more deeply. If two systems need to communicate, APIs stop being an abstract subject and become part of solving an immediate problem. If a deployment fails, I have a reason to understand more about the server, environment, or deployment process involved. Working from Linux has created the same experience because problems with permissions, services, packages, Git, SSH, or the filesystem give me specific concepts to investigate instead of an endless list of Linux topics I might eventually need.

This approach gives my learning a useful filter. There are hundreds of technologies I could spend time studying, and many of them are interesting, but I cannot learn everything simultaneously. A real project tells me which knowledge is necessary now, and applying that knowledge immediately makes it easier to understand why it matters.

## Using My Own Software Creates a Constant Feedback Loop

One of the most useful parts of building internal tools is having continuous access to the user. I know when something annoys me because I encounter it directly. I notice when I avoid a feature because the workflow takes too long, when information is displayed in the wrong place, or when an automation merely moves work around instead of eliminating it. I do not need a survey to discover those problems because they become part of my own daily experience.

That feedback has made me pay more attention to small amounts of friction. Developers can naturally become interested in large features because they are more technically satisfying to build, but a collection of small interface and workflow decisions often determines whether software is pleasant to use. Saving a few clicks, presenting information more clearly, choosing a better default, or removing an unnecessary step may improve the application more than adding another major feature.

Using what I build reminds me that software development is not finished when the program produces the correct output. The experience surrounding that output matters. The user came to accomplish something, and every unnecessary action between the user and that outcome creates friction. When I am also the user, those unnecessary actions become difficult to overlook.

## Not Every Useful Tool Needs to Become a Product

There is another temptation that comes with building something useful: immediately wondering whether it should become a product. A tool solves my problem, and it becomes easy to start thinking about subscriptions, pricing tiers, landing pages, other users, and how it could become another business.

I am trying not to force that decision too early. Software can justify its existence simply by making my own work easier. If an application saves me time, organizes information better, removes a repetitive task, or gives me visibility into something I previously struggled to track, it is already producing value. It does not need thousands of users to prove that building it was worthwhile.

An internal tool can still grow into something larger. Using it myself may reveal that the problem is common enough to justify developing it for other people, but that is something I can discover through experience rather than assuming from the beginning. I would rather start with a genuine problem, build something useful, and allow broader possibilities to emerge than manufacture a business model around every repository I create.

## The Best Project Idea Might Already Be in My Day

If I needed another development project today, I would not begin by searching for a list of programming project ideas. I would look at my own routine and pay attention to the things I repeatedly do manually. I would look for the spreadsheet I keep updating, the information I repeatedly search for, the sequence of commands I keep typing, the data I manually move between applications, or the task that annoys me every week.

Those problems provide something generic project lists cannot: context. I already understand why the problem matters because I experience it. I know what the current process looks like, what frustrates me about it, and what a better outcome would look like. That gives me a starting set of requirements before I write the first line of code.

The first version does not need to be impressive, and it certainly does not need to use the newest framework. It needs to make the problem better. Once I begin using it, the weaknesses will become apparent, new requirements will emerge, and the project will provide plenty of opportunities to learn technologies and concepts that have an immediate purpose.

That is what I am finding increasingly valuable about building my own internal tools. I am still learning programming, architecture, databases, infrastructure, deployment, and all of the other pieces that come with developing software, but the education is attached to something I continue using after the experiment is finished. Instead of building another project that disappears when I have learned the lesson, I am building systems that become part of how I work.

The code teaches me something, but so does living with what I built.

## Community discussion

Top comments from developers on daily.dev.

**@eusebioleite** · 15 upvotes

> Thankfully i reached this conclusion sooner.

**@f4nt0** · 14 upvotes

> This days with the usage of AI to create software quicker it's mandatory to create software to help in day-to-day issues, if you are going to pay for all software created by companies you will loose more money than gaining into the development area. I've created my own homelab,documentation software, validation softwares to help me not be dependant for big companies.

**@fabooy961** · 6 upvotes

> ![GIF](https://static.klipy.com/ii/d7aec6f6f171607374b2065c836f92f4/f5/de/sDGGqYb4.gif)

**@webry** · 5 upvotes

> This is my favorite type of project

**@ristotoldsep** · 4 upvotes

> The best side project is the one that fixes your own annoying Tuesday.

## Similar posts on daily.dev

- [Why Every Developer Should Build a Personal Project](https://daily.dev/posts/why-every-developer-should-build-a-personal-project-9oinkt2nv) · Medium · 1 upvotes · 0 comments
- [The Developer I'm Grateful I Never Became](https://daily.dev/posts/the-developer-i-m-grateful-i-never-became-7rcp6jrje) · DEV · 57 upvotes · 2 comments

---

Tags: [#architecture](https://daily.dev/tags/architecture)

[View this post on daily.dev](https://daily.dev/posts/i-m-starting-to-think-every-developer-should-build-their-own-internal-tools-otvptdniq)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"DiscussionForumPosting","mainEntityOfPage":"https://daily.dev/posts/i-m-starting-to-think-every-developer-should-build-their-own-internal-tools-otvptdniq","headline":"I’m Starting to Think Every Developer Should Build Their Own Internal Tools","text":"Building internal tools for your own real problems teaches software development more effectively than generic practice projects. When you build something you actually use, requirements emerge from genuine needs rather than technology choices. This forces you to care about authentication, responsive design, deployment, error handling, and performance — the parts tutorials skip. It also creates a constant feedback loop since you are your own user, making friction and poor decisions immediately apparent. The approach helps recognize overengineering, lets the project dictate what to learn next, and produces software that continues to deliver value after the learning is done.","url":"https://daily.dev/posts/i-m-starting-to-think-every-developer-should-build-their-own-internal-tools-otvptdniq","datePublished":"2026-09-29T15:29:17.078Z","dateModified":"2026-09-29T15:31:27.758Z","author":{"@type":"Person","name":"John Liter","url":"https://daily.dev/jliter85","image":"https://media.daily.dev/image/upload/s--DQ2HUrO4--/f_auto/v1785100315/avatars/avatar_yHf9cPdgTQEtokv6d8qhM?_a=BAMAMicg0","description":"Retired 20 Year US Army Veteran.\nI Love Coding!\nLearning and then Teaching!","interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"EndorseAction"},"userInteractionCount":13180}},"image":"https://media.daily.dev/image/upload/s--rRnNtWR2--/f_auto/v1790695757/posts/oTVPTDNiQ?_a=BAMAMicg0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":254},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":55}],"comment":[{"@type":"Comment","text":"Thankfully i reached this conclusion sooner.","datePublished":"2026-09-29T15:48:00.139Z","url":"https://daily.dev/posts/oTVPTDNiQ#c-FV3RB3QWY","author":{"@type":"Person","name":"Eusébio Leite","url":"https://daily.dev/eusebioleite","image":"https://media.daily.dev/image/upload/s--ccQB46fi--/f_auto/v1789741448/avatars/avatar_VL9384KKhHkUpz2NoKYmL?_a=BAMAMicg0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":15}},{"@type":"Comment","text":"This days with the usage of AI to create software quicker it’s mandatory to create software to help in day-to-day issues, if you are going to pay for all software created by companies you will loose more money than gaining into the development area. I’ve created my own homelab,documentation software, validation softwares to help me not be dependant for big companies.","datePublished":"2026-09-29T16:00:01.050Z","url":"https://daily.dev/posts/oTVPTDNiQ#c-23j9nJewW","author":{"@type":"Person","name":"Gabriel Stundner","url":"https://daily.dev/f4nt0","image":"https://media.daily.dev/image/upload/s--UpSzkOxs--/f_auto/v1753488097/avatars/avatar_whNNg0ajcmne1B7hPHb0U?_a=BAMClqZW0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":14}},{"@type":"Comment","text":"","datePublished":"2026-09-30T06:57:11.981Z","url":"https://daily.dev/posts/oTVPTDNiQ#c-cogcloRRg","author":{"@type":"Person","name":"Le Fä De Le Lö","url":"https://daily.dev/fabooy961","image":"https://media.daily.dev/image/upload/v1677218265/avatars/avatar_H6lLM2y9S4Yf8VCWicpd8.jpg"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":6}},{"@type":"Comment","text":"This is my favorite type of project","datePublished":"2026-09-29T17:52:47.906Z","url":"https://daily.dev/posts/oTVPTDNiQ#c-rHBFVVsso","author":{"@type":"Person","name":"Samuel Braun","url":"https://daily.dev/webry","image":"https://media.daily.dev/image/upload/v1683105442/avatars/avatar_KjrWzAyEMnN7TAr8iPV9O.jpg"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":5}},{"@type":"Comment","text":"The best side project is the one that fixes your own annoying Tuesday.","datePublished":"2026-09-30T11:01:54.121Z","url":"https://daily.dev/posts/oTVPTDNiQ#c-FUPNBjMqX","author":{"@type":"Person","name":"Risto Tõldsep","url":"https://daily.dev/ristotoldsep","image":"https://lh3.googleusercontent.com/a/ACg8ocLDWc6mZn0JwNmXXw6WY0L_HJ6pegzRttooC5VgtXESHSj3MNYx=s96-c"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":4}}],"isPartOf":{"@type":"WebPage","url":"https://daily.dev/sources/yhf9cpdgtqetokv6d8qhm","name":"John Liter"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"John Liter","item":"https://daily.dev/sources/yhf9cpdgtqetokv6d8qhm"},{"@type":"ListItem","position":3,"name":"I’m Starting to Think Every Developer Should Build Their Own Internal Tools"}]}
```

