ANTIGRAVITY LABJP
Articles/Editor View
Editor View/2026-03-10Intermediate

AI Code Review Guide — Improve Code Quality with Antigravity Editor

Master AI-powered code review in Antigravity Editor. Learn how to detect bugs, security vulnerabilities, and performance issues automatically.

Code Review3Editor4AI10Quality2Security9

As an indie developer, getting a second pair of eyes on your code is a rare luxury. I maintain my own apps and several blogs single-handedly, so for years the person approving my pull requests has been, well, me. More often than not I discovered the things I had missed only after something broke in production.

That is exactly why a tool that can mechanically stand in for a second reviewer has earned a place in my workflow. Antigravity Editor's AI Code Review fills that role: it combines static analysis with machine learning to flag bugs, security vulnerabilities, and performance problems the moment you commit.

In this article I walk through what I learned by actually using it day to day — which mode to start from, how to live with false positives, and how to fold it into a pull-request workflow.

Core Capabilities of AI Code Review

What Problems Does It Solve?

Antigravity's AI code review covers seven distinct analysis dimensions:

  1. Security Analysis — SQL injection, cross-site scripting (XSS), authentication bypasses, cryptographic weaknesses
  2. Performance Optimization — Inefficient algorithms, memory leaks, N+1 query patterns, suboptimal caching
  3. Code Quality — Naming conventions, cyclomatic complexity, dead code, code duplication
  4. Bug Detection — Logic errors, type safety violations, exception handling gaps, off-by-one errors
  5. Architecture Review — Design pattern violations, poor separation of concerns, circular dependencies
  6. Test Coverage — Untested code paths, missing edge case tests, insufficient assertions
  7. Maintainability — Missing documentation, overly complex branches, magic numbers, unclear variable names

AI vs Manual Code Review

AspectAI ReviewManual Review
Execution TimeSeconds to minutesHours to days
ConsistencyIdentical standards appliedVariable by reviewer
Security Detection Rate85% accuracy60% accuracy
ScalabilityUnlimitedTeam-dependent
Context AwarenessFull project understandingFile-local perspective
24/7 AvailabilityYesNo
Speed of FeedbackImmediateDelayed

Getting Started with Code Review

Quick Start: Review Your First File

Open any file in Antigravity Editor and click the "Code Review" button in the sidebar. Within seconds, you'll receive a comprehensive analysis.

// src/auth/authenticate.ts
export async function authenticateUser(email: string, password: string) {
  const user = await db.query(
    'SELECT * FROM users WHERE email = ?',
    [email]
  );
 
  if (user && user.password === md5(password)) {
    const token = jwt.sign({ id: user.id }, 'secret-key');
    return { success: true, token };
  }
 
  return { success: false };
}

AI Code Review Output:

🔴 [CRITICAL] Weak Password Hashing
Line 8: MD5 is cryptographically broken and unsuitable for password storage.
Recommendation: Use bcrypt, scrypt, or argon2 with salt.

🔴 [CRITICAL] Hardcoded Secret
Line 10: JWT secret is hardcoded in source. Exposes secret in version control.
Fix: Move to environment variable: process.env.JWT_SECRET

🟠 [HIGH] Missing Rate Limiting
No rate limiting on authentication attempts. Vulnerable to brute force attacks.
Implement: Use rate-limiting middleware (e.g., express-rate-limit)

🟡 [MEDIUM] Generic Error Message
Line 14: Could leak user existence information. Return generic error.

Review Modes: Tailored Analysis

Antigravity offers specialized review modes for different purposes. Choose the right mode based on your current focus.

Security Mode

antigravity review --mode security src/payment/checkout.ts

Focuses exclusively on security vulnerabilities and best practices:

// src/services/payment.ts
async function processPayment(
  cardDetails: CreditCard,
  amount: number
): Promise<PaymentResult> {
  // Security review checks:
  // - PCI DSS compliance
  // - Sensitive data exposure
  // - Authentication validation
  // - Input validation
  // - API key management
 
  const response = await fetch('https://api.payment.com/charge', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.STRIPE_SECRET}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      card: cardDetails,  // Potential exposure
      amount: amount
    })
  });
 
  return response.json();
}

