Pacific Blue Software Logo

Using Claude Code on a Delphi Project

Using Claude Code on a Delphi Project

Claude Code is an AI coding assistant that works in a folder on your machine. It reads the source, edits files and runs commands, such as the compiler. Most examples you will find are for Python or JavaScript, but it works well with Delphi once it knows the project's rules, can compile the code itself, and is kept away from the few files it handles badly.

This article covers that setup. For the limits worth setting first - databases, deployment, git - see What I Will Not Let an AI Coding Assistant Do.


Where It Helps


Setting Up on Windows

Claude Code runs natively on Windows 10 and 11 and installs from PowerShell without admin rights. Install Git for Windows as well: Claude Code then runs commands through Git Bash, and without it falls back to PowerShell. Start it in the project folder, or open the folder in the Claude desktop app.

Before each session, save everything in the IDE and commit. Git is the record of what the assistant changed and the way back if you do not like it.


Tell It the Rules: CLAUDE.md

Claude Code reads a file called CLAUDE.md at the start of every session and follows it as standing instructions. Rules that apply to all your work go in ~/.claude/CLAUDE.md (C:\Users\<you>\.claude\CLAUDE.md); rules for one project go in CLAUDE.md in the project folder. Keep each one short - under 200 lines - because every line is read every time.

Without one, it writes Delphi the way most Delphi code on the internet is written. If your style is different, say so. An example for a project:

# Order Manager - Delphi 12 Athens, VCL, Win64

## Build
- Build: run build.cmd. After every change, build and fix all errors
  and any new warnings or hints before saying a change is done.
- Tests: run Tests\Run_Tests.cmd.

## Code
- Delphi 12. Inline variables and generics are fine. No RTTI attributes.
- Identifiers Camel_Case with underscores: Load_Orders, not LoadOrders.
- Locals start with L, fields with F, parameters with A.
- No string literals shown to the user outside resourcestring.
- begin and end on their own lines; two-space indent.

## Files
- Do not edit .dfm, .fmx or .dproj files. If a form needs new
  components, list them and I will add them in the IDE.
- Keep source files ASCII. Use #$xxxx for other characters.
- Third-party source (TMS, FireDAC samples) is in E:\Lib - read it
  for reference, never change it.

## Database
- MySQL 8. Times are stored as UTC. The server is not on UTC.
- Never put a database name in SQL.

The most useful lines are the ones that correct a mistake you have seen it make. When it does something you do not want, add a rule; when a rule is never needed, remove it. /init writes a first draft from the project, which is a reasonable starting point to edit down.

Say which Delphi version you use. Models have seen Delphi code from every version since 1995 and will otherwise mix them - for example, avoiding inline variables a modern compiler accepts, or using RTL routines that do not exist in an older one.


Let It Compile

An assistant that cannot compile has to guess whether its code is right. One that can will read the compiler errors and fix them before it shows you anything. For a whole project, a small batch file in the project folder sets up the environment and calls MSBuild with the project's own settings:

@echo off
call "C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\rsvars.bat"
msbuild "%~dp0Order_Manager.dproj" /t:Build /p:Config=Debug /p:Platform=Win64 /v:minimal /nologo

Change 23.0 to your version's folder (37.0 for Delphi 13) and the platform to suit. For a single test program, the command-line compiler is quicker:

dcc64 -B -Q -NSSystem;Vcl;Winapi;Data Test_Split.dpr

Then tell it, in CLAUDE.md, to build after every change. Running the tests the same way closes the loop: it changes the code, compiles, runs the tests, and only reports back when they pass.


Where It Goes Wrong

Form files

A text .dfm or .fmx file can be edited like source, and the assistant will try. The trouble is that a form lives in two places - the form file and the class declaration in the unit - and the IDE keeps them in step, while an assistant editing text does not always. Common results are a property that the component does not have, an event handler name that does not match a method, or a component added to the form but not to the class. The form then fails to load at run time, not at compile time. Binary form files cannot be read at all.

Either keep it out of form files completely, as in the example above, or allow small edits and open the form in the IDE afterwards, which reports any property it cannot read.

Project files

The .dproj is rewritten by the IDE whenever a setting changes, and its structure - configurations inheriting from a base, conditions per platform - is easy to break. Search paths, defines and units added to the project should be changed in the IDE.

Files open in the IDE

The IDE holds its own copy of every open file. If you edit a unit in the IDE and the assistant edits the same unit on disk, one set of changes is lost, depending on which you keep when the IDE asks to reload. Save all before asking for changes, and reload when the IDE says a file has changed.

UTF-8 source without a BOM

This one is silent. Claude Code writes files as UTF-8 without a byte order mark. The Delphi compiler reads a source file without a BOM in the system's ANSI code page, so any non-ASCII character in a string literal is changed. Compiled on a Windows-1252 system:

const
  S = 'café —';

WriteLn(Length(S), ' ', IntToHex(Ord(S[4]), 4));

There is no error or warning. The program simply shows the wrong text. Avoid it by keeping source files ASCII and writing other characters as codes (#$00E9), by saving such files with a BOM, or by compiling with --codepage:65001. Check new files the assistant creates in particular, since nothing in the IDE marks them as different.

Your component libraries

It knows the VCL and RTL well, but third-party libraries less so, and it cannot know which version you have. When it guesses at a method that does not exist, give it the library's source folder to read, and say in CLAUDE.md where it is.


A Workflow That Works

  1. Save all in the IDE and commit.
  2. For anything bigger than a small fix, ask for a plan first. Claude Code's plan mode reads the code and proposes changes without editing anything; correct the plan before it starts.
  3. Let it make the change, build and run the tests.
  4. Read the diff - in your git tool or with the IDE's history view - before you commit. Look for changes you did not ask for.
  5. Reload changed files in the IDE, open any form it touched, and run the program.

Summary


Useful References


An AI Coding Assistant That Knows It Is Working in Pascal


Back to Articles for Developers
Back to Articles on AI
Back to Articles on Delphi
How to Call the Claude API from Delphi