Your CLAUDE.md Instructions Are Being Ignored – Here’s Why (and How to Fix It)

If you use Claude Code, you’ve probably added development standards to your CLAUDE.md file. Something like “always fix root causes” or “no half solutions.”

And you’ve probably noticed Claude ignoring them mid-session.

This isn’t a bug in your instructions. It’s a documented problem with how CLAUDE.md content gets injected.

The CLAUDE.md Disclaimer Problem

When Claude Code loads your CLAUDE.md, it wraps the content in a framing that tells Claude it “may or may not be relevant” and should only be followed “if highly relevant to your task.”

This is documented across multiple GitHub issues:

  • #22309 — CLAUDE.md content wrapped in dismissive framing
  • #21119 — Claude treats explicit instructions as suggestions
  • #7777, #15443, #21385 — Various reports of Claude ignoring CLAUDE.md rules

The practical effect: as your conversation grows and Claude’s context fills with code, tool output, and discussion, your carefully written standards get deprioritized. And when the context window fills up and gets compacted, your CLAUDE.md values get summarized away with everything else.

A Better Approach: Hook-Based Reinforcement

Claude Code hooks are event-driven scripts that fire at specific moments in the session lifecycle. Unlike CLAUDE.md content, hook output arrives as clean system-reminder messages — no disclaimer, no “may or may not be relevant” framing.

I built a plugin called Claude Core Values that uses a three-layer reinforcement strategy:

Layer Hook Event What It Does
Full injection SessionStart Injects all your values at session start — and re-injects them fresh after every compaction
Per-prompt reminder UserPromptSubmit Reinforces your motto on every single prompt
No disclaimer Both Hook output has no “may or may not be relevant” framing

The SessionStart hook fires on startup, resume, clear, and crucially compact — meaning your values are automatically restored every time context gets compressed.

The UserPromptSubmit hook adds a single-line motto reminder (~15 tokens) on every prompt. Over a 50-turn session, that’s ~750 tokens — negligible against a 200k context window.

How It Works

Your values live in a simple YAML file:

# ~/.claude/core-values.yml
motto: "Excellence is not negotiable. Quality over speed."

sections:
  - name: Quality Commitment
    values:
      - "No Half Solutions: Always fix everything until it's 100% functional."
      - "No Corner Cutting: Do the real work until completion."
      - "No Band-Aid Solutions: Fix the root cause, not the symptom."
      - "Follow Through: Continue until completely done and verified."

  - name: Standards
    values:
      - "Follow best practices and highest industry standards."
      - "Build efficient, modular code with separation of concerns."
      - "Always consider performance, scalability, and maintainability."

The plugin reads this file and injects it through two hooks defined in hooks.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/inject-values.sh",
            "timeout": 10
          }
        ]
      }
    ],
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/inject-reminder.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

At session start, Claude sees:

## Core Values & Development Standards

**Excellence is not negotiable. Quality over speed.**

### Quality Commitment
- **No Half Solutions**: Always fix everything until it's 100% functional.
- **No Corner Cutting**: Do the real work until completion.
...

On every subsequent prompt, it sees:

Core values reminder: Excellence is not negotiable. Quality over speed.

Both without the disclaimer. Both surviving compaction.

Installation

The plugin installs directly from GitHub — no cloning needed:

/plugin marketplace add albertnahas/claude-core-values
/plugin install claude-core-values@claude-core-values

Then initialize with a starter template:

/core-values init

You’ll pick from four templates:

Template Philosophy
Craftsman Quality-obsessed. No half solutions. No shortcuts.
Startup Ship fast, iterate rapidly, pragmatic quality.
Security-First Defense in depth, zero trust, OWASP compliance.
Minimal Simple baseline: working code, follow patterns, test before push.

The config gets saved to ~/.claude/core-values.yml (global) or .claude/core-values.yml (per-project). Edit the YAML directly anytime — changes take effect on the next session.

Beyond CLAUDE.md

The plugin also solves practical management problems:

  • Team distribution: plugin install gives everyone identical standards instead of “copy these 30 lines into your CLAUDE.md.”
  • Per-project overrides: Drop a different core-values.yml in any project’s .claude/ directory without touching global config.
  • Structured config: YAML with typed sections is easier to diff and review than freeform markdown.
  • Starter templates: Pick a philosophy and go, instead of staring at a blank file.

The Takeaway

CLAUDE.md is great for project-specific context — file conventions, architecture notes, gotchas. But for development standards you want Claude to follow every time, in every session, no exceptions — hook-based injection is the more reliable path.

The plugin is open source and MIT licensed: github.com/albertnahas/claude-core-values

Requirements: Claude Code, Python 3 (ships with macOS/Linux). PyYAML is optional — the plugin includes a zero-dependency fallback parser.

GitHub Copilot to Generate Conventional Commit Messages in VSCode and JetBrains Rider

Most commit messages are useless.

“fix stuff”
“update code”
“changes”

They work in the moment. They fail six (actually one) months later.

Commit messages are not for today or for something special. They are for:

  • your future self
  • your teammates
  • automation pipelines
  • changelog generators
  • semantic versioning

Writing structured commit messages takes discipline. Under pressure, discipline disappears. Even without the pressure sometimes, just because as developers, we are lazy by nature.

This is where GitHub Copilot becomes interesting.

Instead of using Copilot just for code, you can use it as a commit quality guardrail. With the right instructions, it generates strict Conventional Commit messages automatically, directly inside:

  • VS Code
  • JetBrains Rider

Why Conventional Commits Still Matter

Conventional Commits are not about style.
They are about structure.

The format is simple:

type(scope): description

Example:

