# Designing AI-Compatible Code > A Guide to Writing Code That Works Seamlessly with AI **Published by:** [veganbeef](https://paragraph.com/@veganbeef/) **Published on:** 2025-07-03 **Categories:** ai, software, prompt-engineering, software-engineering, software-architecture **URL:** https://paragraph.com/@veganbeef/designing-ai-compatible-code ## Content There’s a lot of writing out there on prompt engineering and model selection in pursuit of making AI agents smarter and more self-directed software engineers, but I’ve found that isn’t always enough to get consistently helpful results, especially when you’re trying to use AI to update older, more complex codebases alongside human engineers. The structure and style of your code can make a huge difference in how well AI can understand and intelligently extend it.I’m not saying you need to go refactor everything right now, but if you’ve been feeling like your AI engineer is acting less like an expert and more like a junior intern, then gradually incorporating these ideas into your existing code will likely help. The following code architecture and design guidelines are based on my personal experience using AI to edit existing projects and to clone and extend templates into new projects, ordered purely by my own raw gut feeling of how important they are:Core Principles1. Use Common Libraries and PatternsChoose well-documented, mainstream technologies over custom solutionsFollow established approaches (MVC, Repository structures, React patterns) that AI recognizesUse standard naming conventions for your language/frameworkStick to idiomatic code rather than clever implementations2. Modular File StructureCreate many small, focused files (200-300 lines max)Use nested directories that reflect logical relationshipsGroup by feature, not file typeOne primary responsibility per filesrc/ ├── components/authentication/ │ ├── login-form.component.ts │ └── registration-form.component.ts ├── services/user-management/ │ ├── user-profile.service.ts │ └── user-preferences.service.ts └── utils/validation/ ├── email-validator.util.ts └── password-strength-validator.util.ts 3. Extremely Descriptive NamesUse verbose, self-documenting names that explain purpose and contextInclude units, types, and constraints when relevantDon't worry about name length - clarity over brevity { ... }; // Avoid const user = await fetchUser(); const isValid = validateEmail(email); const processData = (response) => { ... }; ">// Good const authenticatedUserWithPermissions = await fetchUser(); const isEmailAddressFormatValid = validateEmail(email); const convertRawApiResponseToUserProfileData = (response) => { ... }; // Avoid const user = await fetchUser(); const isValid = validateEmail(email); const processData = (response) => { ... }; 4. Comprehensive DocumentationAdd docstrings to all functions, classes, and complex logicInclude parameter types, return values, and usage examplesDocument business logic and decision reasoningAdd inline comments for non-obvious code sections { // Check basic email format first const emailRegexPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/; if (!emailRegexPattern.test(emailAddress)) { return false; } // Optional blacklist check for spam domains if (checkBlacklist) { return !isEmailDomainBlacklisted(emailAddress); } return true; }; ">/** * Validates user email format and checks against blacklisted domains * @param emailAddress - The email address to validate * @param checkBlacklist - Whether to check against domain blacklist * @returns True if email is valid and not blacklisted * @example validateUserEmailAddress('user@example.com', true) */ export const validateUserEmailAddress = ( emailAddress: string, checkBlacklist: boolean = true ): boolean => { // Check basic email format first const emailRegexPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/; if (!emailRegexPattern.test(emailAddress)) { return false; } // Optional blacklist check for spam domains if (checkBlacklist) { return !isEmailDomainBlacklisted(emailAddress); } return true; }; 5. Centralize Shared Logic and ConfigExtract all configuration into dedicated files, even if used in one placeCreate utility functions for any logic that could be reusedUse clear, descriptive configuration objects { // Implementation here }; ">// config/database.config.ts export const DATABASE_CONFIG = { connectionTimeoutMs: 5000, maxRetryAttempts: 3, productionPoolSize: 20, developmentPoolSize: 5 }; // utils/email-validation.util.ts export const validateEmailAddressFormat = (email: string): boolean => { // Implementation here }; Additional Best PracticesUse TypeScript or similar type systems for better AI understandingInclude README files in each major directory explaining purposeMaintain consistent code formatting with automated toolsUse meaningful commit messages that explain the "why" not just "what"Include unit tests with descriptive test names that explain expected behavior A final word of cautionYou can of course use AI to implement these changes, but make sure to double check these types of changes, as mistakes here can be pernicious hard to find. ## Publication Information - [veganbeef](https://paragraph.com/@veganbeef/): Publication homepage - [All Posts](https://paragraph.com/@veganbeef/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@veganbeef): Subscribe to updates - [Farcaster](https://farcaster.xyz/veganbeef): Follow on Farcaster ## Optional - [Collect as NFT](https://paragraph.com/@veganbeef/designing-ai-compatible-code): Support the author by collecting this post - [View Collectors](https://paragraph.com/@veganbeef/designing-ai-compatible-code/collectors): See who has collected this post