Understanding Cursor: key features, limitations, and how to use it

16 min read
April 15, 2025

AI tools are quickly becoming part of everyday software development. 

And Cursor is one of the more ambitious ones out there.

It’s built to do more than autocomplete. It reads your codebase, makes large-scale changes, runs terminal commands, and even refactors entire projects. 

But with that level of control comes a big question – how well does it actually work in real-world dev environments?

We spent time working directly in Cursor to see what it’s like to build, refactor, and review code with it by your side.

In this article, we’ll walk you through the key features, real examples of how it performs, and the trade-offs you should know before using it in your workflow

Let’s dive in!

Key Cursor features

First, we’ll start with an overview of Cursor’s main features and functionalities.

Reading and understanding your codebase

Cursor doesn’t start from scratch. It reads your codebase first.

It scans the project to understand how files connect and looks at folder structure, dependencies, and naming patterns. That context makes a big difference.

When asked to generate backend logic, it uses the right packages automatically. Not just generic imports – it grabs the actual ones already used in the project.

In one case, it installed frontend and backend dependencies without being told exactly which ones to use – it figured it out from the code itself.

This makes small prompts go further. 

You don’t have to explain everything, Cursor already knows your project’s setup.

But if your code is messy or inconsistent, that context can also mislead it. 

Cursor can only work with what it sees. The GIGO (garbage in, garbage out) principle still holds. 

So, writing clean code helps it help you.

Reading documentation

Cursor also gives you a way to add more context manually. 

There’s a feature called “docs” where you can input extra information like product specs, logic overviews, or rules on how the app should behave.

You just open the “new doc” tab and reference it by link or URL.

This works especially well when the codebase alone doesn’t tell the full story.

For example, when generating frontend components that followed a specific UX rule, Cursor did much better after being shown a short doc explaining that rule.

Without that doc, it missed the mark. But with it, it nailed the flow.

It’s like giving it a cheat sheet. You can’t expect great results if you don’t give it what it needs to understand the goal.

If your code has weird business logic or domain-specific quirks, this feature is essential.

Agent mode

Agent mode is where Cursor starts to feel less like an assistant and more like a teammate.

With a single prompt, it can update multiple files across your codebase.

For example, when asked to refactor a Go service, it didn’t just touch the main file – it created a proper structure, split logic into smaller, focused files, and rewrote the imports.

It wasn’t just cosmetic cleanup. These were structural changes that made the code easier to work with. 

You could take what Cursor wrote, tweak a few lines, and push to production.

But this kind of power has a flip side.

Sometimes, it makes changes in places you didn’t expect. 

It might jump into related files or update shared logic that wasn’t explicitly mentioned. That can be helpful, or a mess, depending on what you’re working on.

The big takeaway here? You need to review everything. Don’t trust it blindly. 

Agent mode can do a lot with very little input, but that doesn’t mean it always should.

Terminal command execution (YOLO mode)

Cursor can also execute terminal commands directly inside its interface.

That’s not a joke. You type a command, and it runs it, right there.

It installs packages, updates configs, runs scripts, and spits out the terminal output on screen.

And it works. But it also earned the nickname “Yolo Edition” for a reason.

By default, there’s nothing stopping it from doing whatever it wants in the terminal. That’s very risky. 

0263L1000107 2 10

It could accidentally run a command that changes file permissions, wipes something, or pushes a bad commit.

Luckily, there’s a way to limit this.

You can set rules that require manual approval before any terminal command is executed. 

Once these restrictions are in place, Cursor respects them. It’ll ask before running anything, which makes this feature way more usable – and less terrifying.

It’s powerful, especially when you’re spinning up environments or installing dependencies.

But you need to handle it with care. This isn’t a sandbox – it’s your actual terminal.

Single and multi-file refactoring

Refactoring is one area where Cursor really shines.

Feed it a large, bloated file and ask it to break things up – and it does exactly that. 

It separates logic into packages, applies naming conventions from your codebase, and even drops in useful comments.

