I know, I'm late to the game. So many others have been using AI tools to quickly build software and I've been hesitant. I had my reasons.
- I was kind of scared to learn that AI was going to take my job. But burying my head in the sand is no way to deal with that.
- I tried it a few times, and the results weren't very good. But I didn't try too hard or for too long. I didn't learn how to operate the machine.
- I was distracted. I had a leadership job, and I was more focused on solving the people and coordination problems in front of me than learning a new tool.
- It seemed risky. I had to solve a bunch of problems that I knew how to solve in my usual way. Learning a new tool would be slower (I thought), and I didn't know whether I could trust the results.
But now that I've resigned from my previous leadership job and am getting ready to start a new one back in the engineer's seat, I knew it was time to give these tools a serious shot.
Picking My Project
I've long wanted to stand up a web presence to host my resume and other little webby projects that I've wanted to mess with. I've been paying Linode $5/month for a server to try to motivate myself, but I really haven't been doing anything with it. So I woke that old project up.
I wasn't starting from scratch. I started this project a few years ago, but got lost in the infrastructure of it. I had an old repo with the most basic Rust web application written using the Warp framework. I had a Dockerfile set up that builds the application, then embeds the resulting binary into an Alpine Linux image to have the smallest possible result.
I decided that I would use Anthropic's Claude chatbot for my project, and that the goal would be to wake the old project up, get it documented, and then get it published.
The biggest and scariest part was create a new structured website filling with content, and for it to not look horrible. I know how to make web pages from raw HTML and CSS, but that kind of UI fussing is not where I prefer to spend my time.
I had a smaller pet project in mind too - to make a very simple web-based list randomizer which can take the list to randomize as GET
parameters. random.org has a list randomizer, but it relies on the use of POST
data so there's no easy way to make a clickable link that results in a randomized list.
Getting Started
I decided to use Anthropic's Claude chatbot, and to just type every question I had into it.
I started by refreshing my memory. That project didn't build and run as expected and there was no README. Also, I was doing my work on an ARM Mac, but I knew my deployment target was an x86_64 machine. After asking Claude lots of questions, I learned that both docker run
and docker build
support the --platform linux/amd64
argument for this purpose. Also, it's important to configure Docker Desktop (or colima) to use Rosetta 2 and Virtualization.framework
instead of qemu for x86_64 emulation that's not painfully slow.
I also found myself asking Claude what many of the existing lines in my Dockerfile meant. I ended up removing many of them and writing something much simpler. Asking Claude for help here was faster and more effective than a Google search, or digging through the documentation pages myself.
Setting up SSL
I wanted to have a valid SSL cert for my site since that's the expectation these days, but I really didn't want to pay for one. So I asked Claude to set this up using Let's Encrypt. Claude provided a great answer, pointing me to the certbot tool and providing a script that was a decent starting point. I had to go and read the docs myself to finally get this all set up and working, but Claude's answer sped up the whole process.
Something from Nothing
Now for the big task. I asked Claude to build for me a personal website using Warp and a templating framework. Each page should have a common structure and display a navigation pane on the left side to navigate through pages of the site. I asked for a home page, a page to show off my personal projects, a blog, a page for my resume, and a page to host a searchable gallery of gifs and memes I've collected.
The results were remarkable. Claude selected Askama as the templating framework and made all of the pages I requested. It didn't have any information about me, but generated content for each of the pages that was totally made up. Since it was making the pages with Rust, Warp, and Askama, those were featured heavily in the project pages and the resume. There was also some other wild stuff it made up, like an analytics dashboard project, and a CLI task manager. But still, it was a decent starting point that allowed me to progress by editing rather than creating from a blank canvas. There was nothing amazing or novel created, but it was fast and reasonably complete. If I had done this myself, it would have taken hours or days. And I wouldn't have enjoyed it.
So I started editing with Claude:
- I fed my resume into the chatbot and asked it to rewrite the resume page, and refactor all the content out of the template. Success!
- I asked it to add a feature to the GIF gallery so that if you click on an image it would copy the URL to the clipboard. Success!
- I asked it to rewrite the projects page using my real projects (for which I provided GitHub links) instead of the ones it had originally made up. This was a half-success. One of my projects, WatchShopper, had only recently been made public, and there was no README. So it guessed what the app did and it was quite wrong. But that motivated me to write a README for that project, which I fed into the chatbot and asked it to rewrite that project content again. Success!
- I asked it to rewrite the home page based on the content of the resume and the projects, and also based on a brief description of my career focus over the past 15 years. It did a pretty good job.
- The blog feature that was originally written was half-baked, so I asked it to complete the job. Pages for individual blog posts need to work, and content needs to be factored out of the templates. The change here was remarkable again. The refactoring was quite extensive, and Claude chose to bring in a Markdown framework to handle complete blog post content. There were lots of compile errors after this, which required some human debugging but Claude helped too when I fed the error messages in and requested a fix.
- The resulting pages sometimes included rounded rectangles nested to a comical degree. I requested the flattening of some of these and Claude obliged.
As part of the blog feature refactoring, Claude wrote a whole article itself, which I'll link to here: Building a Personal Website with AI, Rust and Warp. That article is well-written, pretty, and enthsiastic. But it's not the article I wanted to write. It's gushing about using Rust, Warp, and Askama. But for me, the interesting part is that I focused on asking for the results I wanted, and Claude provided.
There were some stumbles along the way. Sometimes Claude would tell me it had made a change that it hadn't. The best example was when I requested that the blog post content not be constrained to a fixed width. Claude said: "I'll remove the <article>
tag and the fixed-width CSS." But the resulting code still used both. When I called this out it corrected the mistake and was perhaps overly apologetic. Then I asked why it chose to use <div>
instead of <article>
, and it acknowledged that <article>
was the better choice for this content, and only the fixed-width style needed to be removed. I learned that sometimes when I ask for changes, Claude would take it a few steps further and make additional changes I didn't ask for.
Reflections
The results were not perfect. They still aren't. But I made progress much more quickly than if I had hand-crafted every line of code. I'm a results-driven person, so I'm happy with the results so far because they're accomplishing my goals without taking up too much of my time. And it's really satisfying to me that I can get something working, but also feel confident that it can be refactored as needed to make it better.
The mantra I picked up from Swift over Coffee is "Make it work, make it fast, make it right". Claude definitely speeds up the first step, but also the other two. As long as I provide the initial guidance, but also as long as I verify the work. Claude's results do often feel like those of a very fast intern with a tremendous amount of knowledge, but without much wisdom for how to use the tools in the best way, or that keeping things simpler is better. Maybe I just need to learn how to write better prompts, and configure a default starting context.
The lack of retention is a problem. Since I started uploading code files as part of my requests, I found myself quickly hitting the limits offered by the free offering. I finally upgraded to the Pro offering and that helped. Also, it's pretty annoying to keep uploading portions of my project with my requests and copying the resulting code back down.
What's Next
All in all, I regard this attempt as a success. I had a great experience, and it got better as I learned how to use the tool, how to ask for the right things. I will continue to use Claude and other AI tools to help build, edit, and refactor. I expect I will get the best results when I know exactly what I need, but there's just a big chunk of boring work ahead of me. I also expect tools like this to be helpful in creating poorly-described prototypes that will help me collect my thoughts and later get edited into something good.
I'm not worried about my job going away. For years, my job has been a lot more about understanding what the problem is and describing it than it has been about writing the code. That's what's needed to use these tools. The other big part of my job has been understanding and debugging problems. I'm sure I'll still be spending a large portion of my time reading code and tracing through data flow to find and fix problems.
I'm still worried about the risk. About not being able to trust the results. But that's true of the code I or anyone else writes too. I have to try it, test it, look at it, give feedback. Building software is always an iterative process. It looks like AI tools can speed up some of the iterations.
I need to dig into coding agents next. I expect that'll help me move even faster since I won't be wasting time ferrying the code input to the chatbot and the output back out to my editor or filesystem. Coding agent tools like Cursor, Augment, or Windsurf don't seem to work well with my preferred coding environments, so I need to go meet them where they are. I'm excited to try!