Vibe Coding on IBM i
Can AI tools be used to independently create classic software that runs natively on the IBM i system?
Vibe Coding on IBM i
Artificial intelligence tools are rapidly gaining popularity and achieving very strong results when working with commonly used programming languages such as Python or JavaScript.
However, an important question arises: can AI tools be used to independently create classic software that runs natively on the IBM i system, within the 5250 terminal environment?

In this article, I attempt to answer that question. Instead of writing the code myself, I will rely on descriptions and instructions, using Claude Code — an AI coding agent — to create software according to my guidance. In situations where the tool encounters difficulties or becomes stuck at a particular stage, I will provide precise, technical hints that allow it to continue its work.
Let us test this approach using a simple but representative example. The goal will be to create a data dictionary and an interactive program that enables browsing and maintenance of that dictionary, running natively in the IBM i environment.
Getting Started
At the outset, I created a new code repository and then added a README.mdfile describing the expected behavior of the program. Below is the complete description:
# IBMi-AI
An application for maintaining a dictionary of financial instruments
The financial instruments dictionary has the following attributes:
* ISIN code – uniquely identifies the instrument
* instrument short name
* issuer name
* issue date
* country of issue
* issue currency
* issue size
The financial instruments dictionary is stored in a database.
## Program
A program running in the 5250 terminal is available for browsing the data; it presents the list of instruments in subfile. The list is sorted by ISIN code. The following columns are displayed in the list:
* ISIN code
* instrument short name
* issuer name
* issue date
* country of issue
* issue currency
The user can browse the list by scrolling down and up using PgUp and PgDn.
## Options
The following **actions** are available in the program:
* F3=Exit – Exit the program
* F6=Add – Create a new instrument in the dictionary
For each selected item in the list, the following **options** are available:
* 2=Edit – Edit the instrument in the dictionary, without the ability to change the ISIN code
* 4=Delete – Remove the instrument from the dictionary
* 5=Details – Display all details of the instrument
Information about the list of available **actions** is displayed in the line below the list of instruments. Information about the list of available **options** is displayed in the line above the list of instruments.
## Infrastructure
* Server: IBM Power
* System: IBM i 7.5
* Database: IBM DB2 for IBM i
As can be seen, the documentation contained in the README.md file covers:
- the scope of information to be stored in the data dictionary,
- the expected functionality of the program,
- an indication of the infrastructure on which the developed software is intended to run.
In practice, the README.md serves as a functional contract between me and the AI tool — it is the sole source of knowledge on the basis of which the agent generates the solution structure and the code.
To carry out this task, I use Claude Code launched directly within the Visual Studio Code environment, treating it as an active participant in the software development process rather than merely a supporting tool.

The First Prompt
The first prompt directed to the tool was as follows:
Write the required software according to the description. Also add a Makefile so that on IBM i, in PASE, this repository can be cloned into a directory and fully compiled using
make all. In the Makefile, useSHELL = /QOpenSys/pkgs/bin/bashand also add.ONESHELLto preserve the context of successive system command invocations. Useliblistto set the appropriate library when compiling objects.
I therefore instructed the tool not only to create the software itself, but also to prepare a complete build process. I additionally included several technical suggestions which — based on experience — significantly improve the quality of the initial result and help the AI agent correctly “establish the context” of the IBM i environment from the very beginning.
Claude Code independently creates and modifies files directly within the repository. As a result of executing the above instruction, the following file structure was generated.

Created files:
- fininst.sql — an SQL script that creates the database table along with field descriptions. Appropriate data types were correctly selected for the columns.
- fininstd.dspf — a definition of 5250 display screens, including a data list, an add-record screen, a delete confirmation screen, and a details screen.
- fininstr.sqlrpgle — program code written in RPG using full free-format.
- fininstmsgf.txt — a file containing the definition (source pseudocode) of a message file along with a list of messages. The
Makefiledefines a procedure for generating the actual*MSGFobject based on this source. - Makefile — a set of commands compiling all objects, including library creation as well as clean and rebuild operations for the project.
The initial impression is very positive: the generated code appears complete, consistent, and aligned with the assumptions described in the README.md file.
Compilation
In the next step, I verify whether the generated code actually compiles. I transfer the repository to the IBM i system and start the build process using the command:
make all
The first compilation attempt fails. I record the errors from the build process in a file named errors.txt. Subsequent errors will be captured in the same manner in later commits within the repository, making it possible to trace them step by step at a later stage.
*FILE
In this case, the problem occurred in the generated SQL statement that creates the data table:
4 CREATE OR REPLACE TABLE FININST (
5 FIISIN CHAR(12) NOT NULL WITH DEFAULT '',
6 FISHRTNAM CHAR(35) NOT NULL WITH DEFAULT '',
7 FIISSUER CHAR(50) NOT NULL WITH DEFAULT '',
8 FIISSUEDT DATE NOT NULL WITH DEFAULT CURRENT_DATE,
9 FICOUNTRY CHAR(2) NOT NULL WITH DEFAULT '',
10 FICURRENCY CHAR(3) NOT NULL WITH DEFAULT '',
11 FIISSUESZ DECIMAL(15,2) NOT NULL WITH DEFAULT 0,
12 PRIMARY KEY (FIISIN)
13 );
The system reported the following error:
MSG ID SEV RECORD TEXT
SQL0104 30 11 Position 25 Token ( was not valid. Valid tokens: ) ,.
The cause is straightforward and well known to DB2 for i users: the DECIMAL type definition is missing a space after the comma. Instead of correcting the code manually, I decided to check whether the AI tool would detect the issue on its own based on the error message and propose an appropriate fix.
My next prompt was:
There are errors in compilation, they are recorded in the errors.txt file.

Claude Code correctly interpreted the error message, identified the problematic fragment of code, and pointed out the line containing the invalid syntax. However, the proposed fix did not fully resolve the issue. Nevertheless, I accepted it and ran the compilation again to observe how the tool would respond to further feedback.
As expected, the error persisted.
The next prompt was:
The change did not help, there are still errors — recorded in the errors.txt file.

This time, the agent noticed the formatting problem in the numeric type definition and corrected it in a manner consistent with DB2 for i requirements. At the same time, it changed the column type from DECIMAL to NUMERIC. Although the type change was not strictly necessary, it proved to be functionally neutral and resulted in the table being created successfully.
The final outcome was positive: the table was created without errors, and the compilation process was able to proceed to subsequent stages.
*MSGF
After resolving the error in the table definition, further compilation issues appeared, this time during the creation of the message file.
The system reported the following error:
CPD0074: Value 'FININSTMSG' for MSGF exceeds 10 characters.
The cause is unambiguous: the proposed object name exceeds the maximum allowed length of 10 characters, which applies to object names on IBM i.
As before, the next prompt was very general:
There are errors in compilation, they are recorded in the errors.txt file.

Claude Code correctly diagnosed the problem and introduced the required changes. Importantly, the fixes were not limited to the message file definition alone — the tool also automatically updated the program code that references this object, preserving naming consistency across the entire solution.
After these changes, the *MSGF object was created successfully, and the compilation process was able to continue.
*DSPF
Further errors occur during the compilation of the display file:
Compiling display file FININSTD...
CPC2196: Library IBMIAI1 added to library list.
CPD0043: Keyword SRCSTMF not valid for this command.
CPF0006: Errors occurred in command.
make: *** [Makefile:67: dspf] Error 255
Analysis of the message points to a problem in the Makefile. The CRTDSPF command was invoked with the unsupported SRCSTMF attribute. Unlike many other object types, display files cannot be compiled directly from IFS sources — the compilation requires a source member in a source physical file.
Once again, I applied the same general prompt:
There are errors in compilation, they are recorded in the errors.txt file.

Claude Code correctly identified the root cause and introduced appropriate fixes to the build process: the display source was copied into a source member and then used for compilation.
Despite this, the display file still did not compile successfully. This time, the problem lay directly in the screen definition itself.
The first issue was incorrect positioning of certain attributes, for example the field SFISSUEDT:
A R LISTSFL SFL
A SFOPT 1A B 8 2VALUES(' ' '2' '4' '5')
A SFISIN 12A O 8 5
A SFSHRTNAM 20A O 8 19
A SFISSUER 20A O 8 41
A SFISSUEDT 10A O 8 63
A SFCOUNTRY 2A O 8 75
A SFCURRCY 3A O 8 78
Some fields extend beyond the permissible row width or violate formatting rules, resulting in compilation errors.
The second issue involved overlapping screen fields, as confirmed by the message:
* CPD7866 10 2 Message . . . . : Field overlaps another field with no conditions specified.
Once again, I used the same minimalist prompt:
There are errors in compilation, they are recorded in the errors.txt file.