For example, we turned a messy prototype all-in-one Go file into a tidy, multi-file service with handlers, utilities, and routing logic cleanly split apart. 

It didn’t just guess, it followed our existing patterns.

It’s also great for cleanup work. You can ask it to:

  • Restructure a component
  • Extract a helper
  • Turn repeated logic into a reusable function

In most cases, it gets the structure right and writes clean, idiomatic code.

It won’t always make perfect design decisions. But it will give you a solid starting point. 

And if you’re working against a deadline, that alone makes it worth using.

Cursor won’t replace your judgment. But for speeding up the boring parts of refactoring? It’s a game-changer.

Potential for web search and repo integration

This part is still early, but it’s worth mentioning.

There’s talk about Cursor supporting web search.

That would let it look up missing pieces online, like documentation or usage examples. In theory, it could search public APIs or StackOverflow-style content.

Even more interesting is the mention of repo integration. 

Cursor might soon be able to pull context from private repositories, not just the one you’re working in. That would open up a lot of possibilities. 

Imagine giving it access to both frontend and backend repos and asking it to build a feature that spans both. Or referencing a shared component library that lives in a separate repo.

Right now, this isn’t fully implemented. 

But it’s clear the goal is to make Cursor smarter by letting it see more than just one code folder.

When that happens, the line between “assistant” and “collaborator” will get even blurrier.

Cursor limitations and challenges

Next, we’ll cover some limitations and challenges you should be aware of when using Cursor.

Errors and inconsistencies in output

Cursor isn’t magic. It gets things wrong.

For example, when working in a folder with nested submodules, it failed to detect the right context.

It edited the wrong file and missed key dependencies. Nothing broke immediately, but the logic was off.

Same goes for reused prompts. 

The exact same request on two different days gave different results. One time it added a new helper function. The next time, it reused an existing one.

That kind of unpredictability can make it hard to trust.

Sometimes, Cursor invents functions that don’t exist in your codebase. 

You’ll see a call to something like getUserData(), but it’s not defined anywhere. It’s just assuming.

That’s not always a problem if you know what to look for. But if you’re moving fast, it’s easy to miss.

So, while Cursor can help you code faster, it can also leave you cleaning up weird mistakes later.

Merge conflict handling

Merge conflicts are a part of real-world development, especially in larger teams.

Any tool that can’t handle them reliably isn’t ready to replace your main workflow just yet.

It’s unclear whether Cursor can fully resolve tricky conflicts like .pbxproj files on iOS.

That said, Cursor does offer some early tools to help.

When it detects a merge conflict, it can highlight the differences and suggest AI-generated resolutions. You can review those and either accept the suggestions or edit them manually.

It’s a decent first step. But not a full replacement for mature tools like IntelliJ or GitKraken, which let you resolve conflicts visually – “accept left,” “accept right,” or both – without leaving the IDE.

The Cursor community has already asked for these kinds of features, so the demand is clear. 

Until they land, though, expect to handle your bigger or more sensitive merges elsewhere.

Cursor is moving in the right direction, but for now, it’s still better at writing code than resolving your trickiest conflicts.

Issues with image handling

Cursor doesn’t handle images out of the box.

In one test, a prompt asked it to fetch a specific image from a URL. It wrote the code to use the image but didn’t actually download it.

Turns out, it can do it, but only if you tell it to do it explicitly. 

You have to add a line like “download this image and save it to /assets.

Without that, it just assumes the file is already there.

Not a huge issue, but something to remember when working with assets.

Terminal command risks

Cursor can execute real terminal commands. That’s impressive – but it can also go very wrong.

In one example, it ran a terminal command that modified Git settings and committed changes, all without a confirmation. 

It did what it was told. But it didn’t ask if it should.

That’s the risk.

If you don’t set up “Cursor Rules” to block or confirm terminal commands, Cursor gets full control. And that’s not something you want on day one.

It can run npm install. Or rm -rf. Or anything in between.

Once you add rules to require approval, things get safer. 