feat(auth): add JWT token validation
fix(api): handle null response in user endpoint
refactor(ui): simplify navbar component

Readable Git History

Compare:

update stuff
fix bug
changes

With:

fix(auth): prevent null pointer on login
feat(api): add user filtering by role
ci(github-actions): add build cache

The second history is self-documenting.

Using GitHub Copilot for Commit Messages in VS Code

Copilot can generate commit messages directly from the Source Control panel.

By default, generation is generic.
Custom instructions make it strict.

Add this to your settings.json:

"github.copilot.chat.commitMessageGeneration.instructions": [
    { "text": "Follow Conventional Commits: type(scope): description." },
    { "text": "Use lowercase type and scope." },
    { "text": "Use imperative mood: 'add', 'fix', 'update', not past tense." },
    { "text": "Keep subject under 50 characters. No period." },
    { "text": "Describe the intent clearly. Avoid vague messages like 'update code'." },
    { "text": "Use only these types: feat, fix, docs, style, refactor, perf, test, chore, ci." },
    { "text": "Include a scope when the change targets a specific area." },
    { "text": "Ensure each commit represents one logical change." },
    { "text": "Add a body when needed, separated by a blank line." },
    { "text": "Use bullet points (*) in the body for multiple changes." },
    { "text": "Explain why the change was made, not only what changed." },
    { "text": "Add BREAKING CHANGE: in the footer when applicable." }
]

After staging changes, generate the commit message.

Instead of:

update login logic

You’ll get:

fix(auth): prevent null pointer on login

* add null check for user object
* improve error handling for invalid credentials

Copilot becomes consistent because the rules are explicit.

Using GitHub Copilot for Commit Messages in JetBrains Rider

In Rider, Copilot integrates in the Commit tool window.

With strict instructions, you can enforce full compliance.

Example instruction structure:

Follow the Conventional Commits specification strictly.

<type>(<scope>): <short description>

All sections except the first line are optional.
Use only these types: feat, fix, docs, style, refactor, perf, test, chore, ci.
Max 50 characters. Imperative mood. No period.
Each commit must represent one logical change.
Use BREAKING CHANGE: footer when applicable.

Example output:

feat(auth): add refresh token support

* implement refresh token endpoint
* update token validation logic
* improve session security

Breaking change example:

refactor(api): rename user endpoint

BREAKING CHANGE: /users endpoint is now /v2/users

Go to Settings *> **Tools *> **GitHub Copilot > Git Commit Instructions > Global.

Rider allows more verbose enforcement.
VS Code favors compact rule lists.

Both approaches work.

Making Copilot Strict (Not Creative)

Copilot predicts text.
Constraints reduce variance.

Key principles:

  • Write hard rules, not suggestions
  • Limit allowed types
  • Enforce atomic commits
  • Require proper breaking change footers
  • Review output before committing

Copilot is not replacing judgment.
It removes repetitive formatting work.

When configured correctly, writing a proper Conventional Commit becomes easier than writing a bad one.

👀 GitHub Copilot quota visibility in VS Code

If you use GitHub Copilot and ever wondered:

  • what plan you’re on
  • whether you have limits
  • how much premium quota is left
  • when it resets

I built a small VS Code extension called Copilot Insights.

It shows Copilot plan and quota status directly inside VS Code.

No usage analytics. No productivity scoring. Just clarity.

👉 VS Code Marketplace:
https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights

Understanding Django’s Architecture Beyond the File Structure

Understanding Django’s Architecture Beyond the File Structure

When developers first encounter Django, the framework feels clean, powerful, and “batteries-included.” But after the initial excitement, confusion starts.

Why?

Because most tutorials explain what the files are, not why they exist.

This article breaks down Django’s structure from an architectural perspective — not just folder-by-folder explanation, but system-level understanding.

Why Django Structure Confuses Juniors

Most juniors approach Django like this:

“I created a project. I created an app. Now I put logic somewhere and it works.”

The confusion happens because:

  • The distinction between project and app isn’t conceptually clear.
  • MTV is introduced superficially.
  • Business logic placement isn’t discussed.
  • The request lifecycle remains invisible.
  • Django’s “magic” hides architectural flow.

Without understanding the architecture, Django feels like controlled chaos.

With understanding, it becomes predictable and powerful.

Project vs App — The Most Misunderstood Concept

Let’s clarify this precisely.

The Django Project

A project is the configuration container.

It defines:

  • Global settings
  • Installed apps
  • Middleware
  • Root URL configuration
  • ASGI/WSGI entrypoints

It does not contain business logic.

Think of the project as:

The runtime configuration and environment boundary.

The Django App

An app is a modular unit of functionality.

It represents a domain boundary.

❌ Bad modular thinking

users_app/
orders_app/
payments_app/

✅ Better domain-oriented thinking

accounts/
billing/
analytics/
core/

Each app should encapsulate:

  • Models
  • Views
  • URLs
  • Domain logic related to that specific area

The app is not just a folder — it is a cohesive domain module.

MTV Properly Explained

Django follows the MTV pattern:

  • Model
  • Template
  • View

This is often compared to MVC, but they are not identical.

Conceptual Mapping

Django Classical MVC
Model Model
Template View
View Controller

Model

Represents data structure and database interaction.

  • Defines schema
  • Handles ORM logic
  • Encapsulates data behavior

Models should contain domain rules when appropriate.

View

Despite the name, Django’s View acts more like a controller.

It:

  • Accepts requests
  • Orchestrates logic
  • Interacts with models
  • Returns responses

It should not:

  • Contain heavy business logic
  • Contain large data transformations
  • Become a dumping ground

Template

Responsible for presentation.