The errors were correctly identified, and the screen definition was corrected. After applying these changes, the display file compiled successfully without errors.
*PGM
The final errors appear during the compilation of the RPG program.
The root cause is an inconsistent definition of the SendMsg procedure. The code contains a prototype declaration without parameters:
dcl-pr SendMsg end-pr;
and an implementation of the procedure that accepts a parameter:
dcl-proc SendMsg;
dcl-pi *n;
msgId char(7) const;
end-pi;
Such a mismatch between the prototype and the implementation results in compilation errors.
Once again, I used the same general prompt:
There are errors in compilation, they are recorded in the errors.txt file.

Claude Code correctly identified the issue, unified the procedure definition, and introduced the required fixes in the code. After these changes, the program compiled successfully.
Compiled Objects
After going through all compilation stages and iteratively fixing the errors, the complete set of objects was successfully created in the IBMIAI1 library.

At this point, the library contains all required artifacts: the database table, the message file, the display file, and the RPG program. This means that the build process has completed successfully, and the application is ready for its first execution and testing in the 5250 environment.
Execution
After compiling all objects, I proceed to run the program. Unfortunately, the application does not start correctly — errors appear immediately upon invocation.
The system reports the following messages:
> CALL PGM(IBMIAI1/FININSTR)
Cannot process subfile request for file FININSTD in library IBMIAI1.
? C
Session or device error occurred in file FININSTD.
Application error. RNX1255 unmonitored by FININSTR at statement
0000000172, instruction X'0000'.
To analyze the problem, I once again use the AI tool, providing it with the relevant information via the following prompt:
Errors were reported when the program was launched — you will see them in the errors.txt file

Claude Code interpreted the error as an attempt to perform an operation on an empty subfile and introduced changes to the subfile handling logic as well as to the message subfile processing.

Despite these corrections, the problem persisted and the program still failed to start properly.
In the next step, I launched the debugger to precisely locate the source of the error. The analysis pointed to line 107 in the main procedure. I conveyed this information in the subsequent prompt:
The error still persists. After running the debugger, the error appears on line 107, “write MSGCTL” in the Main procedure.

Based on this input, the tool introduced further corrections in the program code.

This time, the changes proved effective — after applying them, the program started successfully.

Testing
After successfully starting the application, I proceed to test the individual functional options.
F3=Exit
According to the assumptions, the F3 function key should terminate the program. In practice, however, selecting this option causes the application to stop with an error:
> CALL PGM(IBMIAI1/FININSTR)
Message key and messages to remove are mutually dependent.
Application error. CPF24AE unmonitored by FININSTR at statement
0000000848, instruction X'0000'.
Once again, I prepared a prompt containing the most precise diagnostic information possible:
The program starts, but an error occurs after selecting option F3 — see the errors.txt file. The debugger shows that the error occurs when executing line 585, i.e.
QMHRMVPM(‘*’:0:’*ALL’:’*ALL’:errorCode);in theClearMsgprocedure.

Based on this information, the tool correctly identified the issue in the call to the QMHRMVPM API and introduced the appropriate corrections in the ClearMsg procedure. After applying these changes, the F3 option works as expected and the program terminates cleanly.
F6=Add
The next tested scenario is the F6 option, which is used to add a new entry to the dictionary.
The F6 option presents a clean and readable window with a form for adding a new instrument.

From the form, it is possible to return to the list using the F3 key. The validation logic works correctly — the program enforces completion of all required fields.
After the form is confirmed, the new instrument is correctly saved to the database table. Unfortunately, immediately after this operation the program once again stops with an error:
> CALL PGM(IBMIAI1/FININSTR)
Instrument added successfully.
Cannot process subfile request for file FININSTD in library IBMIAI1.
? C
Session or device error occurred in file FININSTD.
Application error. RNX1255 unmonitored by FININSTR at statement
0000000174, instruction X'0000'.
As before, I delegated the analysis of the problem, providing additional information from the debugger:
The program starts, but an error occurs after executing the F6 option — see the errors.txt file. The debugger shows that the error occurs when executing line 109, i.e.
write MSGCTL;in theMainprocedure.