Cursor paused before running anything and asked first. That made the feature way more useful.

The terminal is one of its best features. It’s also the one most likely to wreck your project if you’re not careful.

Lack of feedback during processing

One thing that stands out: Cursor doesn’t always tell you what it’s doing.

You’ll see a loading bar. That’s about it.

When it’s slow, there’s no detailed output.

You don’t know if it’s thinking, stuck, or waiting for something. And that can be frustrating, especially when you’re mid-task.

In one case, after giving a long prompt, the interface just sat there. No errors. No output. Just spinning. Eventually, it worked. 

But if something goes wrong, you won’t always know why. There’s no real-time feedback or debug log.

That’s a limitation. It’s not a dealbreaker, but it does slow down your workflow if you’re trying to move fast.

Treat Cursor like a teammate that’s bad at giving status updates. 

You’ll get something useful eventually. But don’t expect detailed progress along the way.

How to work with Cursor

Finally, we’ll give you some tips on how to successfully work with Cursor and make the most of it.

Choose the right AI model

Cursor doesn’t lock you into one AI model. 

You can pick what works best for your task. We used Claude when demoing Cursor and it performed well. 

But you can easily add other models, too.

Here are all the models you can use:

Cursor supported AI models

You can plug them in via API or even run them locally, if that’s your thing.

That sounds like full control. But there’s a catch.

Even with local models, Cursor still relies on its own backend for some parts of the workflow. Specifically, the way it processes prompts and manages context.

So if you’re expecting a fully offline setup, you won’t get it. Cursor’s backend still plays a role in how everything runs.

Still, choosing your model gives you more flexibility. 

You can tailor your setup based on accuracy, speed, or cost. And that’s a big plus if you’re working on a specific type of project, like mobile, backend, or ML.

The real win here? You’re not boxed in. You can shape Cursor to fit your specific needs and the way you work.

Write clear prompts

Cursor doesn’t read your mind. If your prompt is vague, it’ll guess. 

And that guess might be wrong. Clear, specific prompts get the best results. 

You should think like a product manager writing a ticket. You’re not chatting, you’re giving instructions.

For example, a prompt like: “Add user authentication” will give you a generic result.

A prompt like this is much better:  “Add JWT-based user authentication using Go. Use the existing auth middleware and update the /login route. Save the token in local storage.”

That prompt gave back working code and respected the folder structure. It even followed the naming pattern used elsewhere in the repo.

Too much fluff slows it down. Cursor isn’t looking for a story, it’s looking for clarity.

Short sentences and clear actions. That’s how you get it to do real work.

Review before accepting code changes

Cursor shows you every change before it applies them. 

You’ll see modified files. And inside those, you’ll see modified blocks.

You can approve or reject changes line by line. That’s a good thing, because Cursor can go off-script.

When using agent mode, it sometimes edits helper files, even if your prompt didn’t mention them. That’s not a bug, it’s how it tries to connect the dots. 

But if you’re not careful, it might rewrite something critical.

One prompt changed multiple files and almost broke a build because it edited a shared utility incorrectly.

Luckily, the changes were easy to spot. File-level review would’ve missed it, but block-level saved the day.

Bottom line: never accept everything at once. 

Review every change like you would a pull request from a new hire.

Define rules to manage AI behavior

Cursor gives you ways to rein it in.

There’s a feature called Cursor Rules

You can use it to set hard limits on what the AI is allowed to do. Think of it like a safety net for your project.

For example, if you don’t want Cursor to run any terminal commands without asking, you can create a rule for that:  “Don’t execute terminal commands without permission.”

That was all it took.

From that point on, every time Cursor tried to run something, it paused.

It showed the command and waited for user approval. This turned the terminal from a risk into a controlled tool.

You can also create your own rules from scratch. 

The interface has an “add new rule” option. You write the description, define the restriction, and that’s it.

Rules don’t make Cursor perfect. But they give you a buffer. 

You’re no longer relying on it to just “do the right thing.” You’re telling it what’s off-limits.