Detected Issues:

  • Never transmit full card details to external APIs
  • Store only tokenized references
  • Validate SSL/TLS certificate pinning
  • Implement 3D Secure authentication

Performance Mode

antigravity review --mode performance src/database/queries.ts

Identifies efficiency bottlenecks and optimization opportunities:

# src/services/user_service.py
def get_user_dashboard_data(user_id: int) -> dict:
    # Performance issues detected:
    # - N+1 query pattern
    # - Unbounded result sets
    # - Missing database indexes
    # - Inefficient joins
 
    user = db.query('SELECT * FROM users WHERE id = ?', [user_id])
 
    # Separate query for each data type
    posts = db.query('SELECT * FROM posts WHERE user_id = ?', [user_id])
    comments = []
    for post in posts:
        post_comments = db.query(
            'SELECT * FROM comments WHERE post_id = ?',
            [post.id]  # Query runs for each post!
        )
        comments.extend(post_comments)
 
    followers = db.query(
        'SELECT * FROM followers WHERE following_id = ?',
        [user_id]
    )
 
    return {
        'user': user,
        'posts': posts,
        'comments': comments,
        'followers': followers
    }

Optimization Suggestions:

def get_user_dashboard_data_optimized(user_id: int) -> dict:
    # Single query with efficient joins
    data = db.query('''
        SELECT
            u.*,
            COALESCE(COUNT(DISTINCT p.id), 0) as post_count,
            COALESCE(COUNT(DISTINCT c.id), 0) as comment_count
        FROM users u
        LEFT JOIN posts p ON p.user_id = u.id
        LEFT JOIN comments c ON c.post_id = p.id
        WHERE u.id = ?
        GROUP BY u.id
    ''', [user_id])
 
    return data[0]  # Single query instead of N+1

Style & Quality Mode

antigravity review --mode style src/components/Dashboard.tsx

Enforces consistent code style and maintainability standards:

// Before
export const DashboardComponent = ({ u, p, s, o, c }) => {
  if (!u) return null;
 
  return (
    <div>
      <h1>{u.nm}</h1>
      <div>{p}</div>
      {s && <span className={o}>{s}</span>}
      {c && c()}
    </div>
  );
};
 
// Issues:
// - Abbreviated parameter names
// - Missing prop types
// - No documentation
// - Inconsistent return patterns

AI Recommendations:

interface DashboardProps {
  user: {
    id: string;
    name: string;
    email: string;
  };
  posts: Post[];
  status?: string;
  statusClass?: string;
  renderActions?: () => React.ReactNode;
}
 
/**
 * Displays the user dashboard with posts and actions.
 * @param user - Authenticated user object
 * @param posts - User's posts to display
 * @param status - Optional status message
 * @param statusClass - CSS class for status styling
 * @param renderActions - Optional action renderer
 */
export const DashboardComponent: React.FC<DashboardProps> = ({
  user,
  posts,
  status,
  statusClass,
  renderActions
}) => {
  if (!user) {
    return null;
  }
 
  return (
    <div className="dashboard">
      <header>
        <h1>{user.name}</h1>
      </header>
      <main className="posts-section">
        {posts.map(post => (
          <PostCard key={post.id} post={post} />
        ))}
      </main>
      {status && (
        <aside className={statusClass}>
          {status}
        </aside>
      )}
      {renderActions && (
        <footer>
          {renderActions()}
        </footer>
      )}
    </div>
  );
};

Testing Mode

antigravity review --mode testing src/utils/validation.ts

Analyzes test coverage and suggests comprehensive test scenarios:

// src/utils/validation.ts
export function validateEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
 
export function validatePhone(phone: string): boolean {
  return /^\d{10}$/.test(phone);
}

AI Testing Recommendations:

// src/utils/validation.test.ts
describe('Email Validation', () => {
  describe('Valid emails', () => {
    it('should accept standard email addresses', () => {
      expect(validateEmail('user@example.com')).toBe(true);
    });
 
    it('should accept subdomains', () => {
      expect(validateEmail('user@mail.company.co.uk')).toBe(true);
    });
 
    it('should accept numeric addresses', () => {
      expect(validateEmail('123@456.com')).toBe(true);
    });
  });
 
  describe('Invalid emails', () => {
    it('should reject missing @ symbol', () => {
      expect(validateEmail('invalidemail.com')).toBe(false);
    });
 
    it('should reject missing domain', () => {
      expect(validateEmail('user@')).toBe(false);
    });
 
    it('should reject spaces', () => {
      expect(validateEmail('user @example.com')).toBe(false);
    });
  });
 
  describe('Edge cases', () => {
    it('should reject empty string', () => {
      expect(validateEmail('')).toBe(false);
    });
 
    it('should reject very long emails', () => {
      const longEmail = 'a'.repeat(255) + '@example.com';
      expect(validateEmail(longEmail)).toBe(false);
    });
 
    it('should handle internationalized domains', () => {
      // Future enhancement consideration
      expect(validateEmail('user@münchen.de')).toBe(true);
    });
  });
});

Configuration & Customization

Project Review Configuration

Create .antigravity-review.yml at your project root to enforce consistent review standards:

# .antigravity-review.yml
review:
  enabled: true
 
  security:
    severity_threshold: "warning"
    check_sql_injection: true
    check_xss: true
    check_authentication: true
    check_cryptography: true
    check_file_upload: true
    check_api_security: true
 
  performance:
    enabled: true
    max_function_complexity: 12
    max_cyclomatic_complexity: 10
    detect_n_plus_one_queries: true
    detect_memory_leaks: true
 
  quality:
    enabled: true
    require_type_annotations: true
    require_function_documentation: true
    max_line_length: 100
    enforce_naming_conventions: true
 
  testing:
    enabled: true
    min_coverage_threshold: 80
    require_edge_case_tests: true
 
  # Patterns to exclude from review
  exclude_patterns:
    - "node_modules/**"
    - "dist/**"
    - "build/**"
    - "*.test.ts"
    - "*.spec.ts"
    - "*.generated.ts"
 
  # Automatic fixes
  auto_fix:
    enabled: true
    fix_imports: true
    format_code: true
    remove_unused_variables: true

Inline Review Comments

Suppress specific issues with explanatory comments:

// antigravity-ignore: security (legacy endpoint, migration planned Q3)
export function deprecatedAuthEndpoint() {
  // ...
}
 
// antigravity-ignore: performance (small data set, optimization not worth it)
function niche_feature_with_inefficiency() {
  // ...
}
 
// antigravity-ignore: style (matches legacy codebase for consistency)
const legacy_variable_naming = true;

Integration with Pull Requests

Automated Review on PR Creation

Set up GitHub Actions to automatically review code when PRs are created:

# .github/workflows/ai-code-review.yml
name: AI Code Review
on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - '**.ts'
      - '**.tsx'
      - '**.js'
      - '**.jsx'
      - '**.py'
 
jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
 
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
 
      - name: Run Antigravity Code Review
        uses: antigravity-lab/code-review-action@v2
        with:
          mode: comprehensive
          severity_threshold: warning
          post_comments: true
          fail_on_critical: true
          api_key: ${{ secrets.ANTIGRAVITY_API_KEY }}
 
      - name: Post Review Summary
        if: always()
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const review = JSON.parse(fs.readFileSync('./review-results.json'));
 
            const comment = `
            ## 📊 AI Code Review Results
 
            **Critical Issues:** ${review.critical.count}
            **High Priority:** ${review.high.count}
            **Warnings:** ${review.warnings.count}
 
            ${review.summary}
 
            [View full report](${review.report_url})
            `;
 
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

Pre-Deployment Review Checks

Ensure all critical issues are resolved before production deployment:

#!/bin/bash
# scripts/pre-deploy-check.sh
 
set -e
 
echo "Running comprehensive code review..."
antigravity review \
  --mode comprehensive \
  --fail-on-critical \
  --output json > review-report.json
 
CRITICAL_COUNT=$(jq '.critical.count' review-report.json)
 
if [ $CRITICAL_COUNT -gt 0 ]; then
  echo "❌ Deployment blocked: $CRITICAL_COUNT critical issues found"
  jq '.critical.issues[]' review-report.json
  exit 1
fi
 