In API-based systems (e.g., Django REST Framework), templates are often replaced by serializers and JSON responses.

The Django Request Lifecycle (What Actually Happens)

Understanding this is critical.

When a request hits your server:

  1. Client sends HTTP request.
  2. Web server forwards request to Django (via WSGI or ASGI).
  3. Middleware processes the request.
  4. URL resolver matches the path.
  5. Corresponding view is executed.
  6. View interacts with models / services.
  7. Response object is created.
  8. Middleware processes response.
  9. Response is returned to client.

The important insight:

Every request goes through a predictable pipeline.

Django is not magic — it is structured orchestration.

Modular Design Advice (How to Think Like a Mid-Level Developer)

As projects grow, default Django structure becomes insufficient.

1. Avoid Fat Views

Instead of this:

def create_order(request):
    # validation
    # business logic
    # pricing calculation
    # email sending
    # inventory update

Move business logic into:

  • services.py
  • domain modules
  • dedicated logic layers

Views should orchestrate — not implement business rules.

2. Introduce a Service Layer

Inside each app:

billing/
    models.py
    views.py
    services.py
    selectors.py
  • services.py → write operations
  • selectors.py → read/query logic

This keeps logic organized and testable.

3. Think in Domain Boundaries

Apps should represent cohesive functionality.

❌ Everything in one giant app
❌ Hyper-fragmented micro-apps

✅ Clear domain boundaries
✅ Strong cohesion
✅ Low coupling

Real-World Structuring Patterns

As Django systems mature, structure often evolves like this:

project/
│
├── config/
│   ├── settings/
│   │   ├── base.py
│   │   ├── dev.py
│   │   └── prod.py
│
├── apps/
│   ├── accounts/
│   ├── billing/
│   ├── analytics/
│
├── core/
│   ├── middleware.py
│   ├── permissions.py
│
└── manage.py

Patterns commonly seen in production systems:

  • Split settings per environment
  • Dedicated apps/ folder
  • Clear separation between infrastructure and domain logic
  • Services and selectors pattern
  • Centralized configuration

Structure should support scalability — not fight it.

Common Mistakes Developers Make

1. Putting All Logic in Views

Leads to:

  • Hard-to-test code
  • Repetition
  • High coupling

2. Overusing Signals

Signals are powerful but implicit.

They:

  • Hide logic
  • Create invisible dependencies
  • Make debugging harder

Use them carefully.

3. Ignoring Request Lifecycle

When developers don’t understand middleware or URL resolution, debugging becomes painful.

You must understand the pipeline.

4. Treating Apps as Random Containers

Apps should represent domain modules — not arbitrary file grouping.

5. Overengineering Too Early

Not every project needs:

  • Complex service layers
  • Deep folder hierarchies
  • Microservices

Start simple.
Refactor when needed.
Architect intentionally.

Final Thoughts

Django is not confusing by design.

It becomes confusing when we learn it procedurally instead of architecturally.

If you understand:

  • Project vs App boundaries
  • MTV conceptually
  • Request lifecycle
  • Modular structuring principles

Then Django stops being “magic.”

It becomes a predictable, extensible backend framework.

And that is the difference between using Django and understanding Django

Did you brush up on your fundamentals?

In the era of AI, theoretical knowledge is more important than ever. Recently, while solving the Reverse Integer problem, I realized the real challenge wasn’t reversing digits but understanding 32-bit overflow and memory limits. Python hides overflow with dynamic integers, but low-level constraints still matter. AI can generate working code instantly, yet without knowing concepts like time complexity, integer ranges, or the Euclidean algorithm, it’s hard to judge correctness. Theory builds intuition and clarity. It helps you detect hidden constraints and avoid blind trust in generated solutions. AI is powerful, but fundamentals are what make you truly independent and confident.

The Most Popular AI Tools: What Developers Use and Why

AI tools have become a core part of modern software development. Developers rely on them throughout the life cycle, from writing and refactoring code to testing, documentation, and analysis.

Once experimental add-ons, these tools now function as everyday assistants and are firmly embedded in routine workflows. But why have AI tools become so essential – and how are developers actually using them?

The insights in this article draw on findings from the JetBrains State of Developer Ecosystem Report 2025, which tracks how developers use tools, languages, and technologies, including AI tools, in real-world environments. Shifting the focus from technical model performance, this article looks at usage patterns, developer preferences, and adoption trends across tools, regions, and workflows.

Before we work through which AI tools developers use most, why they choose them, and how these tools fit into everyday work, let’s first clarify what AI tools are and why they matter so much right now.

Disclaimer: Please note that the findings in the article reflect data collected during the specific research period set out in the report.

Table of Contents

·       What AI tools are and why they matter now

·       Most popular AI tools among developers

·       What makes developers choose one AI tool over another

·       How developers use AI tools in daily workflows

·       Global snapshot: How AI tool adoption differs across regions

·       Barriers to adopting AI tools

·       Future of AI tools: What developers want next

·       FAQ

·       Conclusion

What AI tools are and why they matter now

Today’s AI tools for developers span several categories. They include code assistants that suggest or generate code, as well as tools that review code autonomously. Many come as IDE integrations that understand project context.

There are also AI-powered search and navigation tools, refactoring helpers, and documentation generators. In addition, teams now use testing assistants and autonomous or semi-autonomous agents to support more complex workflows.

Understanding today’s AI tools list for developers matters because these tools directly address growing pressures in modern development. They shorten development cycles, reduce manual tasks, and help teams maintain quality, which is especially important as codebases grow.

This growing reliance makes it important to understand which tools developers actually use most. In the next section, we will see what these AI tools are.

Most popular AI tools among developers

