What I learned vibe coding an EV charging map out of Australian open data
Six openly-licensed government and community datasets. 3,157 charging sites, 9,216 plugs, and a long list of things that went wrong. Some of them were the publishers' fault. Several were mine.
The short version
Australia has no national EV charger dataset. What it has is one community database, four state government publications, one territory's policy page, and a lot of inconsistency between them. Stitched together carefully, that gets you about four fifths of the country's public charging.
I wanted to know whether you could build a genuinely useful national charging map without paying for commercial data. The answer is mostly yes. The interesting part isn't the total, though: it's everything that goes wrong on the way there.
This post covers three things: what the combined data actually says about sites and plugs, who operates them (with a table of every operator I could identify and a verified link to each), and every problem I hit. I've been deliberate about including the mistakes that were mine, because they were more instructive than the publishers'.
Sites and plugs: what the data says
After reconciling 3,806 source records into 3,157 distinct sites (merging 649 duplicates along the way), here is the shape of Australian public charging as open data sees it.
Sites by state and territory
Tasmania's bar is split: 81 sites with real coordinates, plus 55 known only to the town (purple). NSW dominates partly through genuine density and partly because NSW simply publishes more than anyone else.
Sites by charging speed
The grey bar is the problem: 1,447 sites (46%) have no usable power rating in any source. Only 54% of sites state their kilowatts.
9,216 plugs is the sum of every plug count actually published, and only 83% of sites publish one. The true figure is higher. For comparison, the commercial tracker Carloop put Australia at roughly 3,774 sites and 10,350 bays in August 2026, which makes this open-data build about 82% of sites and 89% of bays, but those two numbers are counting slightly different things, and anyone who quotes a single national plug total with confidence is overselling it.
How complete is each field?
Coverage is not the same as completeness. A site can be in the data and still tell you almost nothing useful:
| Field | Sites with a value | What that means in practice |
|---|---|---|
| Connector type | 87% | Usually the best-populated field |
| Site name | 64% | The rest fall back to operator + suburb |
| Power rating (kW) | 54% | You cannot filter reliably by charging speed |
| Confirmed by 2+ sources | 12% | Each dataset covers a different state, so overlap is rare |
| Pricing | 0% | Not published by anyone, anywhere |
| Live availability | 0% | No open source exists; see the last section |
Every operator I could identify
This is the table I most wanted when I started and could not find anywhere.
38 operators run five or more sites, accounting for 2,928 of 3,157 sites (93%).
Sites is reconciled physical locations, not charger units. Plugs is the sum of published plug counts, so where a operator's sites don't all publish one the figure is a floor: the percentage tells you how much of it is covered. Max kW is the highest per-plug rating stated anywhere in that operator's records. Two of these names are truncated in the source data itself, which I've left as-is and flagged rather than silently "fixing".
| Operator | Sites | Plugs | Max kW | Current mix | States | Website |
|---|---|---|---|---|---|---|
| Chargefox 3 planned Owned by NRMA, RACV, RACQ, RAA, RAC and RACT |
449 | 1,728 from 81% of sites | 350 | 194 DC 270 AC |
ACT NSW NT QLD SA TAS VIC WA | www.chargefox.com |
| Tesla 24 planned Supercharger + Destination |
416 | 1,694 from 93% of sites | 350 | 174 DC 211 AC |
ACT NSW QLD SA TAS VIC WA | www.tesla.com/en_AU/findus/list/superchargers/Australia |
| Exploren OCPP platform; many host-operated sites |
325 | 914 from 98% of sites | 180 | 52 DC 272 AC |
ACT NSW TAS VIC WA | exploren.com.au |
| Evie Networks 8 planned OSM still lists the old goevie.com.au |
290 | 1,095 from 79% of sites | 400 | 264 DC 5 AC |
ACT NSW NT QLD SA TAS VIC WA | evie.com.au |
| (unattributed) No operator published by any source |
221 | 253 from 38% of sites | 400 | 35 DC 51 AC |
ACT NSW NT QLD SA TAS VIC WA | — |
| Non-networked 4 planned A TfNSW placeholder, not an operator |
218 | 528 | 22 | 214 AC | NSW | — |
| NRMA 16 planned | 132 | 735 from 91% of sites | 350 | 123 DC 14 AC |
NSW NT QLD SA TAS VIC WA | www.mynrma.com.au/electric-vehicles/charging |
| PLUS ES 2 planned Ausgrid subsidiary; kerbside AC |
106 | 114 | 350 | 2 DC 104 AC |
NSW | www.pluses.com.au |
| EVX Pole-mounted kerbside |
103 | 221 from 99% of sites | 22 | 103 AC | NSW VIC | evx.tech |
| BP Pulse 29 planned | 86 | 303 from 87% of sites | 350 | 81 DC | ACT NSW QLD TAS VIC | www.bppulse.com/en-au |
| Ampol AmpCharge |
81 | 323 from 85% of sites | 400 | 76 DC | ACT NSW QLD VIC | www.ampol.com.au/ampcharge |
| JOLT | 72 | 91 from 69% of sites | 50 | 56 DC 4 AC |
NSW QLD SA VIC | joltcharge.com/au |
| Yurika Energy Queensland |
50 | 60 from 58% of sites | 75 | 47 DC 41 AC |
NT QLD | www.yurika.com.au |
| EVUp | 39 | 82 from 97% of sites | 100 | 1 DC 35 AC |
NSW QLD VIC | www.evup.com.au |
| Everty | 34 | 81 | 60 | 4 DC 30 AC |
NSW | everty.com.au |
| Central Victorian Greenhouse Alliance Council alliance, not a network |
34 | 31 from 44% of sites | 62 | 30 DC | VIC | www.cvga.org.au |
| Electric Highway Tasmania town-level Own domain now redirects to NRMA |
30 | 19 from 37% of sites | 350 | 25 DC 12 AC |
TAS | www.mynrma.com.au/electric-vehicles/charging/electric-highway-tasmania |
| Smart Charge | 23 | 57 | — | 23 AC | NSW | smartcharge.com.au |
| EVE Australia No site resolved; may be EVSE Australia |
21 | 52 | 60 | 2 DC 19 AC |
NSW | — |
| ChargePoint Global hardware/network |
20 | 30 from 60% of sites | 22 | 10 AC | NSW QLD SA VIC WA | www.chargepoint.com |
| EVSE Possibly the same firm as "EVE Australia" |
20 | 52 | 22 | 20 AC | NSW | evse.com.au |
| Porsche Smart Mobility Destination charging at dealers |
19 | 39 | 22 | 19 AC | NSW | — |
| Fast Cities Australia 17 planned
Name truncated in the TfNSW export; no site found |
17 | 80 | 350 | 17 DC | NSW | — |
| EVNet Rebranded: evnet.com.au now redirects here |
15 | 35 | — | 15 AC | NSW | chargengo.au |
| Noodoe | 13 | 28 | — | 12 AC | NSW QLD | www.noodoe.com |
| ChargeHub No site resolved |
12 | 36 | 25 | 1 DC 10 AC |
NSW WA | — |
| EVlink No site resolved |
10 | 12 from 70% of sites | — | 1 AC | NSW QLD VIC WA | — |
| Elanga | 9 | 34 | 50 | 1 DC 8 AC |
NSW QLD | elanga.com.au |
| Viva Energy Australia 6 planned Name truncated in the TfNSW export |
7 | 28 | 350 | 7 DC | NSW | www.vivaenergy.com.au |
| Charge Hub Possibly the same as "ChargeHub", unresolved |
7 | 19 | — | 7 AC | NSW | — |
| Engie Site returns an authorisation error from Australia |
7 | 12 from 86% of sites | 150 | 7 DC | NSW VIC | — |
| Saascharge No site resolved |
7 | 17 | 22 | 7 AC | NSW | — |
| INTELLIHUB AUSTRALIA Pty Ltd | 7 | 11 | 22 | 7 AC | VIC | www.intellihub.com.au |
| Electrona Pty Ltd town-level | 7 | 3 from 29% of sites | 22 | 1 DC 1 AC |
TAS | electrona.com.au |
| CasaCharge | 6 | 13 | — | 1 DC 5 AC |
NSW WA | casacharge.com.au |
| Brisbane Airport Corporation Airport, not a network |
5 | 28 | — | not published | QLD | www.bne.com.au |
| 360 EV Charge No site resolved |
5 | 15 | — | 5 AC | NSW | — |
| Charge Post | 5 | 40 | 22 | 5 AC | NSW | www.chargepost.com.au |
Beyond those 38 operators sit 176 more with fewer than five sites each (229 sites and 303 plugs between them). 143 of them appear exactly once. They are pubs, councils, wineries, golf clubs and car dealers who installed a charger and got named as its operator. That's 214 distinct operator strings in total, and it is the single clearest sign that "operator" in this data means several different things at once: a charging network, a site host, a hardware platform, or a placeholder.
Where the data comes from
Six sources, all openly licensed, none requiring an API key. Note how lopsided the record counts are, and that three of the six are limited to government-funded sites rather than everything in their state.
| Source | Covers | Records | Licence | Refresh |
|---|---|---|---|---|
| OpenStreetMap (Overpass API) Full published extent |
AU (national) | 1,590 | ODbL 1.0 | daily |
| Transport for NSW Full published extent |
NSW | 1,958 | CC-BY 3.0 AU | weekly |
| Victoria DEECA Government-funded chargers only: not a complete Victorian inventory. |
VIC | 152 | CC-BY 4.0 | weekly |
| QLD Transport and Main Roads Queensland Electric Super Highway sites only: not a complete QLD inventory. |
QLD | 17 | CC-BY 4.0 | weekly |
| ACT Government ACT Government-funded chargers only (131 bays). The page states 300+ public bays exist territory-wide, so this is roughly 44% of ACT public charging. |
ACT | 34 | CC-BY 4.0 | weekly |
| Tasmania NRE ChargeSmart grant recipients only, located to TOWN level with no street address. Excluded from the default map view; not a charger location. |
TAS | 55 | CC-BY 4.0 | monthly |
Mixing OpenStreetMap into your own stored database makes that database an ODbL "Derivative Database", not merely a "Produced Work", so share-alike attaches to the whole thing, and you must offer it back under ODbL on request. Combining CC-BY government data with OSM does not give you a CC-BY database. If your plan depends on keeping the result proprietary, that plan breaks, and you will discover it after building rather than before.
South Australia's page shows only an indicative design map; Western Australia's "charger map" is a JPEG inside a PDF and its terms are non-commercial only; the Northern Territory points you at PlugShare. Coverage in those three comes entirely from OpenStreetMap volunteers.
Everything that went wrong
This is the useful part. Not one of these was visible from a dataset's description page: every one turned up only by running the data.
1. The open-data portal is not where the open data is
I originally recorded the ACT as publishing nothing, because its open-data portal returns only federated US Department of Energy records. The ACT in fact publishes its full funded-charger list as HTML tables on a policy page. Re-checking the other jurisdictions with that lesson in hand found Tasmania doing the same thing.
Any data survey that only queries portal APIs will under-report. Policy, programme and grant pages need checking too. Two of eight Australian jurisdictions publish charger lists that no portal search will ever surface.
2. A field that means the opposite of what it looks like
Victoria publishes estimated_project_completion. The obvious reading (populated
means "not yet built") is wrong. 96 of 152 rows carry a value and most are past dates
describing finished projects. Taking it at face value mislabelled 96 live sites as unbuilt.
Parsing the date and comparing it to today gives the real answer: 11. Australian
dates are day-first, so Date.parse() can't be used either.
3. Truncated names, in the publisher's own export
The TfNSW dataset contains "Fast Cities A" (17 rows) and "Viva Energy A"
(7 rows): names cut off mid-word. Inconsistently, too: one row has the full
"Viva Energy Australia", which splits one company across two operator values. A
third appears as "PLUS ES Manag". I left them as published and flagged them, because
silently "correcting" a publisher's data is how you end up with a dataset nobody can reconcile
against the source.
4. HTTP 200 is not the same as good data
Two separate incidents, both silent:
- Queensland's CSV returns HTTP 403 with an HTML error page to any
non-browser client. A lenient parser reads that as a zero-row CSV. The same file also has
newlines inside quoted fields, so it holds 17 records where
wc -lclaims 34. - When the primary OpenStreetMap endpoint timed out, the fallback mirror returned a complete-looking 1,493 elements against the primary's 1,590. Nothing truncated, no warning: the mirror's database was simply 43 days stale. A silent 6% coverage loss, small enough to slip under any record-count threshold.
Validate a response before it replaces your cached copy, and where a source states its
own data age, check it. Overpass reports timestamp_osm_base;
refusing anything older than a week turns an invisible degradation into a loud failure. Your
own slightly-old cache beats someone else's much-older data.
5. Publishers state totals: use them
The single most useful trick I found. Both the ACT and Tasmanian pages state their own
figures: "74 public EV chargers with 131 charging bays", and a Total row of
$567,000, so the parse can reconcile against them and refuse the page if it
doesn't add up. That converts a fragile HTML scrape into one that fails loudly when the page is
restructured, instead of quietly returning fewer rows.
// Tasmania: three tables, three stated grant totals, all reconciling
Chargesmart 3 2025 parsed $567000 stated $567000 OK
Fast charging parsed $710500 stated $710500 OK
Destination charging parsed $62500 stated $62500 OK
6. Some coordinates are not locations
Tasmania publishes a town name and nothing finer. Geocoding "Miena" gives you the centre of
Miena, which for a charger is kilometres out. So precision became a graded property rather than
a boolean: surveyed (~10 m), geocoded_address (~100 m, the ACT), and
geocoded_locality (~5 km, Tasmania). Town-level records are excluded from the map by
default, never merged with anything, never returned as "nearest", and confidence-penalised,
while staying fully searchable, because "is there a funded charger in Miena?" is a real question
nothing else answers.
7. Stale and rebranded links inside the data
While verifying operator websites I found OpenStreetMap still carrying
goevie.com.au for Evie Networks, whose site is now evie.com.au. EVNet's
domain redirects to chargengo.au, a rebrand. Electric Highway Tasmania's domain now
lands on an NRMA page. Any URL you inherit from crowd-sourced data needs checking before you
put it in front of a user.
8. "Operator" is four different concepts
214 distinct values, 143 of them
appearing once. "Non-networked" (218 sites) is a TfNSW placeholder, not a company.
"ChargeHub" (12 sites) and "Charge Hub" (7) may or may not be the same
business: I could not resolve it, so I left them separate and said so. Same for
"EVE Australia" and "EVSE". Alias folding fixes the obvious cases
("BP" and "BP Australia"; "Tesla" and "Tesla Motors") but you cannot fold what you cannot verify.
9. The bugs that were mine
Worth separating out, because they were the most instructive failures and none of them were the publishers' doing.
Two PLUS ES sites showed 350 kW on an AC connector. AC charging tops out
around 43 kW, so this was impossible on its face. The cause: TfNSW's
Charger_Type column isn't always "AC" or "DC": 98 rows say
"Upcoming", and my code treated anything that wasn't literally "DC" as AC. Now
the current type is inferred from the power when the stated type is unusable, and no connector
is emitted at all when neither can settle it. A whole-dataset invariant asserts no site ever
claims AC above the physical ceiling.
The ACT names venues ("Next Gen Canberra"); OpenStreetMap entries without a name tag fall back to the operator ("Exploren"). Those vocabularies never resemble each other, so my name-similarity penalty fired on records at the same coordinates and blocked the merge. Fixing it recovered five further cross-source merges nationally: the bug had been quietly costing matches everywhere, not just in the ACT.
Tasmania and the ACT both geocode, and the geocoder resolved "Mawson Club" (10 Heard St) and "Southlands Shopping Centre" (12 Heard St) to the identical point. Between two geocoded records, distance carries no information: 0 m may mean "same site" or "the geocoder couldn't tell them apart". So two geocoded records now require name agreement to merge.
The town-level opt-in worked in the CLI and the core engine but was silently ignored over HTTP, because I never mapped the query parameter. I had a cross-surface equivalence test specifically to catch this class of divergence, and it missed, because its case list didn't include that parameter. Such a test only guarantees the cases you enumerate.
The bar charts in the first version of this write-up were completely empty and
I published them twice without noticing. The fills were <span> elements, and
CSS width and height don't apply to non-replaced inline elements, so all 13 rendered at 0×0.
The automated render check passed both times (a zero-size element produces no console error
and no failed request), and my own checks measured container geometry and read text
back, which an empty rail satisfies perfectly.
The lesson generalises past CSS: if the thing you're verifying is drawn, assert something about the drawing. I now check that nothing styled to have a size renders at zero size, which catches the whole class rather than the one instance.
What I'd tell you before you start
- Settle the licence question first. It's the one decision that is expensive to reverse, and it is a product decision disguised as a footnote.
- Budget real effort for reconciliation. NSW alone has more records than all-of-Australia OpenStreetMap, and neither is a superset. Concatenate them and you ship doubled pins; round coordinates to deduplicate and you merge distinct chargers in one car park. This is where the perceived quality of the whole thing lives.
- Never invent a value. An unparseable rating stays null. A missing fee is unknown, not free. A town name is not a location. Guessing corrupts silently and is invisible in testing.
- Look for an invariant the publisher already asserts: a stated total, count or date you can reconcile against. It's the cheapest possible way to make a scrape trustworthy.
- Validate before you cache, or an error page becomes your dataset.
- Send corrections upstream. Fixes belong in OpenStreetMap, where they benefit everyone and flow back on your next ingest. A private correction store forks from your sources and rots.
- Say what you don't know. No pricing, no live availability, roughly one site in five missing entirely, and four jurisdictions where every pin came from a volunteer. A map that admits this is more useful than one implying uniform authority.
Live availability does not exist in open form. Not at any effort level: it's an OCPI roaming or per-operator partnership problem. If you add it later it belongs as a request-time overlay that is never written into your dataset, because a cached "available" sends a driver to an occupied charger with false confidence. That's worse than no answer.