Hubert Grzesiak logoHubert Grzesiak
AboutServicesWorkBlogVersions
Resume
HomeAboutCase StudiesBlogDevelopersResumeContactPrivacy

© 2026 Hubert Grzesiak. All rights reserved.

The AI Tools I Actually Use Daily as a Frontend Developer

ai developer-tools productivity nextjs

A breakdown of the four AI tools in my daily frontend workflow, their exact boundaries, and why keeping their responsibilities narrow saves time.

Estimated reading time: 5 minute(s)


Most AI tool lists read like sponsored roundups. These four tools are the ones installed on my machine and open during active client and portfolio work.

A lot of software developers spent the last two years collecting AI subscriptions. At one point, I had five different browser tabs open for chat interfaces, two IDE extensions arguing over tab completion, and an experimental CLI agent that rewrote half my git history by mistake.

Most of that got stripped out. The setup that survived is smaller, quieter, and split by clear jobs. When an AI tool does one thing well, it stays in the workflow. When it tries to do everything, it usually wastes twenty minutes of manual cleanup.

Here are the four tools I keep, along with the boundaries I set for each.

1. Cursor for inline edits and local context

Cursor replaced standard VS Code as my primary editor. The main reason is not full-code generation; it is fast inline edits using Cmd+K and tab completions that predict edits across files.

Where standard autocompletion suggests the next word, Cursor looks at recent tab history, open files, and the current git branch. When I rename a prop in a TypeScript interface, Cursor usually suggests the matching change in the consuming component before I finish typing the first letter.

// types/booking.ts
export interface BookingRequest {
  id: string;
  guestCount: number;
  checkInDate: string;
  checkOutDate: string;
  specialRequests?: string;
}

If I update checkInDate to startDate, Cursor recognizes the pattern in the corresponding form handlers and table columns. That eliminates mundane typing without handing over the thinking.

The boundary rule for Cursor: I use it for single-file edits, quick refactors, and inline completions. I do not use its composer for entire feature builds across ten files because that level of multi-file coordination is handled better in the terminal.

2. Claude Code for terminal tasks and git operations

When work spans multiple files, involves running tests, or requires inspecting build errors, I move to the terminal and use Claude Code.

Unlike editor extensions that dump raw code into open files, a CLI agent runs directly in your shell environment. It reads directory structures, checks package scripts, executes tests, and shows clear git diffs before touching anything.

A typical task for Claude Code looks like this:

# Running an audit on Next.js routes
claude "Inspect app/(home)/blog/[...slug]/page.tsx. Check how params are awaited, and update the error boundary to handle missing posts cleanly."

The tool reads the file, identifies that Next.js 15+ treats params as a Promise, updates the type signatures, runs the TypeScript check, and presents a diff for approval.

The boundary rule: Claude Code handles changes where I can write a verification command (bun test, tsc --noEmit, or bun run build). If a task cannot be verified with a command, I write it myself.

3. v0 by Vercel for initial UI scaffolding

Writing repetitive Tailwind CSS utility classes for complex dashboard tables, filter sidebars, or responsive grid shells is tedious. I use v0 to generate initial visual layouts.

Instead of writing five hundred lines of JSX from scratch, I describe the layout and component structure. For example:

"Build a filter sidebar for a travel rental app. Include price slider, bedroom count buttons, amenities checkboxes, and a sticky bottom reset button. Use Tailwind CSS and clean semantic tags."

v0 outputs a React component that looks polished out of the box. From there, I take the code out of the browser and into my project.

What I never do is ship v0 code directly. Generated code always needs manual restructuring:

  • Extracting inline sub-elements into reusable components.
  • Adding missing accessibility attributes like aria-expanded and keyboard navigation.
  • Separating client interactive components from server components in the Next.js App Router.

Treating generative UI as a digital sketchbook rather than finished production code makes it a genuine time saver.

4. Perplexity for technical search and library documentation

Standard Google search results for web development queries have become cluttered with scraper sites and outdated tutorials. When I need to look up documentation for a new React 19 hook, a subtle Next.js caching rule, or a Prisma schema syntax, I search with Perplexity.

Perplexity pulls from current documentation, links directly to the primary sources, and skips the SEO filler that plagues technical queries.

Prompt: "Next.js 15 metadata alternates canonical URL syntax when using dynamic params. Show example with generateMetadata."

Instead of clicking through three blog posts from 2021 that still use the Pages router, I get the exact syntax with links to the official Next.js documentation repository.

The boundary rule: Perplexity is for discovery and syntax lookup. I verify any snippet against the official docs before copying it into production code.

How the pieces fit together

A clean workflow depends on not letting these tools bleed into each other:

  1. Perplexity finds the pattern or library approach.
  2. v0 drafts visual layout components when starting a fresh UI element.
  3. Cursor handles immediate writing, refactoring, and auto-completion inside files.
  4. Claude Code handles cross-file edits, dependency updates, and verification in the terminal.

Keeping the tools separated keeps control where it belongs: in your hands, with working software verified after every step.