Can you replace a $100k Domo stack with open-source alternative & AI agents?
Domo is expensive, but the bill is the easy part. This guide looks at why affordable Domo alternatives run into the same walls, whether a coding agent can build your BI tool instead, and how anfra gives those agent-built apps one governed data backend.
Like a lot of companies, you pay for Domo. The contract is somewhere north of what anyone budgeted (buyers on Reddit report quotes of $70,000 a year for a pre-revenue startup (opens in a new tab), and one estimate puts 20 datasets refreshed once a day at about $100,000 a year (opens in a new tab) under the credit model), but spending the money is still the easier part. Once you have bought it, most of your week goes on the unglamorous stuff: working out how many credits a new refresh schedule will burn (since one credit covers a data refresh, a million rows or a single Magic ETL run, and the price of a credit lives in your contract rather than on a public price list); tracing why the same KPI shows two different numbers on two cards (because every card carries its own Beast Mode calculation); rebuilding a DataFlow that broke overnight; and explaining to finance why none of it lives in Git, so nobody can say who changed a metric or roll it back.
Keeping the tool running and reliable is one job, and making it appealing enough that business users actually open it is another. If you work in data, you know how quickly people abandon a well-built dashboard for Excel. One analyst described their company's Domo rollout (opens in a new tab) as something that "at its best, it's a way to go get an excel export," and most data teams have lived some version of that sentence. The numbers drift once they leave the tool, but at least people get their number fast, in a format they understand.
So you look at Domo alternatives (opens in a new tab) that are more affordable or more powerful, such as Power BI, Metabase or Apache Superset, and the pricing story usually improves. The day-to-day story improves less than you hoped, because every BI tool (opens in a new tab) comes with its own grid, its own list of chart types and its own idea of what a filter can do. As long as you build inside the constraints of a BI tool, you end up back in the same place, with dashboards that are correct, look like every other dashboard ever made, and get exported to a spreadsheet anyway.
Should you replace Domo with a custom-built BI tool?
At some point, every data team has the same wistful conversation: maybe we should just build our own BI tool with our coding agents and cancel Domo.
For a long time, it was a kinda silly idea. The idea sounds less silly than it did a year ago. Claude Code with Opus 5.5 can now work inside your repos, use your tools and run a query to check a number before it answers. It can produce an HTML dashboard that looks far better than a Domo card, with the layout, colours and interactions you asked for instead of the ones a vendor shipped. Your business users have already noticed. Some of them now one-shot a dashboard in Claude on an afternoon, and (accuracy aside) the experience is fast, easy and good-looking enough that they keep coming back to it.
So is that enough? Can a coding agent and an open-source stack replace a $100k Domo contract with something more affordable and better looking?
A BI tool is more than charts and dashboards
The charts were never the whole product. Underneath every BI tool, including Domo, sits a foundation that most teams never think about because the vendor bundled it in:
| Layer | What it does |
|---|---|
| Authentication | SSO, logins and sessions |
| Access control | Who can see which rows, columns and reports |
| Data consistency | One definition per metric, used in every report |
| Performance | Caching and fast queries as usage grows |
| Governance | Audit logs, lineage and change history |
The apps on top are the part data teams want to customise. The foundation underneath is the part they have to reinvent and maintain the moment they build their own, and it is where home-grown BI projects get expensive. Teams that start with one agent-built app soon find themselves adding a Postgres database and a caching layer to each app so pages load quickly, rewriting the permission logic for every new page, and discovering that the agent wrote a slightly different revenue calculation for each one.
Inconsistent metrics do the most damage. When an agent queries raw tables, it decides what each metric means and writes fresh SQL for every app, so it can average a rate that should be recomputed, or join a table that double-counts a fee, and the chart still renders. After a few months, two apps show two different totals and nobody can tell which is right, which is the same drift that made people distrust the Domo cards in the first place.
Trust or freedom, until now
Data teams have been choosing between two imperfect options.
| Trust (numbers mean what your team means) | Freedom (build any app, ask any question) | |
|---|---|---|
| Off-the-shelf BI (Domo, Power BI, Metabase) | Governed data | Limited front end and interactions |
| Custom-built BI (coding agent on raw tables) | Ungoverned, because the app writes its own SQL | Any layout, any interaction |
Off-the-shelf BI gives you governed numbers in a fixed frame. Custom-built BI gives you any frame you like with numbers nobody can vouch for. Most teams end up trading one for the other, which is why the Domo contract survives even after half the company has moved its real work into Claude.
anfra: one governed backend for every data app your agent builds
anfra (opens in a new tab) is an open-source framework for building custom data apps, designed to sit in the top-right corner of that table: a flexible front end on governed data. The simplest way to describe it is a single data backend for every internal app your team builds (opens in a new tab). Your data team defines metrics once, in code, and reviews every change, and every app your coding agent builds asks for those metrics by name.
There are two ways in, and both land on the same definitions:
- Build. A coding agent such as Claude Code, Codex or Cursor writes an app (plain HTML and JavaScript) with the anfra SDK. The app never writes SQL. It asks anfra Server for
revenueby region, and anfra compiles that request into SQL against your definitions and runs it on your warehouse. - Ask. Any agent connects through anfra's MCP server, reads your models, and learns what "revenue" means before it writes anything, so the analysis a business user runs in a chat uses the same definition as the app on their screen.
Underneath both sits your warehouse (Snowflake, BigQuery, Databricks, Redshift, ClickHouse, PostgreSQL, DuckDB and others). anfra runs the SQL there and keeps no copy of your data.
Setup takes one prompt
anfra installs as a single binary for Linux and macOS, and its agent skills teach your coding agent how to write models and build apps:
curl -fsSL https://anfra.ai/install.sh | bash
anfra agent setupFrom there, a single prompt gets you a working app:
Set up anfra in this folder, connect to my ecommerce database. Build me a sales funnel data app. Be creative with your app. Use the anfra-build-data-app skill.
Your data team decides what "revenue" means
Metrics in anfra are code that compiles to SQL, written in AMQL and stored in your repository. This is where your Domo Beast Modes go, and the move is a good moment to collapse the five slightly different versions of each one into a single definition. A Beast Mode such as SUM(amount) / COUNT(DISTINCT order_id) becomes a metric on a dataset:
Dataset sales {
label: 'Sales'
data_source_name: 'warehouse'
models: [orders, users]
relationships: [
relationship(orders.user_id > users.id, true)
]
metric revenue {
label: 'Revenue'
type: 'number'
definition: @aql sum(orders.amount);;
}
metric average_order_value {
label: 'Average Order Value'
type: 'number'
description: 'Revenue per order, before vouchers. Use this for merchandising questions; finance reports use the after-voucher version.'
definition: @aql sum(orders.amount) / count_distinct(orders.id);;
}
}Agents pick the right metric far more often when a description says when to use it, especially when your company has two versions of the same idea (before and after vouchers, gross and net), so it pays to write those sentences while the Beast Modes are fresh in your mind. Your agent can draft the models and metrics, and your team reviews them in a pull request like any other code change.
The app asks for metrics by name
Here is a page with revenue by region and a monthly trend, where a click on a region filters the trend:
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: orders.created_at | month() }
measures { revenue: revenue, aov: average_order_value }
}`,
})
app.mapCrossFilter(byRegion, trend)The page names a dataset and asks for revenue. It never redefines revenue and never writes SQL, so revenue means the same thing in this app, the next app and the chat a business user opens tomorrow. Filters, date drills and cross-filters are built-in patterns in the SDK, which also saves the agent from rediscovering (and paying tokens for) the same interaction logic in every app. The layout, charts and styling are whatever your agent and your users want, which is the part Domo never let you control.
Inspect any number
Every anfra app has Inspect built in. Opening it on a chart walks a number back to its source in three steps: the metric definition in AMQL, the query on that page, and the exact SQL that ran on your warehouse. A reviewer can check where an APAC revenue figure came from without reading the app's code, which is the conversation Domo teams usually have by opening three cards and comparing Beast Modes by hand.
The whole BI project is files you own
An anfra project is a folder in Git:
my-project/
├── models/ # tables and joins
├── datasets/ # metrics such as revenue
├── apps/ # your custom apps
└── .anfra/data_sources.yml # warehouse connection (git-ignored)Your coding agent reads the same files your team reviews, so a change to the revenue definition goes through a pull request, and every app picks it up on the next query. Nothing about your metrics is locked inside a vendor's proprietary data layer, which is the opposite of what happens to Magic ETL pipelines and Beast Modes.
How a Domo stack maps to anfra
anfra covers the semantic layer, the query engine and the app framework, and it leaves data loading to the tools most data teams already run.
| What Domo does today | What replaces it |
|---|---|
| Connectors | Airbyte, dlt or Meltano loading into your own warehouse |
| Magic ETL and DataFlows | dbt Core or SQL in the warehouse |
| Domo's data layer | Your warehouse, queried directly by anfra |
| Beast Modes, per card | anfra metrics, one definition per dataset, reviewed in Git |
| Cards and pages | anfra apps built by your coding agent |
| Ad-hoc questions | Any MCP-capable agent reading your anfra models |
| PDP row-level policies | Your own SSO proxy today; row-level permissions coming to anfra Cloud |
You also do not need to move everything at once. The pattern that works best for teams with a large Domo estate is to leave the standard reports where they are while the switching cost is high, build every new app on anfra, and send exploratory questions to an agent connected over MCP. Domo then shrinks to the reports nobody has rebuilt yet, and the next renewal covers far less.
What is open source today, and what is not
It is worth being precise here, because the foundation table above is the part that matters most.
- Open source today (Apache 2.0): anfra Server, the SDK, the CLI, AMQL, the MCP server and the agent skills, which together give you semantic models, the query engine, the interaction patterns and Inspect. A project runs on your laptop or on one small VM, since the server is a thin Go binary.
- anfra Cloud (in beta, in the US region): logins and roles today, with SSO, row-level and viewer-level permissions, sharing links and audit logs on the way. Self-hosted anfra has none of these, so anyone who can reach the server can open its apps. Teams self-hosting today put it behind their own SSO proxy. A project you build on open-source anfra runs on Cloud unchanged.
- Planned: query caching, connecting external semantic layers such as dbt, Cube, Snowflake and Databricks, and evaluation and trust grading for agent answers. Until caching ships, every page load is a warehouse query, so pre-aggregated tables in the warehouse are the way to keep busy pages fast.
What it costs compared with Domo
| Item | Domo | anfra stack |
|---|---|---|
| BI licence | ~$100k a year for a mid-size deployment, credit-based | $0 (Apache 2.0) |
| Semantic layer and query engine | Bundled, proprietary | anfra, open source |
| Dashboards and apps | Cards on a fixed grid | Built by your coding agent, any layout |
| Data loading and transformation | Bundled connectors and Magic ETL | Airbyte, dlt, dbt Core (open source) on your own server |
| Warehouse | Optional | Usage-based, billed by your warehouse vendor |
| Coding agent | n/a | Your existing Claude Code, Codex or Cursor subscription |
| Hosting | Included | One small server for the Docker image |
The anfra column has no per-seat line and no credits, so adding a viewer or refreshing a dataset more often costs nothing beyond the warehouse queries it triggers. The real cost sits elsewhere: your team's time to model metrics properly and to stand up what Domo bundled (logins, permissions and scheduled reports) until anfra Cloud covers them. For a team that already runs a warehouse and dbt, that time goes mostly into metric definitions, which you should own anyway. For a team with no warehouse and no one comfortable reviewing modelling code, a packaged tool will still be less work for now.
So, can you replace Domo with open source and AI agents?
For most data teams with a warehouse, yes, and the reason is that the part of Domo that was expensive to replace has changed. The front end, which used to take a quarter of someone's time per app, now takes an agent an afternoon. What remains is the foundation (one definition per metric, a query engine that respects it, and a way to check any number), and that is the part anfra gives you in open source.
The quickest way to find out is to pick one Domo page your team opens every week, define its three or four metrics in an anfra dataset, and ask your coding agent to rebuild it against your own warehouse. After that, you can compare what you had to build yourself with what Domo gave you. The quickstart (opens in a new tab) takes about ten minutes, the live demos (opens in a new tab) show what agents have built so far, and the source is on GitHub (opens in a new tab).