In which Claude and [A]I play at being webdevs. For some reflections on the bigger picture of AI as a productivity tool for developers, have a look at the companion post to this one.
I used to speak at a lot of conferences and meetups, and published my talks on a site called noti.st.
Itโs free to use, but you could pay for bells and whistles including a custom domain, which I duly did: talks.rmoff.net.
My background is databases and SQL; I can spell HTML (see, I just did) and am aware of CSS and can fsck about in the Chrome devtools to fiddle with the odd detailโฆbut basically frontend webdev is completely beyond me. That meant I was more than happy to pay someone else to host my talks for me on an excellent platform.
This was a few years ago, and the annual renewal of the plan was starting to biteโover ยฃ100 for what was basically static content that I barely ever changed (Iโve only done three talks since 2021). So I decided to see what Claude Code/Opus 4.5 could do, and signed up for the ยฃ18/month "Pro" plan.
The way Claude Code works is nothing short of amazing. You use natural language to tell it what to doโฆand it does it.
I started off by saying to (prompting) it with something like this:
I would like to migrate my noti.st-based site at https://noti.st/rmoff/ to a static site like my blog at rmoff.net which is built on hugo.
| What I actually said is kinda irrelevant, because itโs not precise. It doesnโt care about typos; it captures the intent. |
Claude Code then poked around the two sites and probably asked me some questions (did I want to import all content, what kind of style, etc), and then spat out a Python script to do a one-time ingest of all the content from noti.st. After seeking permission it then ran the Python script, debugged the errors that were thrown, until it was happy it had a verbatim copy of the data.
Along the way itโd report in on what it was doing and I could steer itโmuch the same way you would a junior developer. For example, on noti.st a slide deckโs PDF is exploded out into individual images so that a user can browse it online. This meant a crap-ton of images which I didnโt care about, but Claude Code assumed I would so started grabbing them.
Claude then proceeded to build and populate a site to run locally. There were plenty of mistakes, as well as plenty of yak-shaving ("hmm can you move this bit to there, and change the shade of that link there"). This can be part of the danger with Claude. It will never roll its eyes and sigh at you when you ask for the hundredth amendment to your original spec, so itโs easy to get sucked into endless fiddling and tweaking.
I found I quickly burnt through my Pro token allowance, which actually served well as a gatekeeper on my time, forcing me to step back until the tokens were refreshed. After four early morning/late nights around my regular work, I cut over my DNS and you can see the results at https://talks.rmoff.net/.
The key things that Claude Code did that Iโd not been able to get ad hoc chat sessions (or even Cursor) to do last year include:
-
Planning out a full project like this one, from the overview down to every detail
-
Talking the talk (writing the code) and walking the walk (independently running the code, fixing errors, evaluating logic problems, etc)
-
Rapidly iterating over design ideas, including discussing them and not just responding one-way to instructions
-
Discussing deployment options, including working through challenges given the cumulative size of the PDFs
-
Explaining and building and executing and testing the deployment framework
Before the sceptics jump in with their well, ackchuallyyy, my point is not that I couldnโt theoretically have done this without Claude.
Itโs that it took, cumulatively, perhaps eight hoursโand half of that will have been learning how to effectively interact with Claude.
Itโs that itโs a single terminal into which one types, thatโs it.
No explosion of tabs.
No rabbit-holes of threads trying to figure this stuff out.
One place.
That fixes its own errors.
That writes code that you could never have done without a serious investment of time.
Would I apply for a frontend engineering job? Heck no!
Does my new site stand up to scrutiny? Probably not.
Will real frontend devs look at the code and be slightly sick in their mouths? Perhaps.
Does this weaken my point? Not in the slightest!
ยฃ18-worth of Claude Code (less, if you pro-rata it over the month) and Iโve saved myself an ongoing annual bill of ยฃ100, built a custom website that looks exactly as I want it, has exactly the functionality that I wantโoh, and was a fuck-ton of fun to build too :)
Does it matter that I didnโt write the code and donโt understand it? ๐
Not whilst I have access to Claude ;)
I realise that in reading this the choler will be rising in some seasoned software engineers. After all, who is this data engineer poncing around pretending to build websites?
And thatโs perhaps the crux of it: Iโm a data engineer, branching out into something I couldnโt do before, courtesy of Claude.
I would definitely use Claude to help me write SQL queries and generate DDL, but Iโd be damned if Iโd put my name to a pull request with a single byte of code that I couldnโt explainโbecause thatโs my job.
I like Oxideโs words here:
However powerful they may be, LLMs are but a tool, ultimately acting at the behest of a human. Oxide employees bear responsibility for the artifacts we create, whatever automation we might employ to create them.
So I can have fun building a website thatโs just my personal site and only on me if it fails. But if Iโm writing code as a professional for my job, itโs on me to make sure that itโs code I can put my name to.
Claude tips ๐
There is a lot written about Claude Code. Some of it cargo-culting, some of it frothy-hype nonsense. Below Iโve listed out some of my 'top tips' that Iโd be passing onto a colleague getting into Claude Code from scratch tomorrow.
Playwright ๐
If youโre doing any kind of webdev work, follow Kris Jenkins' tip and use Playwright so that Claude can "see" as it develops. You can manually take screenshots and paste those into Claude too if you want (including ones youโve annotated with observations and instructions) but in general and particularly for regression testing, Playwright is an excellent addition.
Because this is Claude, you donโt need to actually know how to configure Playwright or run its tests, or anything like that. You just tell Claude: "Use Playwright to test the changes". And it does. Oh, and itโll install it for you if you donโt have it already.
๐๏ธ Ding Dong ๐ ๐
Claude will sometimes ask for permission to do something, or tell you itโs finished its current task.
If youโve got it sat in a terminal window behind your other work you may not realise this, so adding a sound prompt can be useful.
In your ~/.claude/settings.json include:
"hooks": {
"Notification": [ {
"hooks": [ { "type": "command", "command": "afplay /System/Library/Sounds/Funk.aiff" } ] } ],
"Stop": [ {
"hooks": [ { "type": "command", "command": "afplay /System/Library/Sounds/Ping.aiff" } ] } ] },
Obviously, you can waste a lot of time customising it to use just the right sound effect from your favourite 1980s arcade game.
| You might not want to always do this; see my observation above about context switching and continuous interruptions. |
Keep an eye on cost ๐
Depending on how you pay for Claude (fixed plans, or per API calls) youโll discover sooner or later that it can be quite expensive.
You can include the cost of the current session in the status line by adding this to the same config file as above, ~/.claude/settings.json:
"statusLine": {
"type": "command",
"command": "input=$(cat); cwd=$(echo \"$input\" | jq -r '.workspace.current_dir'); tin=$(echo \"$input\" | jq -r '.context_window.total_input_tokens'); tout=$(echo \"$input\" | jq -r '.context_window.total_output_tokens'); mid=$(echo \"$input\" | jq -r '.model.id'); mname=$(echo \"$input\" | jq -r '.model.display_name'); used=$(echo \"$input\" | jq -r '.context_window.used_percentage // \"--\"'); if [[ \"$mid\" == *\"opus\"* ]]; then cost=$(echo \"scale=4; ($tin * 15 + $tout * 75) / 1000000\" | bc); elif [[ \"$mid\" == *\"haiku\"* ]]; then cost=$(echo \"scale=4; ($tin * 0.80 + $tout * 4) / 1000000\" | bc); else cost=$(echo \"scale=4; ($tin * 3 + $tout * 15) / 1000000\" | bc); fi; printf \"\\e[36mโ\\e[0m \\e[1m\\e[96m%s\\e[0m \\e[36mโ\\e[0m \\e[35m%s\\e[0m \\e[36mโธ\\e[0m \\e[33mTokens:\\e[0m \\e[32m%'d\\e[0mโ \\e[34m%'d\\e[0mโ \\e[36mโ\\e[0m \\e[93mCtx Used:\\e[0m \\e[92m%s%%\\e[0m \\e[36mโ\\e[0m \\e[1m\\e[31mCost: \\$%s\\e[0m\" \"$mname\" \"$cwd\" \"$tin\" \"$tout\" \"$used\" \"$cost\""
},
Itโll look something like this:
Also check out ccusage which uses the Claude log data to calculate usage and break it down in different ways which can help you optimise your use of it.
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ Claude Code Token Usage Report - Weekly โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโ
โ Week โ Models โ Input โ Output โ Cache โ Cache Read โ Total โ Cost โ
โ โ โ โ โ Create โ โ Tokens โ (USD) โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโค
โ 2026 โ - claude-3-5-haiku โ 39,694 โ 80,640 โ 4,462,577 โ 28,392,013 โ 32,974,924 โ $26.35 โ
โ 01-25 โ - sonnet-4-5 โ โ โ โ โ โ โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโค
Learn a bit about the models (ask Claude) ๐
Different Claude models (Opus, Sonnet, Haiku) cost different amounts, and you can optimise your spend by learning a bit about their relative strengths. I found that asking Claude itself was useful; using Opus (the most capable model) you can describe what youโre going to want it to do, and which model it would recommend. Like all of this LLM malarky, none of it is absolute, but I found its recommendations useful (i.e. the models it recommended were cheaper and did achieve what I needed them to).
Think of it as having different pairs of running shoes in your closetโdifferent ones are going to be suited to different tasks. Youโre not going to wear your $200 carbon-plate running shoes to kick the ball around the park, are you?
Master the tooling ๐
Go read up on things like:
-
Context windowsโwhat the LLM knows about what youโre doing
-
Context rotโthe more thatโs in the LLMโs context window, the less effective it can sometimes become
-
CLAUDE.mdโwhere Claude makes a note of what it is youโre building and core principles, toolsets, etc-
You can get a lot of value by spending some time on this so that you can restart your session when you need to (e.g. to clear the context window) without having Claude 'forget' too much of the basics of what youโve told it
-
Work with Claude on this fileโliterally say, look at your CLAUDE.md, I have to keep telling you to do x, how can you remember it better. If you give it permission, itโll then go and update its own file
-
-
Use plan mode and accept-change (shift-tab) judiciously. If you just YOLO it and accept changes without seeing the plan youโll often end up with a very busy fool going in the wrong direction. Claude is your servant (for now) and itโs up to you to boss it around firmly as needs be.
-
Watch out for Claude spinning its wheelsโif you see it trying to repeatedly fix something and getting stuck you might be burning a ton of tokens on something that itโs misunderstood or doesnโt actually matter
Claude Code is not just about churning out code ๐
Iโve been experimenting with a few non-coding examples, both pairing Claude with basic-memory and an Obsidian vault.
-
Proofreading my blog (hereโs the prompt, if youโre interested; PRs welcome ๐).
I also have a Raycast AI Preset to do this, but am finding myself more and more reaching for Claudeโs terminal window. It works well because I write my blog posts in Asciidoc, which Claude can read and edit directly (if I ask it to). Claude can also help you write the prompt/skillโI gave it verbatim some feedback I got from a real human being on the initial version of this post, and it distilled that into what it ought to check for next time and updated its skill. Neat.
-
Planning a holiday. Iteratively building up with Claude a spec that captures the requirements of the holiday, it can then help with itineraries, checklists, discuss areas, etc etc. As with the coding project above, it being one window with which to interact is really powerful.
-
Acting as a running coach. Plugging in Garmin and Strava data via MCP I can capture all of my running and health info, and discuss with Claude planned workouts, even weaving in notes from past physio appointments. Obviously I am not following it blindly but as an exercise (geddit?!) in integration and LLMs, itโs pretty fun.
ButโฆbutโฆAIโฆ ๐
This post may well have you spitting coffee into your cornflakes, I realise that. For some reflections on the bigger picture of AI as a productivity tool for developers, have a look at the companion post to this one.