QueryPanel vs Embeddable
Composable charts and builder-oriented embedding.
Embeddable focuses on composable analytics UI. Teams that enjoy owning chart configuration, layout, and presentation details often evaluate builder-first tools.
Comparison at a glance
This table summarizes typical positioning. Every vendor changes over time—validate details against current documentation and your security review.
| Dimension | Embeddable | QueryPanel |
|---|---|---|
| In-app experience for end users | Composable blocks you integrate yourself; whether the experience feels native or iframe-like depends on how you build the shell. | First-class `@querypanel/react-sdk` components—`QuerypanelEmbedded` for a full dashboard, or `QueryPanelProvider` with `QueryInput` / `QueryResult` for a bespoke flow. They render in your React tree like any other product screen (layout, router, modals, tokens)—not a separate iframe "mini app" on another origin. Mint short-lived JWTs on your server; never ship your workspace private key to the browser. |
| Core value | Composable embedding and builder workflows for charts and dashboards. | AI-driven generation plus a ready-made React embed: less manual assembly per new customer question. |
| Trainable knowledge & steering | You own the full knowledge story—gold SQL, glossary, and tenant-aware steering are whatever you implement around your chart composition layer. | Gold SQL queries (curated examples the model prioritizes), database annotations (business context on tables/columns, re-embedded with schema), glossary (domain terms and definitions), and tenant-level definitions (isolation field, enforcement, and per-tenant sync context so every ask() is grounded in the right customer slice—not a one-size global prompt). |
| SQL generation | Depends on how you wire data and queries; often you bring more of the pipeline. | First-class NL→SQL with validation hooks meant for production SaaS backends. |
| Developer workload | Higher control often means more integration and UI assembly work. | Opinionated paths to ship faster: `@querypanel/react-sdk` for full workspace embeds, `@querypanel/node-sdk` when you want headless `ask()` from the server. |
| Multi-tenant | You implement tenant isolation patterns in your integration layer. | Tenant context is part of the ask() / generation contract for safer customer queries. |
| Ideal team | Front-end heavy teams with time to craft the analytics experience. | Small product teams that need analytics shipped without a dedicated visualization squad. |
Four layers your team—and your tenants—can train for better answers
Natural language is only as good as the context the model sees. QueryPanel's knowledge system lets you steer retrieval and SQL with curated examples, business meaning on the schema, shared glossary terms, and tenant-aware definitions—so customer-facing analytics matches how your product actually defines revenue, usage, and risk.
Gold queries
Save vetted SQL for recurring questions. Gold examples are retrieved with schema context and treated as the strongest pattern signal when they match the end user's intent—so joins, filters, and metrics follow what your team already proved in production.
Database annotations
Attach free-text business meaning to tables and columns. Annotations are merged into embedded schema chunks (“Business Context”) so search and generation see how revenue, activation, or ARR are really defined in your warehouse—not only raw column names.
Glossary
Define terms customers actually say (“active seat”, “net MRR”, “expansion”). Glossary entries are embedded alongside schema so the model resolves ambiguous language the way your finance and product teams mean it.
Tenant-level definitions
Per-tenant isolation settings and tenant-scoped schema sync mean each customer’s ask() carries the right tenant id and rules—so retrieval and generated SQL respect dynamic per-tenant shape, not a single global tenant-agnostic prompt.
Manage gold SQL and glossary from the dashboard knowledge base; annotations attach business context to schema objects; tenant isolation and sync keep per-customer context aligned. See documentation for SDK routes and ingestion APIs.
When Embeddable is the better fit
Honest tradeoffs help your team pick faster—and match how buyers actually decide.
- You want maximum front-end control over every chart and interaction primitive.
- Your team already has strong opinions on visualization libraries and design systems.
- You are building a highly custom analytics canvas rather than a standard dashboard shell.
When QueryPanel is the better fit
Especially strong for B2B SaaS shipping customer-facing analytics on Postgres and similar databases.
- You want a trainable knowledge system—gold queries, DB annotations, glossary, and tenant-aware definitions—so NL→SQL and charts reflect your business, not generic schema-only guesses.
- You want a batteries-included embedded workspace as React—`QuerypanelEmbedded`—instead of hand-assembling every chart primitive, and you do not want that workspace trapped in an iframe.
- You want the full loop from customer language to SQL to visualization as one product workflow.
- You care about tenant-scoped SQL generation as the backbone of self-serve customer questions.
- You still want a headless Node `ask()` path when you need server-side or fully custom UI.
Ship the customer UI with React—not an iframe
Most teams lead with @querypanel/react-sdk: drop QuerypanelEmbedded on a normal product route, or compose QueryPanelProvider with QueryInput / QueryResult. It behaves like any other React subtree—your app shell, router, modals, and design tokens—not a separate cross-origin iframe "mini app" with its own layout chrome.
The browser talks to the QueryPanel API with a JWT you mint on your server (RS256). Never ship your workspace private key to the client.
import { QuerypanelEmbedded } from "@querypanel/react-sdk";
// Render like any other page — not an iframe. Mint tenantJwt (RS256) on your server
// with @querypanel/node-sdk; pass only the JWT to the client.
export function CustomerAnalytics({ tenantJwt }: { tenantJwt: string }) {
return (
<QuerypanelEmbedded
dashboardId="your-dashboard-id"
apiBaseUrl="https://api.querypanel.io"
jwt={tenantJwt}
allowCustomization
/>
);
}Headless Node SDK (optional, for your API)
Use @querypanel/node-sdk on your backend to attach database clients, sync schema, sign JWTs for the React embed, and call ask() from API routes when you want a fully custom pipeline. SQL still runs with your drivers. Full quickstart in documentation.
import { QueryPanelSdkAPI } from "@querypanel/node-sdk";
const qp = new QueryPanelSdkAPI(
process.env.QUERYPANEL_URL!,
process.env.PRIVATE_KEY!,
process.env.QUERYPANEL_WORKSPACE_ID!,
);
// After attachPostgres / syncSchema — tenant comes from your auth layer
const result = await qp.ask("Revenue by country last quarter?", {
tenantId: org.id,
database: "analytics",
});
// result.sql, result.params, result.rows, result.chart — you execute SQL with your driverStill evaluating Embeddable and QueryPanel?
Start on the free tier, embed one dashboard, and compare implementation time against your current shortlist.