Back to all posts

AI in the Developer Workflow: What Actually Works (And What's Just Hype)

An honest assessment of AI tools in daily development. What AI is genuinely good at, what it's terrible at, and why understanding fundamentals matters more than ever.

9 min read

Let me be direct: AI is not going to replace developers. But it’s also not a toy. The truth, as usual, is somewhere in the middle — and most of the discourse around AI in development is either breathless hype or dismissive cynicism. Both are wrong.

I’ve been using AI tools daily in my development workflow for over a year now. Not as an experiment. In production work, leading teams, shipping real systems. Here’s my honest, no-hype assessment of what actually works, what doesn’t, and what you should be thinking about.

What AI Is Genuinely Good At

Let’s start with the wins. These are areas where AI tools have measurably improved my workflow:

Boilerplate and Repetitive Code

This is where AI shines brightest. Writing DTOs, mapping functions, CRUD endpoints, configuration files, type definitions from API specs — the kind of code where the pattern is well-established and you’re essentially translating a known structure into syntax.

// "Generate a DTO for the order response with these fields"
// AI produces this in seconds vs. minutes of typing:
interface OrderResponseDto {
  id: string;
  status: OrderStatus;
  items: OrderItemDto[];
  total: number;
  currency: string;
  createdAt: string;
  shippingAddress: AddressDto;
  estimatedDelivery: string | null;
}

Is this revolutionary? No. Does it save 20 minutes of tedious typing multiple times per day? Absolutely. That adds up.

Test Scaffolding

This is probably my single favorite use case. AI is remarkably good at generating test scaffolds — the describe blocks, the setup, the basic happy-path and error cases. It gets the structure right roughly 80% of the time.

// I describe what the function does, AI generates the scaffold:
describe('OrderService.calculateTotal', () => {
  let service: OrderService;
  let mockTaxCalculator: jest.Mocked<TaxCalculator>;

  beforeEach(() => {
    mockTaxCalculator = { calculate: jest.fn() };
    service = new OrderService(mockTaxCalculator);
  });

  it('should sum item prices correctly', () => { /* ... */ });
  it('should apply tax from calculator', () => { /* ... */ });
  it('should handle empty order', () => { /* ... */ });
  it('should throw on negative quantities', () => { /* ... */ });
  it('should round to 2 decimal places', () => { /* ... */ });
});

I still write the actual assertions and edge cases myself. But having the scaffold, the mocks set up, and the test organization ready saves significant time. It’s like having someone set up the workbench before you start building.

Exploring Unfamiliar Codebases

When I join a new project or need to understand a library I’ve never used, AI is an excellent exploration partner. “Explain how this middleware chain works.” “What does this Terraform module provision?” “Walk me through the authentication flow in this codebase.”

It’s not always right. But it’s faster than reading documentation from scratch, and it gives me a starting point for my own investigation. I treat it like asking a colleague who’s worked on the codebase before — useful input, but I verify anything critical.

Documentation and Commit Messages

Writing JSDoc comments, README sections, API documentation, and even thoughtful commit messages. AI handles this surprisingly well because documentation is fundamentally about describing what already exists — and the code is right there as context.

Refactoring Suggestions

“Here’s a 200-line function. Suggest how to break it down.” The suggestions aren’t always production-ready, but they’re a useful starting point for thinking about decomposition. AI can spot extract-method opportunities faster than I can read through a long function.

What AI Is Terrible At

Now the important part. These are areas where trusting AI output will hurt you:

Architecture Decisions

AI cannot make architectural decisions for your system. It doesn’t understand your team’s capabilities, your deployment constraints, your business timeline, your compliance requirements, or the political dynamics that influence technical choices.

I’ve seen engineers ask AI “should I use microservices or a monolith?” and treat the response as gospel. The response will be coherent. It’ll mention trade-offs. It’ll sound authoritative. And it’ll be generic advice that ignores everything that actually matters about your specific situation.

Architecture requires context that doesn’t fit in a prompt. It requires understanding organizational dynamics, team skills, operational maturity, and business trajectory. AI has none of this.

Business Logic

The core logic that makes your system valuable — the pricing algorithms, the matching rules, the compliance checks, the domain-specific calculations — this is exactly where AI is most dangerous.

Why? Because it’ll generate code that looks correct. It compiles. It passes basic tests. But it encodes assumptions about your business domain that may be subtly wrong. And subtle bugs in business logic are the kind that cost real money and erode user trust.

I had a case where AI-generated code for a discount calculation handled percentage-based discounts correctly but applied them in the wrong order when stacked with flat-rate discounts. The code looked clean. The tests that AI also generated passed. The bug made it to staging and would have cost thousands in incorrectly priced orders.

Your business logic is your competitive advantage. Write it yourself. Understand every line.

Security

Do not let AI write your authentication flows, authorization logic, input validation, or anything related to security. AI models are trained on a massive corpus of code, and a significant portion of that code has security vulnerabilities.

AI will generate SQL queries without parameterization. It’ll create JWT validation that doesn’t check expiration. It’ll write file upload handlers without size limits or type checking. Not every time — but often enough that you cannot trust it.

Security is a domain where “works most of the time” is completely unacceptable.

The “AI-Assisted” vs. “AI-Generated” Distinction

This is the framework I use to think about AI in my workflow, and I think it’s the most important distinction in this entire conversation.

AI-Assisted: I’m driving. I understand the problem, I know what the solution should look like, and I’m using AI to accelerate the mechanical parts of implementation. I review every line, I make the decisions, AI handles the typing.

AI-Generated: AI is driving. I describe what I want, AI produces the solution, and I ship it with minimal review. I’m essentially outsourcing understanding.

The first approach makes you faster. The second makes you dangerous.

Here’s my rule: if you can’t explain every line of the AI-generated code, you shouldn’t ship it. Not “I roughly understand what it does” — you should be able to explain why each decision was made, what the edge cases are, and how it fails.

If you can’t do that, you don’t have a solution. You have a liability.

How I Actually Use AI Day-to-Day

Here’s my realistic workflow:

Morning code review acceleration: I use AI to get a quick summary of large PRs before doing my detailed review. “Summarize the changes in this PR and flag potential issues.” This gives me a map before I dive into the territory. I still review every file, but I know where to focus attention.

Test generation: When writing a new service, I write the implementation first, then ask AI to generate test scaffolds. I modify the tests heavily — adding edge cases, fixing assertions, ensuring the tests actually validate behavior rather than implementation. But the scaffold saves 30-40% of the time.

Exploring new libraries: Before reading full documentation, I ask AI to explain the core concepts and common patterns. This gives me a mental model that makes the docs more digestible. Always followed by reading the actual docs.

Boilerplate acceleration: DTOs, mappers, configuration, migration files. Anything where the pattern is established and I’m translating a known structure into code.

What I never use AI for: Architecture decisions, database schema design, security logic, performance-critical code paths, business rule implementation, or any code where being subtly wrong has significant consequences.

Why Fundamentals Matter MORE With AI, Not Less

Here’s the take that might be controversial: AI makes software engineering fundamentals more important, not less.

If you don’t understand design patterns, you can’t evaluate whether AI’s suggested pattern is appropriate. If you don’t understand database indexing, you can’t spot that AI’s generated query will do a full table scan on a million-row table. If you don’t understand HTTP semantics, you can’t catch that AI used POST where it should have used PUT.

AI amplifies what you already know. If you understand system design deeply, AI makes you dramatically faster. If you don’t understand the fundamentals, AI makes you dramatically more efficient at producing broken software.

The developers who are thriving with AI tools are the ones who already had strong fundamentals. They use AI as a power tool, not a crutch. They know enough to:

The Danger of The Comfort Zone

I see a pattern that concerns me: developers who stop learning because AI can fill the gaps. They don’t learn how promises work because AI writes their async code. They don’t understand SQL joins because AI generates their queries. They don’t learn design patterns because AI structures their code.

This works until it doesn’t. And when it doesn’t — when you’re debugging a race condition at 2 AM, or designing a system that needs to handle 10x traffic, or figuring out why the AI-generated code is causing a memory leak — there’s no shortcut. You either understand the fundamentals or you don’t.

AI is a tool. You are the engineer. The tool doesn’t replace the skill — it requires it.

Closing Thoughts

AI in the developer workflow is genuinely useful. I’m more productive with it than without it. That’s not hype — that’s my honest experience after extensive daily use.

But the useful parts are the mundane parts. The boilerplate. The scaffolding. The exploration. The documentation. The stuff that was never the hard part of software engineering in the first place.

The hard parts — understanding problems deeply, making architectural trade-offs, writing correct business logic, building secure systems, mentoring teams — those are still entirely human skills. And I don’t see that changing anytime soon.

Use AI tools. Get faster at the mechanical parts of development. But invest even more time in understanding the fundamentals. Because the developers who will thrive in an AI-augmented world aren’t the ones who can prompt the best. They’re the ones who can think the best.

The AI is the power tool. You’re still the craftsman. Don’t forget which one matters more.

Found this useful?

Share it on LinkedIn, check out more posts, or connect with me to exchange ideas.

Keep reading