The open source framework for vibe-coding your custom BI application.
Use your own HTML, JavaScript, and charting library. Anfra connects the app to reusable metrics, live warehouse queries, and analytics interactions such as filtering, drill-down, and period comparisons.
Website · Docs · Live demos · Quickstart
A funnel analysis app built by a coding agent with Anfra. Try it live →
Traditional BI tools make it easier to trust the numbers, but often limit teams to fixed dashboard layouts and interactions. On the other hand, coding agents can build custom dashboard apps with HTML and JavaScript easily, but wiring each view to the warehouse — and getting filters, drill-downs, and comparisons right — is easy to get wrong and hard to reuse.
With Anfra, you define metrics once, the agent writes the UI, and Anfra turns every click into a query on those metrics. See what that looks like.
These are custom BI apps (HTML/JS/CSS) generated by coding agents on top of Anfra SDK and Anfra semantic runtime.
![]() Funnel analysis Add, remove, and reorder funnel steps. Click a bar to see who converted or dropped off. |
![]() Cohort analysis Retention heatmap by signup month. Click a cell to filter, or right-click to see the underlying rows. |
![]() Cashflow statement Operating, investing, and financing activities with subtotals, monthly or quarterly. |
![]() Canvas builder Add and arrange charts on a canvas. Click a mark to drill into a linked chart. |
Anfra has three parts:
- Anfra SDK: a JavaScript library your app uses to request data and wire up filters, drill-downs, and period comparisons. It asks for data by dataset and metric names, not SQL.
- Anfra Server (
anfra serve): takes each request from the SDK, turns the interaction (a filter, a drill-down, a comparison) into a query on your semantic layer, runs it on the warehouse, and returns the results. It also serves MCP so coding agents can read your models. - Semantic layer: your models, datasets, and metrics, defined as code. Anfra ships with AMQL, the semantic layer behind Holistics, which runs in production at hundreds of companies. Support for other semantic layers is planned.
How it works in a few steps:
- Connect Anfra to your warehouse.
- Define models, datasets, and metrics in AMQL, or have your coding agent draft them for you to review.
- Ask your coding agent to build an app. It reads the semantic layer and writes HTML and JavaScript that uses the Anfra SDK.
- Run
anfra serve. The server resolves each query through the semantic layer, runs it on the warehouse, and returns results to the page. - Check any number in the app to see the query and metric definitions behind it.
A revenue page with two charts: revenue by region and a monthly revenue trend. Clicking a region filters the trend.
1. Define a metric once in the semantic layer:
Dataset sales {
metric revenue {
definition: @aql sum(orders.amount) ;;
}
}
2. Your agent writes the page. It declares two queries in AQL and a mapping that says a click on one filters the other:
const byRegion = app.createQuery('byRegion', {
dataset: 'sales',
aql: `explore {
dimensions { region: users.region }
measures { revenue: revenue }
}`,
})
const trend = app.createQuery('trend', {
dataset: 'sales',
aql: `explore {
dimensions { month: date_trunc(orders.created_at, 'month') }
measures { revenue: revenue }
}`,
})
app.mapCrossFilter(byRegion, trend)
regionChart.on('click', (p) => {
byRegion.select([byRegion.result.rows[p.dataIndex]])
app.execute()
})Queries, controls, and mappings like these are what we call Semantic UI. The page declares what each view shows and how views are connected, and Anfra handles the queries.
3. A user clicks "APAC". Anfra Server rewrites the trend query and runs:
SELECT date_trunc('month', orders.created_at) AS month, SUM(orders.amount) AS revenue
FROM orders
JOIN users ON orders.user_id = users.id
WHERE users.region = 'APAC'
GROUP BY 1The page never wrote that SQL, and revenue means the same thing in every app that uses it.
4. Inspect any number to see the query and metric definitions behind it.
See the Semantic UI guide for queries, controls, and interaction mappings in detail.
curl -fsSL https://raw.githubusercontent.com/holistics/anfra/main/install.sh | bashThe installer downloads the latest release for your platform, places the anfra binary in ~/.anfra/bin, and prints the line to add it to your PATH.
Linux and macOS are supported. See Installation for installer options and updates.
Then install the build-anfra-app skill, which teaches your coding agent how to model data in AMQL and build apps with the Anfra SDK:
anfra setupanfra init custom-bi
cd custom-bi/Your folder structure should look like this:
custom-bi/
├── .anfra/
│ └── data_sources.yml # warehouse connections
├── models/ # model definitions (AMQL)
├── datasets/ # dataset definitions (AMQL)
├── apps/ # one folder per app (HTML + JS)
└── AGENTS.md # instructions for coding agents
Open .anfra/data_sources.yml and fill in your database credentials:
# .anfra/data_sources.yml
data_sources:
warehouse:
type: postgresql
connection:
host: localhost
port: 5432
user: anfra
password: anfra
dbname: analyticsAnfra supports popular warehouses and databases, including Snowflake, BigQuery, Databricks, Redshift, PostgreSQL, ClickHouse and DuckDB. See Data sources for the full list, the type value for each, and its connection fields.
Open the folder in Claude Code or Cursor and ask the agent for an app. Start the prompt with /build-anfra-app so the agent uses the skill:
/build-anfra-app Look at the orders data and build me a revenue overview:
monthly trend, revenue by region with a region filter, and a table of top products.
Clicking a region should filter everything else.
With no models yet, the agent proposes datasets and metrics as code in the models/ and datasets/ folders.
Run anfra serve. The app opens at http://localhost:4000/.
Business users already make reports in Claude or ChatGPT. Connect their agents to one Anfra server instead of straight to the warehouse, and the artifacts they create:
- query shared metric definitions rather than improvised SQL;
- keep no data in the file and refresh when opened;
- can be inspected back to the query and metric behind every number.
The open-source server does not manage users or permissions. To share artifacts with permissions, audit them, and revoke access across the company, use Anfra Cloud.
Anfra Cloud is our hosted product, built on the same open-source engine. It adds what a team needs to share apps: users and SSO, row-level permissions, hosted apps with sharing links, audit logs and version history.
A project you build with open-source Anfra runs unchanged on Anfra Cloud. Moving it takes one publish step, with no changes to your models or apps.
- Use open-source Anfra to build and run apps on your own infrastructure, for yourself or a team that doesn't need per-user permissions.
- Use Anfra Cloud to share apps across your company with logins, permissions and audit logs, without running the server yourself.
| Anfra (open source) | Anfra Cloud | |
|---|---|---|
| Semantic layer, metrics, AMQL engine | ✅ | ✅ |
| JS SDK, controls, interactions, inspect | ✅ | ✅ |
| MCP server + agent skills | ✅ | ✅ |
| Self-host | ✅ | Managed |
| Users, SSO, roles | — | ✅ |
| Row-level and viewer-level permissions | — | ✅ |
| Hosted apps: sharing, public links, discovery | — | ✅ |
| Audit trail, usage monitoring | — | ✅ |
| Snapshots, versioning | — | ✅ |
Anfra Cloud isn't available yet. Join the waitlist to get access when it opens. A paid self-hosted edition with the same features is planned.
How is this different from connecting Claude to my warehouse, or a BigQuery, Metabase or dbt MCP?
For a one-off question, not much. The difference shows up when you build apps: metrics defined once instead of re-derived SQL in every app, interactions like drill-down, cross-filter, funnels and period comparisons resolved by the engine, apps that query live data instead of holding pasted numbers, and the query and metric behind each number.
How is this different from Streamlit, Evidence or Hex?
Those give you a framework to write the app in. Anfra gives you a semantic backend for any front end the agent writes: plain HTML/JS, no Python runtime, no fixed component set. Metrics and interactions are defined once and shared across every app.
I already have a BI tool. Why would I switch?
Anfra is built to replace dashboard BI tools, not to sit beside them. Those tools were designed for building reports by hand in a fixed grid of charts and filters. With a coding agent, your team can build the app they actually need, and Anfra keeps it governed: metrics are defined once in the semantic layer, and every number can be inspected back to its query and definition. Anfra Cloud adds users, permissions and sharing.
Compared with a traditional BI tool, Anfra gives you:
- any layout and interaction your team can describe, instead of a fixed set of chart types;
- a semantic layer that handles funnels, cohorts, drill-downs and period comparisons as built-in operations;
- an open-source engine you can self-host for free.
You don't need to switch all at once. Run Anfra next to your current tool, rebuild reports in it as you need them, and decide at renewal whether you still need the old subscription.
Why build an app instead of asking the chatbot each time?
Asking a chatbot works for a question you ask once. For questions your team asks every week, an app is built once and then just runs: no tokens spent on each repeat question, and everyone who opens it sees the same numbers computed the same way.
Do I have to learn AMQL?
No. Your coding agent drafts and edits models using the build-anfra-app skill, and you review changes like any other code. AMQL compiles to plain SQL you can read.
Can the AI change my metric definitions?
Apps query metrics through the SDK; they don't edit the model. Models are files in your project, so when your coding agent proposes a change to a metric, you review it like any other code change before it takes effect.
Can I use my existing semantic layer?
Not today. Anfra ships with AMQL. We plan to support other semantic layers such as Cube, dbt, Snowflake and Databricks, though advanced interactions like funnels and period comparisons will depend on AMQL.
Does my data leave my warehouse? Which AI does Anfra use?
Queries run on your warehouse, and the Anfra server sends results straight to the page. Apps don't store query results or warehouse credentials by default. Anfra doesn't include an AI model: you use your own coding agent, so what the agent can see depends on what you connect it to.
How do I control who can see what?
The open-source server has no login or permissions: anyone who can reach it can open its apps. To restrict access, run it behind your own SSO proxy. For per-viewer permissions (the same app showing different numbers to different users), sharing and audit, use Anfra Cloud.
Are the numbers computed in the browser?
Numbers come from queries the server runs on your warehouse. Page code can still transform the returned rows in JavaScript; Inspect shows the server query, so anything computed on top of it is visible as page code, not hidden in a metric.
How does Anfra relate to Holistics? Will I be locked in?
Anfra is built by the team behind Holistics, and AMQL is the semantic layer Holistics runs on. Anfra is a separate open-source project, licensed under Apache 2.0, and doesn't need a Holistics account. Your models and apps are plain files in your own repository, and AMQL compiles to SQL you can read.
- Concepts: models, datasets, dimensions, and metrics
- Semantic UI: queries, controls, interaction mappings, and inspect
- CLI reference
- Installation
- anfra.ai: product overview
Anfra is licensed under the Apache License 2.0.




