Keith Troutt: Turning tangled data into clear direction.
I work where data reaches the people who act on it.
Most organizations aren't short on data. They're short on direction. They're buried in dashboards and reports that describe what happened without making clear what to do next. That gap, between having the data and knowing where it points, is the problem I solve.
The way I work is simple: I embed with a client until their problem is my problem. Close enough to see it from the inside, I can shape what they're really after, and often surface an outcome they hadn't thought to ask for. Nearly two decades in BI taught me the rest, how to see where an organization is actually trying to go, and which question is worth answering before anyone builds anything.
I have the technical depth to make the answer real, from data modeling and visualization to full applications and AI-powered tools. But the technology was never the point. The point is taking something dense and tangled and making it obvious, and building whatever it takes to move an organization from where they are to where they need to be.
LinkedIn ·
GitHub ·
keith@keithtroutt.com
Portfolio
TabLens
Desktop IDE for Tableau workbooks: formula editing, dependency graphs, and AI documentation
Tools: Tauri v2, Rust, Svelte, Python, Monaco, Cytoscape.js
Award: 2nd Place, Tableau Conference 2026 Hackathon
Overview
A native desktop application that turns Tableau workbook maintenance into an engineered workflow. Open any .twb, .twbx, .tds, or .tdsx file locally, or connect straight to Tableau Cloud and skip the download/upload cycle entirely. Includes a Monaco formula editor covering all 182 Tableau functions with real-time validation, an interactive Cytoscape.js dependency graph, a Time Intelligence Builder with fiscal calendar support, cross-workbook calculation import, and a 4-step bulk AI documentation wizard. Built on Tauri v2 (Rust) with a Svelte frontend and Python sidecar, fully supported on macOS (Apple Silicon + Intel) and Windows.
Challenge
Tableau's native editor provides no way to visualize calculation dependencies, identify unused fields, or document an entire workbook at scale. Complex workbooks with dozens of calculated fields become impossible to audit or hand off.
Solution
Built a Tauri + Rust + Svelte desktop app that parses Tableau XML directly. The Monaco formula editor covers all 182 Tableau functions with autocomplete and signature help, and validates in real time, including nested aggregate detection through calculated field references, with proper LOD scope handling. Cross-workbook import opens a second workbook read-only and resolves a selected field's full upstream dependency chain automatically, handling name conflicts and datasource mapping. Tableau Cloud integration connects via Personal Access Token stored in the OS keychain: browse the project hierarchy, open a workbook, edit, publish back.
Also included: a Cytoscape.js dependency graph, a Time Intelligence Builder with fiscal calendar arithmetic and auto-variance generation, a health scanner with six performance rules, formula find-and-replace with preview, markdown export scoped to workbook or worksheet, timestamped backups on every save, and a bulk AI documentation wizard supporting Anthropic and OpenAI.
Impact
2nd place at the Tableau Conference 2026 Hackathon. Development began March 2, 2026 and TabLens was submitted that April. Now at v11.2.0 across 16 releases, with Tableau Cloud integration, cross-workbook calculation import, and a formula validator covering all 182 Tableau functions. Reduces workbook documentation and audit from hours to minutes.
View Releases on GitHub
TabShift
Self-hosted migration platform for Tableau Server to Cloud: audit, rationalize, and execute with full dependency ordering
Tools: SvelteKit, FastAPI, Python, Docker, SQLite
Overview
A self-hosted Docker application that takes organizations from Tableau Server audit to completed Cloud migration in a single platform. Runs entirely inside the customer network, so no data leaves. Built with a SvelteKit frontend, FastAPI backend, and SQLite state store, with live SSE progress streaming and checkpoint/resume surviving container restarts. Shares a Python XML parsing core with TabLens: same engine, different scale.
Challenge
Migrating from Tableau Server to Tableau Cloud is not a lift-and-shift. Organizations have years of accumulated workbooks, undocumented Prep flows, and permissions that have grown organically, with no reliable inventory, no dependency visibility, and no governance tooling.
Solution
Full REST API crawl of all site assets with real-time SSE progress and checkpoint/resume. 5-dimension asset scoring generates a 0–100 composite score with Migrate / Review / Retire recommendations and written rationale per asset. Full lineage graph built without a paid Catalog license. Dependency-ordered migration execution automatically patches workbook XML to repoint data source references. Includes a Prep flow parser that translates .tflow XML into Snowflake CTE chains (8 step types) with HIGH/MEDIUM/LOW confidence scoring and Jaccard-based redundancy detection. Air-gapped tarball for public sector environments.
Impact
Covers the entire migration lifecycle (audit, scoring, lineage, Bridge planning, migration execution, post-migration validation, and stakeholder reporting) in a single self-contained platform. Five HTML reports with custom organization branding for consultant delivery.
TabPromote
Content lifecycle management for Tableau Cloud: promote workbooks across Dev and Prod with semantic diffs and a one-click workflow
Tools: SvelteKit, FastAPI, PostgreSQL, Docker
Overview
A self-hosted platform for managing the Tableau Cloud Dev-to-Prod promotion workflow. Built for organizations using Tableau Cloud's multi-site Advanced Management setup: BI developers iterate on Dev, and the Center of Excellence reviews and promotes to Prod in a few clicks. PostgreSQL backend for multi-user access with credentials encrypted at rest.
Challenge
Tableau Cloud's multi-site environment separation (Dev/Prod) has no built-in promotion workflow. Teams manually download from the source site and re-upload to the destination, across dozens of workbooks, per release cycle. No diff, no review gate, no audit trail of what was promoted or by whom.
Solution
Three-column dashboard shows all configured Tableau Cloud sites side by side. Before promoting, displays a semantic diff summarizing changes to calculated fields, parameters, filters, worksheets, and dashboards since the last published version. Optional side-by-side XML view with synced scrolling. One-click promotion via Tableau REST API with configurable approval gates for COE workflows. Role-based access (Admin / Promoter) with a full promotion log recording content name, destination, user, and timestamp.
Impact
Eliminates the manual download/re-upload cycle entirely. COE teams see exactly what changed before promoting, with a complete, timestamped audit trail of every promotion across all sites.
VizMe
Browser-based wireframing for BI developers: mock up dashboards that look like Tableau, Power BI, or Sigma
Tools: React, TypeScript, Tailwind, Zustand, MCP
Overview
A browser-based wireframing tool where picking a skin (Tableau, Power BI, Sigma) re-shells the entire canvas to match that tool's chrome, fonts, and color palette. 15+ BI-specific widgets including bar, line, scatter, KPI tiles, filters, tables, Sankey, decomp tree, and maps. Multi-page projects with tab navigation, PNG/PDF export with editor UI stripped. Backed by a VizMe MCP server that exposes the live wireframe to Claude.ai via Model Context Protocol: click "Open in Claude" and Claude reads your wireframe directly, no copy-paste required.
Challenge
Generic wireframing tools (Figma, Miro) force BI work into boxes. When stakeholders see a Figma mockup of a "Tableau dashboard," they see Figma, not Tableau. Discovery sessions stall on aesthetics instead of layout and content decisions.
Solution
React + Zustand app with a skin system that re-shells the entire canvas per BI tool: Tableau's gray nav and blue accents, Power BI's dark header, Sigma's snap-to-grid layout. Added a MCP server (TypeScript on Vercel, Vercel KV for per-user state, Clerk auth) so users click "Open in Claude" and Claude reads the live wireframe through the Model Context Protocol, enabling design critiques, layout polish, or generation of a real .twbx Tableau workbook. Multi-user from day one with per-userId state keying and an append-only Zod-validated schema.
Impact
One of the first purpose-built BI tools with native MCP integration. Live wireframe-to-Claude handoff with no copy-paste or prompt engineering required. .twbx Tableau workbook generation validated against Tableau Desktop 2026.1.
Live site
SnowPro Gen AI Prep
GES-C01 exam study guide and practice platform: 47 topics, 4 domains, 506 practice questions
Tools: Next.js, TypeScript, MDX, Tailwind, Vitest
Overview
A hand-curated study guide and question bank for the Snowflake Specialty: Gen AI (GES-C01) certification. Every one of 47 topics lives as an MDX file with structured frontmatter, custom components (<ExamTip>, <Gotcha>, <TestYourself>), and SQL syntax highlighting via Shiki. Ships as 59 prerendered static pages with zero runtime dependencies. Practice mode serves randomized topic quizzes; exam mode simulates the full 55-question proctored format.
Challenge
Existing GES-C01 study resources are scattered, thin, or AI-generated content that fabricates Snowflake-specific behavior. Candidates have no structured path through the four exam domains and no reliable question bank that traces every claim back to a primary source.
Solution
Next.js 15 static site with MDX as the content database. Content discipline: one verbatim quote per source, maintainer browser-pull verification for every claim WebFetch could fabricate, distractors constructed by content (never letter-keyed) for correctness integrity. 479 tests across 51 files, including an MDX compile gate and a coverage gate that blocks commits if any catalog topic lacks questions. Single source of truth for slug → title → domain mapping enforced at build time.
Impact
506 practice questions (495 active) across 47 topics. 59 prerendered static pages, complete exam simulation, and a structured reading path per domain. Subscription access in progress.
NYC CitiBike Rentals
Tableau Public dashboard analyzing NYC CitiBike rental patterns: station usage, trip duration, and rider demographics
Tools: Tableau
Overview
An interactive Tableau dashboard exploring New York City CitiBike rental data. Visualizes station-level activity, trip duration distributions, rider type breakdowns (subscriber vs. casual), and temporal usage patterns across the CitiBike network.
Challenge
NYC CitiBike generates millions of trip records across hundreds of stations: raw data gives no intuitive sense of network usage patterns, demand hotspots, or how rider behavior varies by time, location, and membership type.
Solution
Built a Tableau dashboard that surfaces station-level usage patterns, trip duration distributions, and subscriber vs. casual rider breakdowns. Interactive filters let users explore patterns by time period and geography across the CitiBike network.
Impact
Published on Tableau Public. Demonstrates end-to-end data storytelling, from raw trip data to an interactive, shareable visualization.
View on Tableau Public
Decomposition Tree
Tableau Viz Extension that breaks a metric down by its contributing attributes to surface root cause
Tools: Svelte, D3.js, Tableau
Overview
A Tableau Viz Extension that brings decomposition-tree analysis natively into Tableau dashboards. Pick a measure and progressively break it down by one dimension after another, and the tree expands to show how each attribute contributes to the total, so you can drill from a headline number straight to the segments driving it. Built with Svelte and D3.js on the Tableau Extensions API.
Challenge
Tableau has no native decomposition tree: the Power BI-style "what's driving this number" visual. Analysts tracing a metric to its root cause have to build manual drill paths or rebuild the same nested breakdowns by hand for every question.
Solution
Built a Tableau Viz Extension with a Svelte frontend and a D3.js-rendered tree. Users pick a measure and add the dimensions to decompose by; the extension reads the worksheet data and renders an interactive, expandable tree where each node shows its share of its parent. Clicking a branch drills further, following the largest contributors down to the root cause.
Impact
Brings Power BI-style decomposition-tree and root-cause analysis into Tableau without leaving the dashboard, and is reusable across any measure-and-dimension combination.
SnowLens
Snowflake data profiling & quality workbench: profile a table or whole schema, score quality, infer keys, and generate non-destructive fix SQL
Tools: React, FastAPI, Snowpark Container Services, Docker, Cortex
Overview
A data profiling and quality workbench that runs entirely inside Snowflake as a Snowpark Container Services app. Profile a single table or an entire schema in one pass, review column-level quality metrics across six dimensions, infer primary/foreign keys, generate non-destructive fix SQL, and export client-ready HTML/PDF reports with ER diagrams, all from the browser. Built for the Snowflake Native App Marketplace and as a consulting accelerator for client data discovery.
Challenge
Data discovery on Snowflake is slow and manual: analysts write ad-hoc SQL to check null rates, formats, and key relationships table by table, with no consistent quality scoring and no client-ready output. And any cleanup risks mutating the source data it's meant to assess.
Solution
Built a Snowpark Container Services app (React + Vite frontend, FastAPI backend, NGINX router) that profiles a table, or an entire schema, in a single type-aware SQL pass. It scores every column across six quality dimensions, auto-detects primary and foreign keys (including composite) with confidence tiers, parses view DDL into a lineage graph with transitive risk, and surfaces Cortex LLM recommendations per column. A fix workbench previews the combined SQL live and executes it into clean Views, Materialized Views, or Dynamic Tables, never touching source tables. RBAC-aware throughout, so read-only users can view and copy SQL but not execute.
Impact
Turns multi-day client data discovery into a single browser session, with branded HTML/PDF and client-ready Markdown reports (embedded Mermaid ER diagrams) ready for delivery. Non-destructive by design and RBAC-aware, and packaged for the Snowflake Native App Marketplace.
Rebalance
An interactive map that solves the bike-share rebalancing problem using real Citi Bike data, with a routing optimizer built from scratch
Tools: DuckDB-Wasm, deck.gl, MapLibre GL, JavaScript, Python, Parquet, Vite, Vercel
Overview
Rebalance is an interactive look at a real logistics problem: every night, bike-share operators send trucks to move bikes from stations that fill up to stations that run empty, so riders find a bike and an open dock in the morning. Using a day of real Citi Bike trip data for Manhattan, the tool derives each station's surplus or deficit from actual ride flows, then routes a fleet of trucks to rebalance the system. Everything runs in the browser: DuckDB-Wasm handles the data and distance work, and a hand-written solver does the optimization. Users can adjust the vehicle mix or let the fleet optimizer pick it, watch a truck fill and empty along its route, and click any station to see why it's imbalanced hour by hour. Built with Claude Code, with a routing solver written from scratch rather than handed off to an optimization API.
Challenge
The hard part wasn't drawing a map, it was solving the routing honestly. This is a capacitated pickup-and-delivery problem, a cousin of the traveling salesman problem, where trucks can't carry more bikes than they hold and a station's need has to be met without wasted driving. I wanted the optimizer to be genuinely mine rather than an off-the-shelf routing API, and I wanted it fast enough to re-solve live as the inputs change. Getting real, messy trip data into a shape the solver could use, and keeping the whole thing responsive in the browser, was the core difficulty.
Solution
I aggregated millions of raw trips down to a per-station net-flow signal in DuckDB, then wrote a cluster-first solver: k-means to assign stations to trucks, nearest-neighbor to seed each route, and 2-opt to refine it, all respecting truck capacity at every step. The solver runs in a Web Worker so the interface never freezes. DuckDB-Wasm computes the distance work in-browser, deck.gl and MapLibre render the routes and animation, and a load-profile chart exposes exactly why a truck's route loops back when it hits capacity.
A fleet optimizer that solves all 104 vehicle mixes (up to 4 each of box truck, cargo van, and bike trailer, 8 total) and prices each one with a fixed dispatch cost per vehicle, a per-mile rate, and overtime past an 8-hour shift. Results plot cost against longest-route hours, exposing the tradeoff directly: a single box truck is cheap on paper until fifteen hours of overtime prices it out.
Impact
Full coverage of all 227 imbalanced stations at $535 across 108.5 miles, with a recommended fleet of two box trucks, one cargo van, and three bike trailers. The optimizer surfaces the real tradeoff rather than a single answer: three box trucks and one bike trailer cover the same ground with four vehicles for $19 more. A working demonstration of turning open data into a decision tool, with a hand-written solver rather than an optimization API.
Live site