Guru: Are Binding Directories A Shortcut Or A Source Of Chaos?
February 16, 2026 Gregory Simmons
Ask any IBM i developer about binding directories, and you will usually get one of two reactions: A grateful nod or an eye roll. For some, binding directories are a lifesaver, making compile commands cleaner and projects easier to manage. For others, they are a ticking time bomb, introducing hidden dependencies that come back to haunt you months later.
I have seen both sides. In fact, one of the worst compile-day disasters I’ve witnessed started with a well-meaning developer adding a single service program to a global binding directory. Suddenly, half the shop’s programs were linking against the wrong version of a procedure. What was meant to save time turned into a fire drill, and it all came down to a tool that wasn’t inherently “bad” but was just poorly managed.
When you build a program or a service program, the compiler needs to know which modules and service programs to bind to. You could specify every single one explicitly in your CRTPGM or CRTSRVPGM commands, but that’s tedious and prone to mistakes. Binding directories were created to solve this problem. Think of a binding directory as a shopping list of service programs and modules. Instead of rewriting the same list every time you compile, you put them all in a binding directory, reference that directory once, and let the system figure out the rest.
Here’s a simple example:
CRTBNDDIR BNDDIR(MYLIB/MSHRMBDIR) ADDBNDDIRE BNDDIR(MYLIB/MSHRMBDIR) OBJ((MYLIB/MSHRMUTILS *SRVPGM)) CRTPGM PGM(MYLIB/MYPGM) MODULE(MYLIB/MYPGM) BNDDIR(MYLIB/MSHRMBDIR)
In this example, MSHRMBDIR becomes a central list. Any program built with it automatically binds to MSHRMUTILS, and you don’t have to keep retyping the service program name in every compile command.
Binding directories shine in large projects or teams. Instead of memorizing dozens of dependencies, a developer can just specify a single directory. This makes onboarding new team members easier – “Just use MSHRMBDIR” – and it reduces typos and forgotten modules. They also simplify maintenance when used carefully. If you add a new utility service program, you don’t need to modify every compile script; just update the binding directory, and all future compiles will pick it up. For teams that are disciplined and communicate changes, binding directories can feel like a productivity superpower.
But here is the dark side: Binding directories make it easy to lose track of what is actually being bound. When you use a binding directory, you’re delegating control to a system-level list. That’s fine if everyone is on the same page, but in many shops, these directories grow organically. Someone adds a new service program here, another developer tweaks something there, and before long, no one is quite sure what is in that directory.
Worse, if two service programs export procedures with the same name, the system will happily bind whichever one it finds first in the directory. You won’t know anything’s wrong until a program calls the wrong version at runtime. I’ve seen this firsthand: a single addition to a global binding directory caused dozens of programs to compile against the wrong procedure. The result? Hours of frantic debugging and finger-pointing. The developer who made the change wasn’t careless – they were trying to help. The problem was a lack of boundaries.
So, should you avoid binding directories altogether? Not at all. Like most tools, the key is to use them with intention. Here’s a strategy that works well: keep them application-specific. Instead of one giant system-wide directory, create a separate directory for each application or subsystem. This keeps changes contained. Name them clearly. Something like MSHRMBDIR makes it obvious what’s inside. Document everything. A binding directory should never feel like a mystery box. Keep a simple list in your project documentation so developers know exactly what’s in it. And be cautious with shared libraries. If a service program is truly universal, like a date utility library, fine. But make sure it’s stable before adding it to multiple binding directories.
Some developers I know refuse to use binding directories altogether. They specify every module and service program explicitly in their CRTPGM and CRTSRVPGM commands. There’s nothing wrong with that – it is the safest approach because you always know exactly what’s being bound. But there’s a trade-off: more manual work. Explicit binding makes sense for critical code or projects where absolute control is required. Binding directories, on the other hand, are great for speeding up day-to-day development when you have good processes in place. If your team is disciplined, there’s no reason you can’t mix the two approaches. Use directories for non-critical projects and keep things explicit where you need control.
Binding directories aren’t evil. They are a tool, one that can either make your life easier or create a tangle of hidden dependencies, depending on how you use them. The key is intentionality: Keep them organized, documented, and scoped to specific applications. If your shop is using a single, massive binding directory that no one fully understands, it’s time for a cleanup. Start small, create directories per application, and be explicit where it matters most. You will find that binding directories can be a real productivity boost – without the chaos.
In the next article, we will zoom out and talk about service program lifecycle management: how to make changes safely, deploy across environments, and avoid breaking production when evolving your service programs.
Until next time, happy coding.
Gregory Simmons is a Project Manager with PC Richard & Son. He started on the IBM i platform in 1994, graduated with a degree in Computer Information Systems in 1997 and has been working on the OS/400 and IBM i platform ever since. He has been a registered instructor with the IBM Academic Initiative since 2007, an IBM Champion and holds a COMMON Application Developer certification. When he’s not trying to figure out how to speed up legacy programs, he enjoys speaking at technical conferences, running, backpacking, hunting, and fishing.
RELATED STORIES
Guru: Service Programs And Activation Groups – Design Decisions That Matter
Guru: Binder Source Is Your Service Program’s Owner’s Manual
Guru: Access Client Solutions 1.1.9.11 – Security First, With Continued Investment In SQL Tooling
Guru: Taming The CRTSRVPGM Command – Options That Can Save Your Sanity
Guru: CRTSRVPGM Parameters That Can Save or Sink You
Guru: A First Look at Bob, The IBM i Assistant That’s Closer Than You Think
Bob More Than Just A Code Assistant, IBM i Chief Architect Will Says
IBM Pulls The Curtain Back A Smidge On Project Bob
Big Blue Converges IBM i RPG And System Z COBOL Code Assistants Into “Project Bob”
Guru: When Attention Turns To You – Writing Your Own ATTN Program
Guru: WCA4i And Granite – Because You’ve Got Bigger Things To Build
Guru: When Procedure Driven RPG Really Works
Guru: Unlocking The Power Of %CONCAT And %CONCATARR In RPG
Guru: AI Pair Programming In RPG With Continue
Guru: AI Pair Programming In RPG With GitHub Copilot
Guru: RPG Receives Enumerator Operator
Guru: RPG Select Operation Gets Some Sweet Upgrades
Guru: Growing A More Productive Team With Procedure Driven RPG
Guru: With Procedure Driven RPG, Be Precise With Options(*Exact)
Guru: Testing URLs With HTTP_GET_VERBOSE
Guru: Fooling Around With SQL And RPG
Guru: Procedure Driven RPG And Adopting The Pillars Of Object-Oriented Programming
Guru: Getting Started With The Code 4 i Extension Within VS Code
Guru: Procedure Driven RPG Means Keeping Your Variables Local
Guru: Procedure Driven RPG With Linear-Main Programs
Guru: Speeding Up RPG By Reducing I/O Operations, Part 2
Guru: Speeding Up RPG By Reducing I/O Operations, Part 1
Guru: Watch Out For This Pitfall When Working With Integer Columns


