Back to Blog

Cursor vs Copilot vs Windsurf: How Different AI Agents Write Code from the Same Instructions

Artur Valokhin - dev.family
Artur Valokhin
lead frontend developer

Sep 25, 2025

13 minutes reading

Cursor vs Copilot vs Windsurf: How Different AI Agents Write Code from the Same Instructions - dev.family

Recently, I demonstrated how to accelerate the development of the admin panel using Admiral, a React-based back-office framework developed by the dev.family team. Explore it on GitHub: https://github.com/dev-family/admiral.    

Initially, I used Cursor rules, which are plain-text instructions that AI agents can interpret and convert into actual code. However, I then realized that this approach isn't exclusive to Cursor. These rules are just .md files – essentially prompts – that you can read or reuse across other AI tools, such as GitHub Copilot, Windsurf, Replit, Zed, Continue, and more. 

I decided to run an experiment to test how well three tools – Cursor, Copilot, and Windsurf – handle the same set of admin panel rules. My goal? To adapt the Cursor-based rule set for each platform and see if I could get similar results.

Rule Capabilities Comparison 

To start, I compiled a table that breaks down the key features of each tool, including rule types, storage location, activation modes, and length limits.

Feature

Cursor

Windsurf

Copilot

Rule Types

Project-wide, local, global

Project-wide, local, global

Project-wide, local

Storage Location

.cursor/rules 

.windsurf/rules

.github/copilot-instructions.md .github/instructions

Nested Rules Support

Multiple Rules Support

Activation Modes

Mention, always-on, glob pattern, agent decision

Mention, always-on, glob pattern, agent decision

Always-on, glob pattern

Length Limit

Recommended: 500 lines

Max: 12,000 characters

No official limit info

Rule Types

Each tool has its own level of rule application. Here's how they work:

  • Project-wide rules apply to the entire codebase within a specific project;
  • Project-local rules also work within the same project but can be scoped to specific files or directories;
  • Global rules are available across all projects where the tool is installed.
👉 In Copilot, you can define one or more project-wide rule files or use glob patterns to target specific files or folders. However, Cursor and Windsurf offer more: they support global rules that apply across all projects in your IDE and allow rules to be triggered by direct mentions.

As a result, Copilot offers fewer options compared to its competitors when it comes to rule flexibility and activation.

Storage Location

This refers to where each tool stores its rule files, which is usually in a dedicated folder or a specific file in the root of the repository. Ideally, there would be a unified structure compatible with different AI tools. But in practice, each tool uses its own format. However, Windsurf supports importing rules from the .cursor directory if it’s already present in the project.

Nested Rules Support 

This refers to the ability to place rule files in subdirectories, which is a particularly useful feature for monorepos because different parts of a project may require different sets of instructions.

While Copilot doesn't directly support nested rule files, it lets you configure the context in which a rule applies, such as using glob patterns.

applyTo: "src/app/**/*.ts"

Multiple Rules Support

All three tools allow you to apply multiple rules simultaneously, which is a key feature for complex projects that require different types of logic or constraints.

Activation Modes

Each tool has its own methods for determining when and where a rule should apply:

  • Mention-based – the rule is triggered via direct mention or reference;
  • Persistent – the rule is always active, with no additional conditions;
  • Glob pattern – the rule only applies to files that match a specified pattern;
  • Agent decision — the AI determines whether to apply the rule based on its own internal logic.

Length Limitations

Each tool may have recommendations or limits for rule length. These constraints can affect performance, usability, and the number of tokens consumed, which impacts the tool’s cost and efficiency.

Rule-in-Rule Support

We also explored referencing one rule inside another. This could be helpful when handling certain logic variations conditionally. For instance, one rule could outline the general process for creating a page while delegating type-specific logic to distinct rules.

Let's create two simple example rules to test this concept.

test1.md

Write Hello in the chat

After that use @test2.md rule

test2.md

Write Bye-bye in the chat

The first rule instructs the AI to apply the second rule once the first is complete.

Cursor handles this perfectly. It executes everything exactly as instructed without adding unnecessary text.

<span>Rule-in-Rule Support</span>

Windsurf only partially succeeded on the third attempt.

<span>Rule-in-Rule Support</span>

Clearly, Cursor has a much better understanding of what’s expected of it.

<span>Rule-in-Rule Support</span>

Since Copilot doesn't support rule activation by mention, there's nothing to test in this case.

Evaluating Rule Effectiveness

Now, let's move on to the fun part: testing how well each tool handles our custom instructions for generating CRUD structures in projects built with the Admiral library.

We’ll add the rule to the appropriate location so the tool can recognize it, and then try using it in practice.

The rule expects a list of seven input points, which I’ve prepared in advance:

1. clients.

2. clients.

3. id, full_name, phone, email, created_at, actions.

4. surname, phone, first_name, email, patronymic, gender, birthday, previous_surname, password, uuid_1c, deleted_at, document_type, document_number, document_expiry_date, birth_address, settings_is_notify_upcoming_payments.

5. 

6. id, phone, email, full_name

7. 

Let’s see how the rule performs across different tools.

Windsurf

The rule itself contains all the necessary instructions. It was designed so that simply mentioning it in the chat would prompt the agent to request all the necessary information. Let's try that and see if the agent reads the rule file and provides a brief summary.

<span>Windsurf</span>

Next, we will simply send the list and hope the agent takes it from there. It worked – the agent understood the task and generated the entire required codebase.

Result

On the first try, the entire codebase was generated without any critical errors: сomponents were selected correctly and attributes were used properly. However, the application failed to run due to the incorrect folder structure. Instead of placing the clients directory inside the existing src/crud, the agent created it in the project root which wasn’t what the rule described.

On the second attempt, the structure was correct. The app launched successfully, and all pages rendered as expected.

Copilot

Things got trickier here. Copilot applies any rule automatically to all prompts, as long as the file matches the glob pattern. That means if you create a rule for generating CRUD structures, it will trigger on every prompt in matching files because you can’t restrict its activation scope. 

Still, we decided to test it anyway to see if it’s usable in practice. Just like with Windsurf, we placed the rule file inside .github/instructions.

Since Copilot does not have the ability to activate a rule based on a mention, we will compose a more detailed query manually.

The agent read the rule, outlined a structure, and generated a Frankenstein project that was completely unrelated to the rule or the actual project.

Result

The generated code couldn’t even be run. The file structure was technically correct, but the content inside the files didn’t match the expected output.

It tried to import components from packages that weren’t even installed like @pankod/refine-antd. The file structure didn’t align with what the rule described.

In one of the typed templates, it imported a nonexistent type from an empty file. It also used types and functions from Next.js, even though that framework wasn’t being used in the project.

To top it off, there was an empty file for types, and the rest of the code tried to import from it anyway.

Bottom line: too many issues to count, and the final codebase is completely unusable.

Key Takeaways

Here’s what I learned from this experiment:

  1. Cursor once again proved to be the most reliable tool – it followed the rules precisely and delivered exactly what was expected.
  2. Windsurf came in second: it didn’t get it right on the first couple of tries, but eventually generated the correct output.
  3. Copilot, for now, isn’t suitable as a primary tool for this kind of work. Its rule support is still too limited compared to fully AI-powered IDEs.

That said, Copilot still has its strengths especially when you want to:

  • define global project-wide rules (e.g., for code style or naming conventions);
  • provide high-level structure to help the tool understand where to place new entities.

But if you're looking to use custom rules that can be triggered on mention, your best bets are still Cursor or Windsurf.

Still have questions about Cursor, Copilot, and Windsurf? We're here to help!

You may also like: