oxc-project/oxc · warning · OxcDiagnostic

Prevent client components from being async functions.

Error message

Prevent client components from being async functions.

What it means

Warning from oxlint rule `nextjs/no-async-client-component`. React only supports async components on the server; a component in a file with a `'use client'` directive runs in the browser, where async components cannot be rendered or hydrated. The rule flags async function components in client context at lint time, before it becomes a hydration or runtime failure.

Source

Thrown at crates/oxc_linter/src/rules/nextjs/no_async_client_component.rs:12

use oxc_ast::{
    AstKind,
    ast::{BindingPattern, ExportDefaultDeclarationKind, Expression, Statement},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{ast_util::get_declaration_of_variable, context::LintContext, rule::Rule};

fn no_async_client_component_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Prevent client components from being async functions.")
        .with_help("See: https://nextjs.org/docs/messages/no-async-client-component")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct NoAsyncClientComponent;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Prevents the use of async functions for client components in Next.js applications.
    /// This rule checks for any async function that:
    /// - Is marked with "use client" directive
    /// - Has a name starting with an uppercase letter (indicating it's a component)
    /// - Is either exported as default or assigned to a variable
    ///
    /// ### Why is this bad?
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Remove `'use client'` so the page becomes an async server component (best fix when no hooks/state are used).
  2. Keep the client component but drop `async`, and load data with `useEffect` + fetch, SWR, or React Query.
  3. Move the async fetching into a server component and pass results down as props.

Example fix

// before
'use client';
export default async function Page() {
  const data = await getData();
  return <pre>{JSON.stringify(data)}</pre>;
}

// after
export default async function Page() {
  const data = await getData();
  return <pre>{JSON.stringify(data)}</pre>;
}
Defensive patterns

Strategy: validation

Validate before calling

// fail on async exports in client files:
// rg -l "^'use client'" app components | xargs rg -n 'export (default )?async function'

Prevention

When it happens

Trigger: A file whose top-level contains `'use client'` (tracked through the module graph) that declares or exports an `async function` used as a component, including `export default async function Page()`.

Common situations: Adding `await` data loading to a page and also marking it `'use client'` for hooks or state; copying an async server page into a client widget; mixing React Server Component patterns from tutorials.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/9e19f20c4821537e. Report an issue: GitHub.