That alone makes Cursor way more usable in real-world projects.

Cursor vs. GitHub Copilot: how do they compare?

If you’ve used GitHub Copilot, you might be wondering how Cursor stacks up. 

Both tools aim to help you write better code faster – but they approach the problem differently.

Here’s a quick side-by-side breakdown:

Cursor vs. GitHub Copilot: comparison

FeatureCursorGitHub Copilot
Codebase awarenessUnderstands your whole codebaseSingle file focus
Edits and code generationMulti-file edits and generationLine-by-line suggestions
Chat supportChat interface with contextNo interactive chat
PlatformBuilt on VSCodeIDE plugin only
PricingFree for individual usePaid subscription
Language supportSupports all major languagesLimited language support

Copilot is simpler and more lightweight, but less powerful when it comes to full-project tasks.

Cursor offers deeper context awareness and more flexibility for larger projects, so it’s more useful in a professional environment.

And it can explain complex code blocks in simple terms, making it perfect for both juniors and seniors.

We’ve tested both – and for real-world software development, we definitely recommend Cursor.

It does more of the heavy lifting, especially when you’re working on something bigger than a single function.

Cursor pros and cons

But as much as we like Cursor, it’s not without its flaws.

Here’s a quick overview of its pros and cons:

Pros


  • Increased productivity
  • Context-aware assistance
  • Powerful code generation
  • Customizable setup
  • Useful learning tool

Cons


  • Learning curve
  • Cluttered UI
  • Occasional inaccuracies
  • No full local-only mode

Still, the pros easily outweigh the cons – especially if you’re working on complex projects where speed and structure matter. 

Just take the time to set it up right, and you’ll get a lot out of it.

Cursor free vs. paid plans: is it worth it?

Cursor offers a free version that gives you a taste of its capabilities. 

You get access to core features like autocomplete, chat, and basic agent functionalities. 

However, there are limits. 

Free users are limited to 50 slow premium requests and 2000 code completions per month. And once they run out, you have to wait for your next reset date.

So if you use them all up in one day, you’ll have to wait a month for it to reset or upgrade to a paid plan before you can use Cursor again.

Here’s an overview of their paid plans:

Cursor paid plans

If you’re just testing Cursor out to see how it works and if it fits your workflow, the free plan is more than enough.

But, if you plan to use it extensively (as an individual), the Pro plan ($20/month) should be up your alley.

And if you’re getting it for your whole team and need advanced security features, the Business plan ($40 per user/month) is likely the best fit.

So, in short, if you’re serious about using Cursor, getting a subscription is absolutely worth it.

Understanding Cursor: FAQs

It can get close, especially for repetitive or boilerplate tasks. But like any junior developer, its output still needs reviewing.

It’s a productivity booster, not a replacement for real code reviews.

You can use local models or your own API keys, but Cursor still relies on its backend for certain operations. It’s not fully offline yet.

If you’re using Cursor daily in real projects, yes.

The Pro version removes usage limits, speeds up responses, and makes the tool much more practical for professional use.

Conclusion

Cursor isn’t just another AI plugin. 

It’s a serious tool with real potential to change how developers work.

It can refactor code, execute commands, and respond to prompts in ways that actually save time. 

But it also needs guardrails. And a human in the loop.

If you’re thinking about bringing AI into your workflow, Cursor is worth trying. 

Just know when to trust it – and when to take matters into your own hands.

And if you want to learn more, check out our other articles on everything software development and AI – you won’t regret it!

Categories
Written by

Toni Vujevic

Software Engineering Team Lead

Skilled in React Native, iOS and backend, Toni has a demonstrated knowledge of the information technology and services industry, with plenty of hands-on experience to back it up. He’s also an experienced Cloud engineer in Amazon Web Services (AWS), passionate about leveraging cloud technologies to improve the agility and efficiency of businesses. One of Toni’s most special traits is his talent for online shopping. In fact, our delivery guy is convinced that ‘Toni Vujević’ is a pseudonym for all DECODErs.

Related articles