People ask what I work with, and I still answer with a list. PHP, Laravel, Filament, a bit of Go, C when the job is a binary. The list is not wrong. It is also not the work. The work is the part that never fits in a badge: a panel that has to match how an office actually moves paper, a payment that has to clear on a gateway the tutorial never mentions, a small tool I wrote because I was tired of doing the same thing by hand.

I live in Pokhara. I have been building software long enough that the first things I shipped are embarrassing in the useful way. Forms. Pagination. Attendance. A task list. None of that was a product. It was the period where I learned that a program is finished when someone else can use it without me sitting next to them, not when it runs on my machine.

The unglamorous years were the real ones

I started close to the metal of the web, which for me meant PHP without a framework doing the heavy lifting. Validation, pagination, a starter layout I copied forward until I understood why the folders existed. It felt slow. It was. I could see every request. When something broke, there was nowhere for the bug to hide except the file I had just written.

That habit never really left. I still want to know which layer owns a problem. Laravel is home now because it is where the applications I care about live: admin panels, records, permissions, queues, the boring machinery of a business. Filament and Livewire sit on top of that when the person using the software is not a developer and should not have to be. I did not adopt them because they were current. I adopted them because a week of panel work was disappearing into selects, tables, and filters I had already built twice.

C showed up for a different reason. I wanted to know what I was skipping. Games, small utilities, a timer, a tool that diffs two .env files and refuses to edit them without a backup. Sixteen repositories of C is not a career change. It is how I stop the high-level stack from becoming superstition. If I cannot explain a file, a process, or a socket without reaching for a framework word, I go write the small version until I can.

Go landed in the same gap. I needed to hand a file to another machine on the same network without uploading it anywhere. A short CLI that serves the paths you pass it was enough. Password if you want one, port if 8092 is taken. I still reach for that shape when the artifact should be one binary and a help screen.

Tutorials stop at the border

A lot of what I learned from other people's posts did not survive contact with the work in front of me. The examples assume Stripe, or a user model with two roles, or a status field that is just a string. The systems I touch are more specific than that.

Payments were the clearest case. If the checkout has to be eSewa or Khalti, an international guide is a story about a different country. I wrote small PHP SDKs for both so an application could configure the amount, the return URLs, and the transaction, then read the gateway's answer back, without dragging a whole framework along for a form post. The lesson was not the SDK. The lesson was that "integrate payments" is not a universal task. It is a local one, and the local one is the one the user is actually trying to pay.

The same thing happens inside admin panels. A status dropdown looks like a solved problem until a reviewer and an author are looking at the same record and must not be offered the same moves. I have written about that separately, because it grew into its own package. The experience under it is older: most of the defects I ship are not crashes. They are legal moves the screen offered and the rest of the system never planned for.

I also got tired of documentation that needed a documentation platform. I wanted Markdown, more than one version, a sidebar from the folder tree, and a search box. That became a JavaScript tool with a create script, which is the least PHP-shaped thing I maintain. I use it when the thing being built is the reading experience itself. I do not use it to avoid writing the docs.

What I stopped collecting

For a while I treated every new library as progress. Another frontend framework, another state manager, another way to say "component." Some of that was useful. React and Alpine and Tailwind are in the kit because interfaces still have to be built. NestJS is there when the API is its own service and PHP is the wrong host. Flutter showed up when the question was who may do what inside a mobile UI, which is the same question I keep meeting on the server, just with widgets.

The collection slowed down when I noticed I was learning names instead of seams. A seam is the place two parts meet: the form and the database, the panel and the permission, the request and the gateway, the CLI and the file. If I can draw that line, the library is a detail. If I cannot, a new library makes the line harder to see.

So the filter I use now is dull. Does this remove a kind of work I already repeat, or does it add a kind of work I will have to remember? Filament plugins I publish tend to pass that test: notifications, comments, workflows. A chart library passes it when embedding a graph should not mean inventing a canvas API on a Thursday. A file watcher passes it when restarting a process by hand has become the bottleneck. A feature-flag package for Flutter passes it when if statements in widgets have started to mean policy.

Things that fail the test sit in old repositories and teach me what I was curious about that month. I do not delete them. Curiosity is part of the job. I just try not to call curiosity a product.

How a week actually goes

Most weeks are not a new repository. They are a model that grew a column, a report someone needs before a meeting, a permission that was fine until a second office started using the same panel. The skill that matters there is not a framework. It is sitting with the person who does the job and writing down the sentences they already use. "A clerk can submit. A manager can approve if the amount is under this. Nobody deletes." Those sentences are the specification. The enum, the policy, and the screen are translations.

I write the translation as close to those sentences as I can. If the rule is stable and universal, it belongs in code, where a test can hold it still. If the rule changes by role, or by a number someone in the office owns, it belongs where they can see it without a deploy. I have been wrong in both directions. Hard-coding a threshold that operations needed to change every month made me the bottleneck. Putting a structural rule in a settings screen made the screen a second programming language nobody wanted to learn.

Reviews, when I get them, are about that choice more than about style. I would rather be told the road is wrong than the naming is. Naming still matters. A status called done that means three different things will outlive every refactor.

I keep notes when something surprises me. A gateway field that is not the field the docs name. A cast that makes an enum and a string compare unequal. A select that hides an option and still accepts it from a crafted request. Those notes are the only reason I trust myself on the next project. Memory is worse than I want it to be, and production is a better teacher than I am, provided I write the lesson down before I feel clever again.

Pokhara is not a constraint I perform

I am not interested in the essay where a developer outside Kathmandu or Bangalore explains that the internet works here too. It does. The interesting part is the work that is specific to where the users are. A payment gateway. A fiscal habit. A language the panel must speak. A file that has to move across an office LAN because the cloud upload is the long way around. Those details are the product. The stack is how I stop them from becoming a mess.

Working from here also means a lot of the day is quiet. I read more than I post. I would rather ship a small package with a real README than keep a streak. When I do write, I want it to be something I can still agree with a year later: what the problem was, what I refused to build, and the rule I am trying to keep.

The rule, for now

Learn the boring path until you can see it. Use a framework when the boring path is long enough to be dangerous to copy. Drop down a level when the framework word is hiding the mechanism. Prefer a tool that deletes a repeated chore over a tool that adds a concept. Write the rule in the place the person who owns the rule can find it.

The list of technologies will keep changing. PHP is still the language I reach for first, because it is the one my projects are already speaking. That is not loyalty. That is where the seams are. The experience worth keeping is the set of seams I have already crossed badly once, and the hope that I cross them less badly the next time.