echo "✅ All critical issues resolved. Safe to deploy."
exit 0

Real-World Review Example

Complex Payment Processing Function

// src/services/payments/processor.ts
import Stripe from 'stripe';
import { db } from '../../database';
 
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
 
export async function createSubscription(
  customerId: string,
  planId: string,
  billingEmail: string
) {
  try {
    // Create Stripe customer
    const customer = await stripe.customers.create({
      email: billingEmail,
      metadata: { internal_id: customerId }
    });
 
    // Create subscription
    const subscription = await stripe.subscriptions.create({
      customer: customer.id,
      items: [{ price: planId }]
    });
 
    // Save to database
    await db.query(
      'INSERT INTO subscriptions (customer_id, stripe_customer_id, plan_id, status) VALUES (?, ?, ?, ?)',
      [customerId, customer.id, planId, subscription.status]
    );
 
    // Send confirmation email
    await sendConfirmationEmail(billingEmail, subscription.id);
 
    return {
      success: true,
      subscriptionId: subscription.id
    };
  } catch (error) {
    console.log(error);
    throw error;
  }
}

AI Code Review Findings:

🔴 [CRITICAL] Unvalidated Customer Email
Line 15: billingEmail is not validated before passing to Stripe API.
Risk: Invalid emails could cause payment processing failures.
Fix: Validate email format before using.

🔴 [CRITICAL] Incomplete Error Handling
Lines 35-37: Generic error handling doesn't distinguish between
Stripe errors, database errors, and email service failures.
Fix: Implement specific error handling for each service.

🟠 [HIGH] Stripe Event Webhook Required
Line 24: Subscription creation is acknowledged without webhook
confirmation. If webhook fails, database becomes inconsistent.
Risk: Orphaned records or missing subscription updates.

🟠 [HIGH] Race Condition Risk
Lines 23-28: Database insertion happens after Stripe confirmation.
If insertion fails, Stripe has the subscription but DB doesn't.
Fix: Use idempotency keys and transaction management.

🟡 [MEDIUM] Missing Retry Logic
Line 19: Email could fail silently. No retry mechanism.
Fix: Implement queue-based email delivery with retries.

🟡 [MEDIUM] PCI DSS Compliance
Line 15: Ensure no card data is being logged or stored.
Verify: All sensitive data flows through tokenization.

Best Practices

Effective Review Workflow

  1. Continuous Integration — Run reviews on every commit
  2. Progressive Severity — Fix critical issues first, then warnings
  3. Team Alignment — Customize .antigravity-review.yml to match team standards
  4. Learning Orientation — Use detected issues as teaching opportunities
  5. False Positive Management — Carefully curate exclusion rules

What Not to Do

// ❌ Ignoring all warnings
// antigravity-ignore
function needsRefactoring() { }
 
// ✅ Targeted, justified exclusions
// antigravity-ignore: performance (accepted complexity for readability)
function complexBusinessLogic() { }

Where to start

Trying to switch on every check at once buries you under false positives, and the habit never sticks. What worked for me was enabling Security Mode alone and clearing only the Critical findings first. Once those standards started to feel natural, I layered in performance and readability checks one at a time.

As a concrete next step, drop a .antigravity-review.yml with just the security rules into one of your repositories and run a single review against your most recent commit. The moment you see the first finding on your own code, you will have a feel for where this tool fits.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Editor View2026-03-24
Working With Antigravity's Diff View — Reviewing and Managing AI Code Changes with Confidence
Learn how to use Antigravity's Diff View to efficiently review, approve, and manage AI-suggested code changes — chunk by chunk, file by file.
Editor View2026-06-16
Feeding Spec PDFs to Antigravity 2.1.4: A Practical Attachment Workflow
Field notes on using the PDF attachment added in Antigravity 2.1.4 as a spec-driven implementation workflow: supported formats, the scanned-PDF trap, token cost, and how to verify the output.
Editor View2026-04-08
Antigravity Editor Common Errors Fix: AI Completion, Connection Issues & Project Loading Failures
Fix the most common Antigravity editor issues: AI code completion stopping, projects failing to open, terminal freezes, Git integration problems, and extension conflicts — with step-by-step solutions.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →