Build 3 Tableau Viz Extensions Live with Claude Code
A live, unscripted workshop: a heat map, a radial bar chart and a custom table built as Tableau viz extensions with Claude Code, errors and port conflicts included.
The short version
Eric runs a pop-up workshop building three Tableau viz extensions on Superstore data with Claude Code in VS Code: a calendar heat map with marginal sum bars, a radial bar chart, and a custom table. He starts from an empty folder and short prompts on purpose, to show how little Claude needs to be told about what a Tableau extension is.
Before building, he covers the basics: viz extensions live on a worksheet's Marks card, dashboard extensions drop onto a dashboard, and both load a .trex manifest that points Tableau at web files. Locally that's a Python http.server on localhost. On Cloud or Server the files need a public home, which can be as simple as GitHub Pages or a public S3 bucket.
Most of the session is the real loop: load the extension, hit an error, copy it back to Claude, reload. Running two Claude sessions in one folder causes port conflicts and mixed-up projects, which he calls out as the thing to avoid. By the end all three extensions render on one dashboard with config modals, after roughly 90 minutes that he estimates was under an hour of actual prompting.
The breakdown
The manifest is the bridge, and hosting can be as simple as a public bucket
Eric describes the .trex file as the bridge between Tableau and your HTML and JavaScript. It tells Tableau where the web code lives and carries the author details that show up in the permission pop-up when someone adds the extension.
For local work a localhost server is enough. Once a workbook is published to Cloud or Server, the files must be reachable from the public web. He shares his own files from GitHub Pages and notes a public S3 bucket with the HTML, JavaScript and CSS dropped in works too. The starter repo includes a manifest.hosted template for that step.
Fable was about twice as fast as Opus, without a big quality jump
Eric mostly uses the latest Opus. He tried Fable until it was revoked the week before and found that everything ran about twice as fast, but asking both Opus 4.8 and Fable for the same solution didn't show a big quality difference.
On cost, he got by on the $20 a month Claude plan for a while and now uses the tier with five times the usage, and says he doesn't usually hit its limit.
Building your own extension is the safe answer when data access is on the line
Some extensions need detail-level data access, and on Tableau Cloud every extension has to be allowlisted and approved by an admin. Eric points to the Extension Exchange, where Tableau hosts its own extensions and approved partners like LaDataViz publish theirs.
His stance: at a company with PHI he would not tick the full data access box for an outside extension, other than Tableau's own. Building it yourself and hosting it internally lets you give it the access it needs. He also mentions that getting onto the Exchange is a lengthy process he is going through himself.
Errors are normal: copy the message, give it back to Claude, reload
The first loads of both extensions throw errors, including a missing XML element in the manifest. Eric's routine is to copy the error (right-click is the only way to copy inside Tableau), paste it to Claude, and reload. Usually the next iteration runs.
He notes the starter repo's CLAUDE.md was written after many of these rounds, so recurring mistakes get folded into the instructions. Changing HTML only needs a click on the extension in the Marks card dropdown, but any manifest change, like a new port, needs a full reload of the .trex file.
Claude extends past the prompt, and a screenshot steers the style
The radial bar prompt only asked for a chart that's customizable from a config modal. Claude added a title, spacing, radius, rounded ends, label and font options, reference rings and bar sorting on its own. Eric likes that it thinks past the exact prompt, while noting sometimes you want exactly what you asked for.
When the first radial came out in a different style than he expected, his trick was to take a screenshot of the one he wanted and say "I'd like this style." Later he asks for a toggle between the two styles, live canvas updates as you slide, a gradient color option and a reset to defaults button.
Two Claude sessions in one folder will trip over each other
Running the radial and heat map in parallel in the same folder caused port clashes and mixed up the two projects. Eric moves ports from 8765 to 1111 and 2999, reloading the manifest each time, and tells beginners to focus on one extension until it loads.
Asking Claude what other features it would recommend returned, first, a suggestion to separate the projects. Near the end a session sets up a single npm start that serves all three extensions from their own folders.
Creativity is the bottleneck now, plus a little code sense
An attendee who built a workbook calculation lineage web app with Claude says so many barriers have been removed that creativity is the bottleneck, while knowing a bit about what the code should do helps a lot. Eric agrees, and adds that you can ask Claude how to avoid the hang-ups you hit next time.
Both note that a few years ago this would have meant a full development cycle in JavaScript, HTML and CSS, plus a lot of Stack Overflow.
A detailed prompt turns into a feature checklist for the custom table
For the table Eric uses prompts he prepared ahead of time. Claude splits one extensive prompt into eight features with a to-do list and works through all of them before he tests.
The result has dark mode, compact spacing, cell styles (plain, bars, heat, dots), zebra striping, export with field selection, instant search, pagination and sorting. Earlier he explains why a table is a good fit: a web table renders text directly instead of drawing every mark, so it can outperform a native Tableau table.
Key takeaways
- Claude already knows what a Tableau extension is, so a one-line prompt is enough to get started.
- A .trex manifest points Tableau at your web files, and on Cloud or Server those files just need a public home like GitHub Pages or an S3 bucket.
- When it breaks, copy the error back to Claude and reload; any manifest change needs a full reload of the .trex.
- Run one Claude session per extension and give each project its own folder to avoid port and file conflicts.
- For a heat map built off a date field, set the pill to exact date so the config can pick the date parts.
- Building your own extension lets you grant data access without trusting an outside vendor with sensitive data.
Watch this when
You want to see the unedited process of building Tableau viz extensions with Claude Code, including the errors and how to get past them.
Mentioned in this video
- 13:31Tableau extension starter repo ↗
Includes a CLAUDE.md, a base index.html and a hosted manifest template
- 9:35How to host a Tableau extension →
Localhost vs GitHub Pages or S3 hosting
- 28:50Tableau Exchange ↗
Where Tableau and approved partners publish extensions
- 29:37LaDataViz ↗
Tristan's viz extensions, an approved Exchange partner
- 36:48Tableau Extensions API ↗
The JavaScript library Tableau maintains that extensions call
- The Viz Extension Kit ↗
Every extension with full source, to modify and self host
- 90 minute 1:1 build session ↗
Build one on your own data, includes the Kit