Developers rarely rely on a single AI tool. Instead, they combine multiple tools depending on their IDE, workflow style, and project requirements. According to the AI usage insights in the the JetBrains State of Developer Ecosystem Report 2025, adoption clusters around three main categories: IDE-native assistants, standalone AI-powered development environments, and browser-based or cloud chat tools.

Across these categories, the most popular AI assistants are GitHub Copilot, JetBrains AI Assistant, Cursor, Windsurf, and Tabnine. Adoption of these top AI tools varies based on ecosystem, IDE choice, and workflow style.

IDE-native assistants, such as GitHub Copilot and JetBrains AI Assistant, remain among the most popular AI tools because they operate inside the editor and integrate directly into existing workflows, making them more context-aware.

Standalone AI-focused editors and assistants, such as Cursor and Windsurf, often emphasise more experimental or agent-style workflows. This is an area that is evolving across the ecosystem, with increasing convergence between IDE-native tools and more agent-driven capabilities.

Other tools focus on specific priorities. For example, Tabnine attracts teams that prioritize privacy and local inference. Region-specific tools also play an important role in areas with strong domestic AI ecosystems or regulatory constraints.

This diversity becomes clearer when comparing the best AI tools for developers side by side.

Comparison table: AI tools overview

AI tool Typical use case Underlying models Distinct features Integration type
GitHub Copilot Code generation and completion GPT family Tight GitHub + VS Code workflows IDE / Cloud
JetBrains AI Assistant Context-aware help, refactoring Claude / GPT / Gemini Deep IDE context + privacy focus In-IDE
Cursor Inline edits, debugging, chat Claude / Gemini Fast UI, multi-step edits IDE plugin
Windsurf Autonomous task execution and code changes Claude / GPT Agent-like capabilities Standalone
Tabnine Privacy-oriented code suggestions Proprietary / DeepSeek Local inference options IDE plugin
Disclaimer: Please note that the findings reflect data collected during the specific research period set out in the report.

What makes developers choose one AI tool over another

Developers are not choosing AI tools solely on novelty. They evaluate how well a tool fits existing workflows, how reliable the output feels, and whether the tool aligns with team constraints. The JetBrains State of Developer Ecosystem Report 2025 identifies several of these practical considerations that shape decision-making.

Integration quality ranks among the most important factors. Developers prefer AI coding tools that work seamlessly inside their preferred IDE. A tool that interrupts flow or requires constant context switching often fails to gain long-term adoption.

Accuracy and code quality are equally crucial. Developers expect AI coding tools to produce reliable results that they can trust. When outputs require extensive correction, confidence drops quickly.

Privacy and data security also influence developer AI preferences. This is especially true in enterprise environments. Tools that offer local processing or clear privacy guarantees often see stronger uptake in regulated industries.

Finally, pricing, transparency, and vendor reputation affect adoption. Developers value clear pricing models, flexible access, and vendors with a track record of supporting developer tools. Trust builds over time through consistency and ongoing communication.

Let’s see how developers evaluate each of these factors in this AI assistant comparison.

Key factors influencing tool choice

Factor Why it matters How developers evaluate it
IDE integration Supports smooth workflows Works natively in their preferred IDE
Code accuracy and quality Affects trust and usability Produces correct, clear, and maintainable code
Privacy and security Protects source code and IP Provides clear data handling and local mode options
Pricing and access Impacts adoption at scale Offers flexible tiers and predictable costs
Transparency Builds confidence Discloses model provider and data policies
Vendor reputation Signals long-term reliability Demonstrates a history of dev tools and quality support
Disclaimer: please note that the findings reflect data collected during the specific research period set out in the report.

How developers use AI tools in daily workflows

Developers integrate AI tool usage throughout the development life cycle rather than limiting it to a single task. Most workflows combine several forms of AI access depending on the problem at hand.

When coding with AI tools, developers may use in-IDE assistants for context-aware code help and chat-based interfaces for problem-solving and prototyping. In addition, developer AI assistant usage may combine browser tools for quick inline answers, APIs for automation and CI/CD tasks, and local models for privacy-restricted environments.

Across these use cases, developers are clearly no longer relying on a single tool. AI workflows increasingly involve choosing the right tool for the task at hand, be it writing code, refactoring, debugging, generating documentation, testing, or understanding unfamiliar code.

The JetBrains State of Developer Ecosystem Report 2025 indicates that developers frequently switch between AI access points in this way. They choose the interface that best fits the task rather than expecting one tool to handle everything.


Workflow types and examples

Workflow type Typical use case Example tools Integration context Developer benefit
In-IDE assistance Code suggestions, refactoring JetBrains AI Assistant, GitHub Copilot IDE Immediate, context-aware help
Chat-based interaction Explanations, brainstorming, regex, prototyping ChatGPT, Claude Browser / Cloud Fast iteration and reasoning
API integration Automation, CI tasks, documentation OpenAI API, Anthropic API Backend / DevOps Scalable automation
Browser extensions Quick inline code insights Codeium, AIX Web Lightweight access
Local/private models Secure, offline coding Tabnine, DeepSeek (self-hosted models) On-premises / Enterprise High privacy and control
Disclaimer: please note that the findings reflect data collected during the specific research period set out in the report.

With AI firmly established in daily workflows, the next section looks at regional differences in AI tool adoption.

Global snapshot: How AI tool adoption differs across regions

Global AI adoption patterns do not look the same everywhere. Regional ecosystems, regulations, and developer communities shape which tools gain traction. The JetBrains State of Developer Ecosystem Report 2025 highlights clear regional AI trends.

In North America, developers commonly adopt mainstream tools such as GitHub Copilot, JetBrains AI Assistant, and Claude-based assistants. Strong cloud infrastructure and rapid LLM innovation encourage experimentation with multiple tools.