Despite the introduced changes, the error persisted. The next prompt refined the observation:
The error still occurs in the same place. It seems that the MSGCTL display doesn’t work correctly when an MSG was actually sent via the SendMsg function.

The problem was still not resolved. At this point, it became clear that the cause was not a single instruction, but an incorrect definition of the message subfile (MGGSFL) in the display file.
In subsequent iterations, I repeatedly used prompts indicating that the proposed changes were ineffective:
The error still occurs in the same place. Could this be related to the PGMQ and MSGPGMQ variables in DDS?
It didn’t help. Shouldn’t these two fields be one field?
Still not working.
Still not working.
At that stage, Claude Code searched sources available on the web for examples of correct message subfile implementations and proposed a series of further modifications.
None of these changes produced an immediate result. Only after pointing out the missing element:
PGMQ initialization is missing.
did the tool introduce the correct fix. Once PGMQ was properly initialized, the message subfile definition began to function correctly, and the F6 option stopped generating errors.
Final outcome: adding a new entry now works correctly from start to finish.
2=Edit
The edit option works as intended.
The same form used for adding a new instrument is displayed, with the difference that the ISIN field is locked for editing. This behavior is correct, as ISIN serves as the primary key of the table.
The entered changes are correctly saved to the database, and after returning to the list, the subfile is refreshed and displays the updated data.
4=Delete
The delete option works correctly. The program displays a confirmation screen asking whether the selected instrument should be removed.

After confirming the operation, the record is deleted from the database, and the application returns to the list view, which refreshes and no longer shows the removed entry.
5=Details
The details option works correctly.

The program properly displays a screen with the details of the selected instrument, without allowing data editing, in accordance with the functional requirements.
Styling and UI Corrections
After completing the functional tests, I turned my attention to minor imperfections in the presentation layer.
In the instrument list view, the ISIN column header was missing. Additionally, the description of the 5 = Detail s option contained an extra space, a typical formatting error in DDS definitions.
I reported both issues to the AI tool, also providing a screenshot from the 5250 terminal along with a simple instruction:
The ISIN column header description is missing from the instrument list view. Additionally, there is excess space in the ‘5=Detail s’ option.
Claude Code correctly identified the indicated elements in the screen definition and applied the required corrections. After recompiling, the list view was displayed correctly, and the minor stylistic issues were resolved.
Summary
The finished program:

The experiment was successful: it was possible to deliver a fully functional native IBM i application without writing a single line of code manually. This fact alone clearly demonstrates the significant potential of modern AI tools in the context of software development — even on such a specialized and niche platform as IBM i.
At the same time, it must be emphasized that the generated code was not correct on the first attempt. Reaching a fully working application required many iterations, manual analysis of system messages, and numerous corrections. Debugging proved to be time-consuming and, at times, cumbersome — particularly in areas characteristic of IBM i, such as DDS, message subfiles, and integration with system APIs.
A key limitation of this experiment was that Claude Code had no ability to independently perform compilations or run the generated code. Unlike popular ecosystems (e.g., Python or JavaScript), where the tool can iterate almost autonomously, the entire feedback loop here had to be executed manually. This meant the need to:
- manually trigger compilations,
- collect error logs,
- pass them to the AI tool,
- and repeatedly issue similar analysis and correction prompts.
If a tool such as Claude Code had direct access to an IBM i system — with the ability to run commands, compile objects, and test applications — the efficiency of this process would increase dramatically. In that case, vibe coding on IBM i could become not only an interesting experiment, but a practical and meaningful enhancement to a programmer’s day-to-day work.
References
- Code repository created as part of this article — https://github.com/leszekczajka/ibmi-ai-1
- Claude Code — https://claude.com/product/claude-code
- Visual Studio Code — https://code.visualstudio.com/
- IBM i — https://www.ibm.com/products/ibm-i
메타데이터
- post_id
- ec83b4575bc7
- slug
- vibe-coding-on-ibm-i-ec83b4575bc7
- url
- https://medium.com/@leszek.czajka/vibe-coding-on-ibm-i-ec83b4575bc7
- canonical_url
- https://medium.com/@leszek.czajka/vibe-coding-on-ibm-i-ec83b4575bc7
- author_url
- https://medium.com/@leszek.czajka
- status
- ok
- fetched_at
- 2026-06-29 02:33:43