AskSQL API Reference (core v0.10.0)
    Preparing search index...

    Module @asksql/react

    @asksql/react

    React components and hooks for AskSQL:

    • <AskSqlChat />: full-page chat with SQL review, results table, charts.
    • <AskSqlBubble />: floating chat head you can drop into any app.
    • useAskSql: headless hook exposing the whole ask / approve / run state machine, for building your own UI.
    • Building blocks: <ResultTable />, <SqlBlock />, <SchemaBrowser />, <ResultChart />.
    • useSavedQueries / SavedQueryStore: pin and reuse questions (localStorage-backed, SSR-safe).

    Light and dark themes, CSS-variable theming, CSP nonce support.

    AskSQL React chat: a plain-language question turned into SQL, with the results and a chart below it

    Turn on answerSchemaQuestions and questions that aren't a data query - "how are the tables related?", "summarize this database", even "how would I add an index?" - get a grounded, read-only explanation from the schema instead of an error. A question with nothing to do with data is declined in one line. No query is run, and names it can't find are flagged:

    AskSQL React chat answering "How are the tables related?" with a plain-language explanation of the foreign-key relationships - no query, no results table

    npm i @asksql/core @asksql/react
    

    @asksql/core is a peer dependency, and yarn (or npm with legacy-peer-deps) will not install it for you, so name it explicitly as above.

    import { AskSqlChat, HttpTransport } from '@asksql/react';

    const transport = new HttpTransport({ baseUrl: '/asksql' });

    export function Page() {
    return <AskSqlChat transport={transport} />;
    }

    HttpTransport talks to an @asksql/server sidecar at baseUrl; credentials never reach the browser. Pass headers for an auth token.

    useAskSql models the conversation as turns; each turn carries its own sql, result, error, etc.

    import { useAskSql, HttpTransport } from '@asksql/react';

    const transport = new HttpTransport({ baseUrl: '/asksql' });

    function MyUi() {
    const { turns, busy, ask, run, editSql, cancel } = useAskSql({ transport });

    return (
    <>
    <button disabled={busy} onClick={() => ask('How many orders shipped today?')}>Ask</button>
    {turns.map((t) => (
    <div key={t.id}>
    <div>{t.question}</div>
    {t.sql && <pre>{t.sql}</pre>}
    {t.result && <span>{t.result.rowCount} rows</span>}
    {t.error && <p role="alert">{t.error.userMessage}</p>}
    </div>
    ))}
    </>
    );
    }

    The table is always the default view. A Chart toggle appears next to it only when the result can say something a table cannot: at most 50 rows, at least 2 columns, and at least one numeric column besides the label column. A date or timestamp label draws a line chart, anything else a bar chart, and at most 4 series are plotted. Nothing switches to a chart on its own. <ResultChart> and the isChartable(result) predicate are exported if you want the same rule in your own layout.

    When the sidecar is unreachable (wrong baseUrl, server down, or a CORS rejection), the transport surfaces a typed error with code: 'NETWORK_ERROR' and an actionable userMessage, distinct from an HTTP error the server returned. The components render it inline; with the hook, read it from the turn's error.userMessage. If you see NETWORK_ERROR in the browser, check that baseUrl is correct and that the server allows the page's origin (CORS).

    LocalTransport wraps a @asksql/core engine running in the same tab (for example DuckDB-WASM over uploaded files), so the whole ask -> guard -> run loop happens in-browser - same <AskSqlChat>, no server.

    <AskSqlChat> also accepts initialQuestion (asked automatically whenever it changes to a new non-empty value - e.g. an "ask about selection" hand-off, with onInitialQuestionConsumed to clear your state) and sqlDisplayPlacement ('before' | 'after') to show results first with the SQL below.

    The UI is override-friendly at four levels, lightest to fully custom:

    Theme with CSS variables - restyle without touching components. Override any of --aq-accent, --aq-bg, --aq-surface, --aq-fg, --aq-muted, --aq-border, --aq-code-bg, --aq-warn, --aq-danger, --aq-shadow (and --aq-accent-fg), and set theme="light" | "dark" | "auto".

    Component props - <AskSqlChat> takes placeholder, suggestions, requireApproval, showConnectionPicker, connectionId, and nonce (CSP); <AskSqlBubble> adds title, icon, position, offset, and zIndex. The vanilla widget's AskSQL.mount() takes the same theme / title / position / offset / zIndex.

    Compose the building blocks - <ResultTable>, <SqlBlock>, <SchemaBrowser>, and <ResultChart> (plus the formatCell / toCsv helpers) are exported standalone, so you can lay out your own surface while keeping our rendering.

    Go fully headless - useAskSql (see Headless above) gives you the entire ask -> approve -> run state machine with zero markup; render your own UI on top while the engine and guard still run underneath. The hook also exposes planFor(), which runs EXPLAIN through the guard and returns the database's own plan.

    Full documentation: https://github.com/rahulmahadik/AskSQL

    API reference: rahulmahadik.github.io/AskSQL

    HttpTransport
    LocalTransport
    SavedQueryStore
    SseParser
    TransportError
    AskParams
    AskSqlBubbleProps
    AskSqlChatProps
    ChartSeries
    ChartSpec
    ChatEvent
    ConnectionSummary
    DisplayCell
    HttpTransportOptions
    KeyValueStore
    SavedQuery
    SchemaBrowserProps
    Transport
    Turn
    UseAskSqlOptions
    UseAskSqlResult
    BubblePosition
    ChartKind
    TurnPhase
    ASKSQL_CSS
    AskSqlBubble
    AskSqlChat
    ensureStyles
    formatCell
    formatPlan
    inferChart
    isChartable
    ResultChart
    ResultTable
    SchemaBrowser
    SqlBlock
    toCsv
    useAskSql
    useSavedQueries