European developers balance adoption with privacy considerations. Data residency and compliance requirements influence tool selection, leading to broader interest in solutions that offer transparency and local processing options.

In the Asia-Pacific region, developers often combine global tools with regional offerings. Mobile-first development cultures and fast-growing ecosystems drive rapid experimentation, particularly with cloud-based assistants.

Mainland China stands out due to its strong domestic AI ecosystem. Developers there frequently rely on local tools and models such as DeepSeek, Qwen, and Hunyuan, which align better with infrastructure and regulatory realities.


Regional highlights and local leaders

Region Most used tools Local ecosystem drivers Notable observations
North America GitHub Copilot, JetBrains AI Assistant, Claude Strong cloud and LLM innovation High multi-tool adoption
Europe JetBrains AI Assistant, GitHub Copilot Privacy regulations, data residency Balanced adoption across tools
Asia-Pacific GitHub Copilot, Gemini Mobile/cloud-first development cultures Rapid experimentation and growth
Mainland China DeepSeek, Qwen, Hunyuan Strong domestic AI ecosystem Preference for locally hosted models
Disclaimer: please note that the findings reflect data collected during the specific research period set out in the report.

While AI tool usage worldwide is undoubtedly gaining momentum, barriers to AI adoption also exist, which we explore in the next section.

Barriers to adopting AI tools

Despite growing interest, not all developers or teams adopt AI tools easily. The JetBrains State of Developer Ecosystem Report 2025 shows that such AI adoption challenges often stem from uncertainty rather than opposition.

Privacy and security concerns remain the most common AI coding tool barriers. Teams worry about exposing sensitive code or intellectual property, especially when tools rely on cloud processing. Without clear guarantees, organizations may restrict or ban usage.

Legal and ownership questions are other reasons why developers avoid AI tools. Developers and managers want clarity about who owns AI-generated code and how licensing applies. Uncertainty leads many teams to limit AI use to non-critical tasks.

Individual barriers matter as well. Some developers lack confidence in using AI tools effectively or struggle to evaluate output quality. Others distrust AI suggestions due to past inaccuracies.

Cost, licensing, and infrastructure constraints can also limit adoption, particularly for larger teams. Per-seat pricing and usage caps further complicate budgeting and rollout decisions.


Obstacles and evaluation criteria

Barrier Why it matters Typical impact
Privacy and security concerns Increases the risk of exposing sensitive code Usage blocked or restricted
IP and code ownership concerns Creates legal uncertainty Hesitation to rely on AI for core code
Lack of knowledge or training Reduces confidence in using tools Slower individual adoption
Accuracy and reliability issues Impacts trust in outputs More manual review required
Internal policies and processes Requires compliance and complex approval workflows Delayed tool rollout
Cost and licensing Exceeds budget or per-seat limits Partial or limited deployment
Disclaimer: please note that the findings reflect data collected during the specific research period set out in the report.

In the next section, we move from the barriers of today to developers’ hopes for the future.

Future of AI tools: What developers want next

Developers do not simply want more AI features. They want better ones. The JetBrains State of Developer Ecosystem Report 2025 not only indicates greater adoption but also shows that developers are hopeful about the future of AI. Their expectations focus on reliability, integration depth, and control rather than novelty.

Higher code quality tops developer AI expectations. Developers want fewer hallucinations, cleaner outputs, and suggestions that respect project conventions. Trust grows when AI behaves predictably.

Deeper IDE integration also ranks high. Developers expect future AI tools to understand entire projects, not just individual files. Context retention across sessions and multi-file awareness are increasingly important.

Privacy remains central. Many developers want local or on-device options that allow them to use AI without sharing code externally. Transparent data handling builds confidence.

Pricing clarity and explainability also influence future AI assistant trends. Developers want predictable costs and better insight into why tools suggest certain changes.

But most significantly, as AI tools evolve, developers want support for complex workflows and architecture reasoning. The goalpost is also shifting. Developers now expect future AI tools to move beyond basic autocomplete and act as collaborative partners.


Developer expectations and trends

Expectation Why developers want it Example improvements
Higher code quality Trust and reliability Fewer hallucinations, cleaner output
Deeper IDE integration Seamless workflows Context retention, multi-file awareness
Privacy and control Secure code handling On-device or local LLM options
Transparent pricing Predictable team adoption Usage-based models, clearer tiers
Explainability and reasoning Trust in decisions Clearer chain-of-thought summaries
Context awareness Handling real projects Larger context windows, project-wide understanding
Disclaimer: please note that the findings reflect data collected during the specific research period set out in the report.

The following FAQ addresses some of the most common questions developers ask when evaluating and using AI tools.

FAQ

What are the most popular AI tools among developers today?
According to the report’s findings, developers commonly use tools such as GitHub Copilot, JetBrains AI Assistant, Cursor, and Tabnine, often combining them rather than using a single tool.

Are AI tools safe for use with private or proprietary code?
Safety depends on the tool. Developers increasingly prefer tools that provide clear privacy policies or local processing options.

Which AI tools work best inside IDEs?
IDE-native tools tend to perform best for daily coding tasks because they understand project context and workflows.

Do developers prefer local AI models or cloud-based solutions?
Preferences vary. Some developers value cloud flexibility, while others prioritize local models for privacy and compliance.

How do AI tools help with debugging and documentation?
They explain code, identify errors, suggest fixes, and generate comments or documentation drafts.

Are AI tools suitable for enterprise teams with strict security requirements?
Many are, especially when they offer strong privacy guarantees, administrative controls, and predictable pricing.

