Migrating From Tally Into ERPNext Without Losing Your Ledger
Every few weeks a business owner in Nairobi or Nagpur asks me the same question: "We have ten years of books in Tally. How do we move it all into ERPNext?" They have usually already found the answer that does not exist, an old GitHub thread titled something like "ERPNext Tally Migrator" that has been open for years with no maintained tool at the end of it. Every link is a dead fork or a consultant's private script.
So let me say the thing plainly: there is no supported, one-click Tally-to-ERPNext importer, and there probably never will be, because the hard part is not reading Tally's export. The hard part is that your two systems model accounting differently, and a tool cannot decide how your chart of accounts should map. That is a judgement call, and it is yours.
The good news is that you do not need ten years of transactions inside ERPNext. You need masters plus opening balances, and the framework already has the tools to load them correctly. This is the migration I have done for real SMEs, in the order that actually works.
Do not try to replay every historical voucher into ERPNext. Migrate masters (Chart of Accounts, Customers, Suppliers, Items) with the Data Import tool, then bring in opening balances only as of a clean cut-off date: GL account balances via an opening Journal Entry against the Temporary Opening account, customer and supplier balances via the Opening Invoice Creation Tool, and stock via a Stock Reconciliation with purpose Opening Stock. Then reconcile the opening trial balance against your Tally trial balance before you go live. Keep Tally read-only as your historical archive.
Why there is no reliable Tally importer
Tally and ERPNext both keep a double-entry ledger, but almost nothing lines up one-to-one. Tally has "Groups" and "Ledgers"; ERPNext has an Account tree with a root_type (Asset, Liability, Income, Expense, Equity) and an is_group flag. Tally mixes parties and ledgers freely; ERPNext splits a customer into a Customer master and a receivable Account. Tally's tax handling is a set of ledgers; ERPNext uses structured tax templates tied to items and party groups.
A generic tool would have to guess all of that mapping, and a wrong guess does not fail loudly. It produces a ledger that balances to the wrong numbers, which you discover three months later during an audit. That is why the honest approach is a guided manual migration of a small amount of data, not an automated replay of a large amount.
Step 1: Pick a clean cut-off date and freeze it
Choose an accounting period boundary, ideally the first day of a financial year or at least the first of a month. Everything before that date lives in Tally forever. ERPNext starts life with the closing position of that date as its opening. Trying to straddle a mid-period cut-off means you reconcile partial-month VAT and half-paid invoices by hand, which is where migrations go to die. A clean boundary is worth waiting a few weeks for.
Step 2: Map and import the Chart of Accounts
Export your Tally chart of accounts and, in a spreadsheet, add three columns next to each ledger: the ERPNext root_type, the parent account, and whether it is a group. This mapping is the single most important artifact of the whole migration. Do it deliberately.
ERPNext ships a default chart per country; decide early whether you are extending that default or replacing it with a faithful copy of your Tally structure. For an SME that already thinks in its Tally groups, I usually mirror the Tally structure so the accountant recognises the tree on day one. Import with the Data Import tool: go to Data Import, choose the Account DocType, download the template, and fill it. Import group (parent) accounts first, then leaf accounts, because a child cannot reference a parent that does not exist yet.
Import order for the Account DocType:
1. Group accounts (is_group = 1), top of tree first
2. Leaf accounts (is_group = 0), each pointing at an existing parent
Step 3: Import Customers, Suppliers and Items
Still in the Data Import tool, load the party and item masters, again downloading the template per DocType so the column names are exactly what ERPNext expects. Do them in this order:
- Customer and Supplier masters (names, groups, territory, tax IDs).
- Item masters (item code, item group, unit of measure, whether it is stock/non-stock).
- Only then anything that references them.
The Data Import tool validates against the DocType's own rules, so if a Customer Group named in your CSV does not exist, the row is rejected with a clear message rather than silently creating garbage. Create the supporting masters (Item Group, Customer Group, UOM, Territory) first, or the import will reject rows that reference them.
Step 4: Load opening balances the way ERPNext expects
This is where most home-grown scripts get it wrong. You do not import opening balances as raw GL rows. There are three distinct mechanisms, one per kind of balance.
GL account balances: an opening Journal Entry against Temporary Opening
For balance-sheet accounts that are not parties or stock (cash, bank, fixed assets, loans, equity), create a Journal Entry with Is Opening = Yes. Debit or credit each account with its cut-off balance, and put the balancing figure against the special Temporary Opening account. When every asset and liability opening is entered correctly, the balance on Temporary Opening nets to zero. That zero is your first sanity check: if it is not zero, an opening is missing or on the wrong side.
Customer and supplier balances: the Opening Invoice Creation Tool
Do not dump a single lump receivable figure into a customer account. Outstanding receivables and payables come in through Accounting > Opening Invoice Creation Tool, which creates one opening invoice per outstanding document. This preserves the ageing, so your first Accounts Receivable ageing report in ERPNext matches Tally instead of showing everything as due today. If you care about collections, and you do, this step is not optional.
Stock: a Stock Reconciliation with purpose Opening Stock
Opening inventory comes in through a Stock Reconciliation with Purpose = Opening Stock, giving each item its quantity and valuation rate as of the cut-off. ERPNext posts the stock value and balances it against Temporary Opening automatically, which is why the receivables, payables and stock openings all have to be counted when you check that account nets to zero.
Step 5: Reconcile the opening trial balance
Now prove the migration. In ERPNext open the Trial Balance report as of the cut-off date and compare it, line by line, against the Tally trial balance for the same date. They must agree to the last unit of currency. Work top-down: if a group total is off, drill into its children until you find the account that diverges.
Reconciliation checklist (must all be true before go-live):
[ ] ERPNext Trial Balance total debits = total credits
[ ] Temporary Opening account balance = 0
[ ] AR ageing in ERPNext matches Tally outstanding by customer
[ ] AP ageing in ERPNext matches Tally outstanding by supplier
[ ] Closing stock value in ERPNext = Tally stock summary value
[ ] Bank/cash opening balances match the last reconciled statement
If ERPNext and Tally disagree, the migration is not done. A trial balance that does not tie out is not a rounding quirk to shrug at; it is a real error that will compound with every transaction you post on top of it.
Multi-currency and tax templates
If you invoice in more than one currency, set the account currency on your bank and party accounts before loading openings, and enter each foreign-currency opening at the exchange rate ERPNext should record, not a blended average. Getting the rate wrong here creates phantom unrealised gains later.
For tax, build your Sales Taxes and Charges and Purchase Taxes and Charges templates to match your jurisdiction (VAT in Kenya, GST in India) before the first live invoice, and map your Tally tax ledgers to the accounts those templates post to. Do not try to migrate historical tax transactions; migrate the tax configuration and let ERPNext compute tax on new documents.
What people get wrong
Replaying every historical voucher. Teams write a script to import ten years of sales and purchase entries so ERPNext "has the full history". It is slow, it double-counts against opening balances, and it almost never ties out. You do not need it. Keep Tally as the read-only archive for anything before the cut-off and start ERPNext clean.
Importing opening balances as plain GL entries. Bypassing the Opening Invoice Creation Tool and Stock Reconciliation to "just insert the numbers" destroys ageing and stock valuation. The ledger total might match while every subsidiary report is wrong.
Skipping the group-before-leaf order. Importing the Account tree or item masters in arbitrary order produces a pile of rejected rows and a half-built tree that is worse than starting over. Order is not a nicety here; it is a hard dependency.
Going live without a tied-out trial balance. The temptation, under a deadline, is to accept "close enough". There is no close enough in a ledger. Fix it before the first invoice, because after that every report inherits the error.
When it is still broken
- Temporary Opening will not zero. You have missed an opening balance or entered one on the wrong side, or a stock or party opening was posted outside the Journal Entry and is not reflected. Re-run the checklist; the non-zero amount is usually exactly one missing account.
- Data Import rejects rows you think are valid. Read the error column, it is specific. The usual cause is a referenced master (Item Group, Customer Group, UOM) that does not exist yet. Create it and re-import only the failed rows.
- You need historical reports in ERPNext anyway. Reconsider whether you truly do. If a regulator requires it, import summarised monthly journal entries per account rather than every voucher, and clearly flag them as migrated.
- The mapping is bigger than one person can hold. This is a normal point to bring in help. A structured migration by someone who has done it is far cheaper than unwinding a mis-mapped chart of accounts a year in. If you want the broader shape of an engagement, I wrote about what an ERPNext implementation actually looks like.
Migration is not about moving everything. It is about moving the right small thing correctly: your masters and one honest opening balance. Do that, tie out the trial balance, and ERPNext starts its life on numbers you can trust.
Frequently asked questions
- Is there an official tool to migrate Tally data into ERPNext?
- No maintained, supported one-click importer exists, and the long-running community threads never shipped one. The reason is that mapping Tally's groups and ledgers onto ERPNext's account tree, party masters and tax templates is a judgement call a generic tool cannot make. The reliable path is a guided manual migration of masters plus opening balances.
- Do I need to import all my historical transactions into ERPNext?
- No. You need masters (Chart of Accounts, Customers, Suppliers, Items) and one clean set of opening balances as of a cut-off date. Keep Tally as a read-only archive for everything before that date. Replaying years of vouchers is slow, double-counts against openings, and rarely ties out.
- How do I load opening balances correctly in ERPNext?
- Use three separate mechanisms: an opening Journal Entry (Is Opening = Yes) against the Temporary Opening account for GL balances, the Opening Invoice Creation Tool for customer and supplier outstanding, and a Stock Reconciliation with Purpose = Opening Stock for inventory. When done correctly, the Temporary Opening account nets to zero.
- How do I know the ERPNext migration is correct?
- Run the Trial Balance report in ERPNext as of the cut-off date and compare it line by line against the Tally trial balance for the same date. They must agree exactly, the Temporary Opening account must be zero, and AR/AP ageing and stock value must match Tally before you post any live transaction.