Build a ChartMogul alternative
Build a ChartMogul alternative from an invoice CSV, monthly MRR, and a churn list. The card lists $69 to $119 a month. Live billing sync stays later.
You can build a ChartMogul alternative from an invoice CSV, a monthly MRR number, and a churn list. ChartMogul is that product. The catalog line is “Invoices in. MRR and churn out.”
The card lists $69 to $119 a month. ChartMogul’s pricing page lists Starter at $69 a month through Pro at $119 a month, billed monthly. Annual Starter is $57 and annual Pro is $99. The card leaves out the free plan, which covers up to $10,000 of MRR, and Enterprise from $19,900 a year. The first estimate is 10 hours. The verdict is “MRR you can add up”.
Last time I wrote about building a Vimeo alternative. That was a teardown. This one is a regular backlog topic. Live billing sync stays on the skip row.
Build a ChartMogul alternative from one CSV
The ChartMogul page splits the work into three rows.
The first row is 10 hours. Invoice import, MRR, and a churn list. You bring a file. The month has a number. The customers who stopped are listed.
The second row is 3 days. Expansion, a month compare, and a second source CSV. A chart of October against November can wait until November’s number already matches the file.
The third row is 1 month and up. Live billing sync, a CRM, and a warehouse export. The table labels that row as the part you should skip.
If you tell an agent to “clone ChartMogul”, it aims at the third row. Copy the prompt, then pin it to the first one.
Store Customer, Invoice, Plan, and MonthSnapshot. The card names all four. For these 10 hours, all four exist. The customer is the name on the invoice. The plan carries the interval in months. The invoice is the amount and the period. The snapshot is that month’s MRR and the customer ids in it, so the next import can see who left.
A customer is a name, unique on your account. A plan is a name and an interval, 1 for monthly and 12 for annual. An invoice is an amount in cents, a plan, and a start and end date. A month snapshot is the total for one calendar month and the customers who contributed.
The audience is a founder tracking subscription revenue from one billing export. The goal on the card is to import invoices, see MRR and churn, and know which customers moved. The same v1 also stands in for Baremetrics and Maxio. The card lists both and does not give them prices.
A ledger with invoices and a profit figure is Xero at $27 to $97 a month. A shorter invoice loop is FreshBooks at $23 to $60 a month, in Vibe code your own FreshBooks. Named events and a funnel are Mixpanel at $140 to $2,289 a month, in Vibe code your own Mixpanel. Xero keeps the books. Mixpanel counts what people did in the product. This file is the billing export you already downloaded.
A sales pipeline is HubSpot CRM at $20 to $150 a person a month, in Build a HubSpot alternative. The non-goal on the ChartMogul card says the clone is not that pipeline, and it is not a live billing connector.
The guardrail is the rule you paste into the prompt. Store amounts as integer cents. Compute MRR on the server from imported invoices. Reject a CSV that fails validation without writing a partial import.
How a ChartMogul alternative adds up MRR
Mira closes November on November 7, 2026. The file is invoices-nov.csv. Two rows are valid.
Northwind Studio is on Pro, interval 1, amount 4900 cents, period November 1 through November 30. Harbor Mail is on Annual, interval 12, amount 58800 cents, period November 1, 2026 through October 31, 2027. Pine and Co paid 2900 cents in October and has no November row.
November MRR is 4900 plus 4900, which is 9800 cents, $98. Harbor’s $588 becomes $49 because you divide by 12. Pine and Co is the churn list, at the $29 from the October snapshot.
ChartMogul’s MRR article says a monthly plan contributes the amount paid each month, and any other plan is normalized from the invoice amount and the billing interval. Their line item article says subscription and trial lines count, one-time charges do not, and tax is removed before the division. Their proration writeup uses this shape. Take the amount in cents, subtract tax, multiply by the ratio that turns the interval into a month, then multiply by a prorate factor. The factor is 1 when the line is not prorated. A $90 charge for 3 months is $30 of MRR in that page’s example.
The 10-hour clone keeps that non-prorated case. Cents divided by the interval. There is no tax column, so the cents in the file should already exclude tax. There is no refund column either. The MRR article says refunds change MRR only for Stripe, and other billing sources leave the number alone. The CSV cannot see that setting. If a charge was refunded and you do not want it in the month, leave the row out.
Their invoice handling article says the default is to count a new subscriber when the first invoice is fully paid. Issued, or partially paid, are the other choices. The clone does not know paid from open. You make that call before the row goes in the file.
A second Harbor row that also covers November is an error. One covering invoice per customer per month. Their line item article lists proration types for a mid-month change, including differential and full. The clone has no proration column. Resolve a plan change in the file, or leave it for the month row.
A third row, Lumen Co, has a start and a blank end. Import stays off. Northwind, Harbor, and the October snapshot are not touched.
Your browser talks to one Astro app. Node.js plus Astro is the default. Use TanStack Start if React is your weekday language. The capability line on the card is Astro, HTMX, and D1. Customers, plans, invoices, and the November snapshot live in D1. Nothing in this row calls Stripe.
Every query is scoped to Mira. A guessed customer id from another account returns an empty page.
Screens of a ChartMogul alternative
v1 needs the import, the month, and one customer. Expansion and a second file are the 3-day row.
The import
Mira has invoices-nov.csv open. Two rows preview clean. Lumen Co is marked bad because the period end is empty. Import is off until that row is gone. The note on the screen says a bad file writes nothing.
The month
After a clean file, November reads $98. Northwind and Harbor are active. Pine and Co is the churn list at $29. Mira does not type the total. It is the sum of the stored rows whose period covers November, with Harbor divided by 12.
The customer
Harbor’s page shows one invoice, the annual period, and the $49 that landed in November. The status is active because that period covers the month. Pine’s page would show the October invoice and a churned status, with no November row.
How an invoice CSV becomes a month
Mira drops the bad row and imports. The server checks every remaining row for a customer, a plan, an interval, an integer cent amount, and two dates. Then it writes customers, plans, and invoices in one transaction. If the write fails halfway, the month still shows October.
Node.js plus Astro reads that transaction back and builds the November snapshot. A customer is in the month when one invoice period covers it. MRR for that customer is the cents divided by the interval. The snapshot stores $98 and the two ids. Pine and Co is on the October snapshot and missing from this one, so the churn list is that name and $29.
Next month’s import uses this snapshot the same way. Expansion, a side-by-side of the two months, and a second billing CSV are the 3-day row. A Stripe connection, proration types, and a warehouse export are the month row.
Start with the first row
Go to Build your own ChartMogul. Copy the Astro prompt, or TanStack Start if that is what you write.
Tell the agent the first estimate only. Invoice import, MRR, and a churn list. Ten hours.
Import a clean invoices-nov.csv, confirm November reads $98, and confirm Pine and Co is the only churn row. Paste the all-or-nothing rule from How to write a coding agent prompt, and keep the three rows in How to scope a SaaS clone. If you need Stripe, proration, or a CRM, keep the plan you already pay for that part.