Can AI tools speed up development without reducing code quality?

Yes, when developers use them intentionally. AI tools speed up repetitive tasks such as code generation, refactoring, testing, and documentation, while reviews, IDE checks, and automated tests help maintain quality.

Conclusion

AI tools have evolved from optional add-ons into essential components of modern software development. Developers now rely on them for coding, refactoring, documentation, testing, and learning, integrating AI assistance throughout daily workflows.

Current adoption trends show that developers value accuracy, deep integration, and privacy above experimental features. The JetBrains State of Developer Ecosystem Report 2025 reflects broad and growing use across regions, tools, and development styles.

As AI tools continue to evolve, they move toward deeper context awareness, stronger reasoning, and more secure deployment options.

For developers, AI no longer represents a future possibility. It has become a practical, everyday partner in building software.

Hashtag Jakarta EE #320

Hashtag Jakarta EE #320

Welcome to issue number three hundred and twenty of Hashtag Jakarta EE!

Ooops, I amn an little late publishing Hashtag Jakarta EE number 320. I am currently on my way home from Johannesburg and a successful JakartaOne by Jozi-JUG. I will write more about the event in a separate post next week. Speaking of next week, Immediately after returning from South Africa, I will head to San Jose, California for DeveloperWeek.

Since I have been busy traveling, I don’t have much update regarding what’s going on with Jakarta EE 12, but according to the minutes of the call this week, the estimated release date looks like it will be pushed out to Q4 this year. Delivering it in 2026 is the important aspect, not necessarily the month. This gives the platform team and the indivicual specifications a little more time to get their work don.

Registration for Open Community eXperience in Brussels, April 21-23 is open. I have a 20% discount code, so DM me if you are interested in attending this conference.

Ivar Grimstad


Pandas 3.0’s PyArrow String Revolution: A Deep Dive into Memory and Performance

Introduction

Pandas 3.0 made a game-changing decision: PyArrow-backed strings are now the default. Instead of storing strings as Python objects (the old object dtype), pandas now uses Apache Arrow’s columnar format with the new string[pyarrow] dtype.

But here’s the question that matters: How much does this new string dtype actually improve performance and memory usage in real-world scenarios?

To find out, I ran comprehensive benchmarks across diverse datasets and common string operations. The results? 51.8% memory savings on average, with operations running 2-27x faster.

This isn’t a theoretical improvement, it’s a fundamental shift in how pandas handles string data.

The Results: Summary Dashboard

Let me start with the headline numbers, then we’ll dive into how I got them.

Result Summary

The Four Key Metrics

1. 51.8% Memory Savings

Across all test datasets, the new PyArrow string dtype used half the memory of the old object dtype. This isn’t a marginal improvement, it’s transformative for memory-constrained environments.

2. 6.17x Average Operation Speedup

String operations aren’t just more memory-efficient: they’re dramatically faster. On average, operations like str.lower(), str.contains(), and str.len() run 6x faster with PyArrow strings.

Some operations are even more impressive:

  • str.len(): 27x faster
  • str.startswith(): 16x faster
  • str.endswith(): 15x faster

3. 889 MB Total Memory Saved

Across our test datasets (totaling 645 MB on disk), we saved nearly 1 GB of RAM in memory. For a real data pipeline processing dozens of datasets, this compounds quickly.

4. Memory Overhead: The Game Changer

The bottom chart reveals something crucial about how pandas handles strings:

Old string dtype (object):

  • CSV files on disk: 645 MB
  • Loaded into pandas: 1,714 MB
  • Memory overhead: 165.7% (more than doubles!)

New string dtype (PyArrow):

  • CSV files on disk: 645 MB
  • Loaded into pandas: 825 MB
  • Memory overhead: 27.9% (minimal overhead)

What does this mean?

When pandas reads a CSV file, it doesn’t just store the raw bytes: it creates in-memory data structures for fast operations. The old object dtype was incredibly inefficient, essentially duplicating string data multiple times. The new PyArrow string dtype keeps overhead minimal with a smarter memory layout.

This is the difference between pandas 2’s Python-object approach and pandas 3’s columnar Arrow approach.

The Methodology: Why 5 Different Datasets?

Now that you’ve seen the results, let me explain how I tested this. Real-world data comes in many shapes and sizes. A single benchmark on one type of data wouldn’t tell the whole story.

That’s why I created 5 distinct datasets, each representing common patterns you’ll encounter in production:

1. Low Cardinality Dataset (1M rows)

What it is: Repeated categorical values like product categories, status codes, regions, and priorities.

Why it matters: This is typical of business data – think order statuses, customer segments, or department codes. The same values repeat millions of times.

Example columns:

  • category: “Electronics”, “Clothing”, “Food” (10 unique values)
  • status: “pending”, “completed”, “failed” (4 unique values)

2. High Cardinality Dataset (1M rows)

What it is: Mostly unique strings like user IDs, email addresses, and session tokens.

Why it matters: When every row is different (like customer emails or transaction IDs), pandas can’t use simple optimizations. This tests worst-case scenarios.

Example columns:

  • user_id: “USER_00000001”, “USER_00000002″… (1M unique)
  • email: “user123@example45.com” (1M unique)

3. Mixed String Lengths Dataset (1M rows)

What it is: A combination of short codes (2-5 chars), medium names (20-50 chars), and long descriptions (100-300 chars).

Why it matters: Real data isn’t uniform. You might have product codes next to customer addresses next to order notes. This tests how pandas handles variable-length strings.

4. Dataset With Nulls (1M rows)

What it is: Data with missing values (10-33% nulls in different columns).

Why it matters: Messy data is reality. How does pandas 3.0 handle missing string data compared to pandas 2?

5. Large Dataset (10M rows)

What it is: A scaled-up version to test performance at scale.

Why it matters: Memory savings that look good at 1M rows might behave differently at 10M rows. This validates the findings scale linearly.

Memory Savings by Dataset Type

Memory Consumption Comparison

The memory savings from PyArrow strings vary significantly by dataset characteristics:

Best Case: Low Cardinality Data (-71.6%)

When data has repeated values (like categories), PyArrow strings shine:

  • Object dtype: 219 MB
  • PyArrow string dtype: 62 MB
  • Savings: 71.6%

Worst Case: Mixed String Lengths (-30.6%)

Variable-length strings see smaller (but still significant) savings:

  • Object dtype: 383 MB
  • PyArrow string dtype: 266 MB
  • Savings: 30.6%

The Pattern

Notice how savings correlate with data characteristics:

  1. Repeated values (low cardinality) → Best savings (64-72%)
  2. Unique values (high cardinality) → Good savings (53-55%)
  3. Variable length (mixed sizes) → Moderate savings (31%)

Takeaway: PyArrow strings help everywhere, but they’re especially powerful for categorical-like data.

Performance: Operation-Specific Speedups

Operation Speedup Heatmap

This heatmap shows how much faster PyArrow strings are compared to object dtype for common string operations (values > 1.0 mean PyArrow is faster).

The Fastest Operations

  1. str.len(): 10-27x faster

  2. str.startswith() and str.endswith(): 11-18x faster

  3. str.contains(): 3-5x faster

  4. str.split(): 1-8x faster

The Pattern

Read operations (like len(), startswith()) → Massive speedups (10-27x)

  • These operations just examine existing data without modification

Transform operations (like replace(), split()) → Good speedups (2-5x)

  • These operations create new data, which limits the performance gains

The Trade-off: CSV Loading Time

Load Time Comparison

There’s no such thing as a free lunch. While PyArrow strings save memory and run operations faster, loading CSV files is 9%-61% slower.

Why the Slowdown?

When pandas reads a CSV with PyArrow strings enabled:

  1. It parses the text (same as before)
  2. It converts strings to PyArrow’s columnar format (extra step)
  3. This conversion involves building dictionary encodings and optimized memory structures

Pandas is doing more work upfront to enable better performance downstream.

Real-world impact: On our 10M row dataset, the difference is 1.63s vs 2.02s, an extra 0.4 seconds for 10 million rows. For many data pipelines, this upfront cost might be negligible compared to the 2-27x speedup in subsequent operations.

Pros and Cons: Should You Adopt PyArrow Strings?

Benefits of PyArrow String Dtype

  1. Massive Memory Savings (30-72%)

  2. Dramatically Faster String Operations (2-27x)

  3. Minimal Memory Overhead (28% vs 166%)

  4. Modern Data Ecosystem Integration

Trade-offs to Consider

  1. Slower CSV Loading (9-61% slower)

    • Initial data ingestion takes longer
    • May impact workflows that repeatedly load small files
    • The trade-off: slower start, much faster operations
  2. Behavioral Changes

    • String dtype behaves differently from object dtype in edge cases
    • Need to update code that explicitly checks for object dtype
    • Testing required for migration

The Recommendation

For most data workflows, PyArrow strings are a clear win. The memory and performance benefits far outweigh the trade-offs.

Consider staying with object dtype if:

  • You rarely work with string columns
  • Your datasets easily fit in memory
  • Load time is critical and you rarely perform string operations
  • You have legacy code that’s deeply coupled to object dtype behavior

Definitely adopt PyArrow strings if:

  • You process large datasets with text data
  • String operations are a significant part of your workflow
  • Memory is a constraint in your environment
  • You’re building production data pipelines
  • You work with modern data tools (Parquet, Arrow, DuckDB, etc.)

Conclusion

Our comprehensive analysis across 5 diverse datasets and 15+ string operations conclusively shows that PyArrow-backed strings deliver transformative improvements:

  • 51.8% average memory savings across all dataset types
  • 6.17x average operation speedup for string operations
  • Minimal memory overhead (28% vs 166% with Python objects)

PyArrow strings aren’t just an incremental improvement, they’re a fundamental reimagining of how pandas handles text data. By adopting Apache Arrow’s proven columnar format, pandas has joined the modern data ecosystem while delivering massive performance and memory improvements.

For most data practitioners working with text data, the question isn’t “Should I use PyArrow strings?” but rather “How quickly can I migrate?”

Questions or feedback? Feel free to open an issue or contribute to this analysis! The code we used in this analysis has been uploaded to this repo.

Reporails: Copilot adapter, built with copilot, for copilot.

This is a submission for the GitHub Copilot CLI Challenge

What I Built

Reporails is a validator for AI agent instruction files: CLAUDE.md, AGENTS.md, copilot-instructions.md. It scores your files, tells you what’s missing, and helps you fix it.

The project already supported Claude Code and Codex. For this challenge, I added GitHub Copilot CLI as a first-class supported agent – using Copilot CLI itself to build the adapter.

The architecture was already multi-agent by design. A .shared/ directory holds agent-agnostic workflows and knowledge. Each agent gets its own adapter that wires into the shared content. Claude does it through .claude/skills/, Copilot through .github/copilot-instructions.md.

Adding Copilot took 113 lines. Not because the work was trivial – but because the architecture was ready.

Repos:

  • CLI: reporails/cli (v0.3.0)
  • Rules: reporails/rules (v0.4.0)
  • Recommended: reporails/recommended (v0.2.0)

Demo

After adding Copilot support, each agent gets its own rule set with no cross-contamination:

Agent Rules Breakdown
Copilot 29 30 CORE – 1 excluded + 0 COPILOT-specific
Claude 39 30 CORE – 1 excluded + 10 CLAUDE-specific
Codex 37 30 CORE + 7 CODEX-specific

Run it yourself:

npx @reporails/cli check --agent copilot

My Experience with GitHub Copilot CLI

It understood the architecture immediately

I explained the .shared/ folder — that it was created specifically so both Claude and Copilot (and other agents) can reference the same workflows and knowledge without duplication. Copilot got it on the first exchange:

Copilot understanding .shared/ architecture

Copilot understanding .shared/ architecture

The key insight it surfaced: “The .shared/ content is already agent-agnostic. Both agents reference the same workflows. No duplication is needed – just different entry points.”

That’s exactly right. Claude reaches shared workflows through /generate-rule.claude/skills/.shared/workflows/rule-creation.md. Copilot reads instructions → .shared/workflows/rule-creation.md. Same destination, different front doors.

What it built

Copilot created the full adapter in three phases:

  1. Foundation.github/copilot-instructions.md, agents/copilot/config.yml, updated backbone.yml, verified test harness supports --agent copilot
  2. Workflow Wiring – entry points in copilot-instructions.md, context-specific conditional instructions, wired to .shared/workflows/ and .shared/knowledge/
  3. Documentation – updated README and CONTRIBUTING with agent-agnostic workflow guidance

Copilot Contribution Parity Complete

Copilot Contribution Parity Complete

The bug it found (well, helped find)

While testing the Copilot adapter, I discovered that the test harness had a cross-contamination bug. When running --agent copilot, it was testing CODEX rules too — because _scan_root() scanned ALL agents/*/rules/ directories indiscriminately.

The fix was three lines of Python:

# If agent is specified, only scan that agent's rules directory
if agent and agent_dir.name != agent:
    continue

Test Harness Agent Isolation FixTest Harness Agent Isolation Fix

The model selector surprise

When I opened the Copilot CLI model selector, the default model was Claude Sonnet 4.5. The irony of building a Copilot adapter using Copilot CLI running Claude was not lost on me.

What worked, honestly

Copilot CLI understood multi-agent architecture without hand-holding. It generated correct config files matching existing adapter patterns. The co-author signature was properly included in all commits. It didn’t try to duplicate content that was already shared – it just wired the entry points.

The whole experience reinforced something I’ve been thinking about: the tool matters less than the architecture underneath. If your project is structured well, any competent agent can extend it. That’s the whole point of reporails – making sure your instruction files are good enough that the agent can actually help you.

What also happened during this challenge

While building the Copilot adapter, I also rebuilt the entire rules framework from scratch. Went from 47 rules (v0.3.1) to 35 rules (v0.4.0) – fewer rules, dramatically higher quality. Every rule is now distinct, detectable, and backed by evidence. But that’s a story for another post.

Try it: npx @reporails/cli check

GitHub | Previous posts

I built WikiPilot with GitHub Copilot CLI

This is a submission for the GitHub Copilot CLI Challenge.

## What I Built

I built WikiPilot, a local-first, AI-powered CLI that generates a structured wiki for real codebases with
source-grounded evidence.

Instead of manually writing docs that drift over time, WikiPilot analyzes repositories, extracts symbols, plans
pages, generates documentation, validates quality, and outputs a static viewer-ready wiki.

### Key capabilities

  • Evidence-first docs: generated sections include source references and confidence scoring.
  • Incremental updates: processes changed files by default, with full rebuild support.
  • Multi-language analysis: TypeScript/JavaScript and C# support.
  • Machine-readable outputs: manifests, codemap, quality reports, and wiki plan artifacts.
  • Viewer experience: static docs viewer with navigation, TOC, and Mermaid support.

### Why this matters
WikiPilot makes documentation more auditable, repeatable, and CI-friendly, so teams can keep
architecture knowledge close to the code without heavy manual curation.

## Demo

  • Repository: https://github.com/HariharanS/wikipilot
  • Screenshots:

### Suggested walkthrough (60–90 seconds)

  1. Show .wikipilot.yml and explain the target repo setup.
  2. Run generation (generate) and show incremental + quality outputs.
  3. Open generated markdown and point to evidence/source grounding.
  4. Launch viewer (serve --build) and show navigation + rendered docs.
  5. Close with one practical “before/after” outcome (time saved, clearer onboarding, etc.).

## My Experience with GitHub Copilot CLI

GitHub Copilot CLI acted like a development copilot across architecture iteration, implementation, and debugging
loops while building WikiPilot.

I used it to speed up:

  • CLI command design and refactors
  • prompt/schema iteration for generation quality
  • debugging pipeline edge cases
  • improving developer UX and docs

### Example Copilot CLI workflows I used


bash
   copilot "help me design a CLI flow for generate/serve/evaluate-models commands"
   copilot "review this module and suggest a safer refactor with minimal changes"
   copilot "debug why this output quality check is failing and propose a fix"
   copilot "draft docs for this command based on code behavior"
  Impact
  Copilot CLI reduced context switching, accelerated iteration on tricky parts (generation + validation), and helped

** Ran out of copilot credits **
- missing features to deploy to cloud
- use improved prompts and regenerate docs to improve quality of docs produced
  keep momentum from idea to working end-to-end tool.
  What I learned
   - Evidence-grounded AI output is much more trustworthy than free-form generation.
   - Incremental pipelines are critical for real-world repo scale.
   - Good DX (clear commands, predictable outputs, quality reports) matters as much as model quality.
  What’s next
   - Better cross-repo relationship visualization
   - More language analyzers
   - Richer interactive viewer exploration and traceability