Omni has acquired Explo 🥳 | Learn more

How I built an AI fantasy football app in Omni

From spreadsheet scrambles to streamlined stats

How I built an AI fantasy football app in Omni: From spreadsheet scrambles to streamlined stats

Editorial note: This blog shares how a member of our sales team ran the numbers to build a custom data app for their fantasy football league with Omni 🏈

In life, we are presented with many choices. One of the important ones is “How seriously do you want to take your fantasy football league?”. In my case, the resounding answer is extremely, and arguably, too seriously.

Aside from my job here at Omni, few roles or responsibilities matter more to me than being the Commissioner of the friends & family fantasy football league my Grandpa and I started back in 2010 – TRUFFLE, or The Radical Ultimate Fantasy Football League Experience. Rolls right off the tongue.

Now, I promised our Marketing team I wouldn’t go too deep into the minutiae of our league, but the headline is its sheer complexity: We’re talking Points per First Down scoring, 2 starting quarterbacks, and player Salaries & Contracts that can carry over from year-to-year and require all 12 teams in our league to stay below the 500 fictitious dollar Salary Cap — kind of like the NFL, minus the billion-dollar sponsorship deals. We’re working on it.

Capturing all that complexity left me with only one logical solution: build a custom fantasy football & salary cap analytics website to help everybody manage their teams and contracts. 

So, that’s what I did. 

What started as a fun sports and data side project in 2019 turned into TRUFFLEdash — a pretty nifty embedded analytics web app, if I do say so myself.

Now, let me finally tie this back to Omni…

Just like any product manager out there having the “build vs. buy” debate for analytics, my homegrown version of things had some shortcomings. From data living in CSVs, to random bouts of downtime, and the painful process of combing through 10,000 lines of R code to make minor aesthetic changes; maintaining the site became unsustainable. 

Enter Omni.

Fantasy Football app built with Omni Overview

When I first joined Omni, I wanted to get comfortable with the platform by spending time with familiar NFL data. The deeper I got into the product, the more my plan evolved. Rather than just exploring and visualizing data, I decided to see if I could build a fully Omni-powered TRUFFLEdash 2.0 for my entire league.

Now that you have some context on our league and website, let me dive into how I built it – from data prep and modeling to customizing the look and feel of the full web app.

Getting the data ready #

As with most home-cooked analytics projects, my data started scattered across a bunch of CSV files — half Python-scraped and cleaned NFL data, half manual admin files with league and team info that I maintained as commissioner (with important things such as team names, logo files, and custom color hex codes). Working in data, I knew there were better options. It was time for a full data stack refresh. After a thorough evaluation, I chose MotherDuck for the automated pipelines, combined with CSVs uploaded directly to Omni to handle my manually maintained data sources.

Getting started was easy. Within a couple of hours, I went from uploading my existing CSVs in the UI to using MotherDuck’s Python / R connectors to overwrite database tables directly from our scraping scripts. After adding a few join keys to link everything in Omni, our league was suddenly powered by a modern data stack.

When it came time to set up ingestion for my manual commissioner files, it seemed silly to make changes in a local CSV file, run a separate script to push that into MotherDuck, and then surface in Omni. That’s when I realized I was looking at a perfect use case to play with Omni’s native data input functionality to upload CSVs. By adding my data to Omni, I could manage changes in one central place, while making it easier to join and connect it with the data I’d already added to MotherDuck via our data model.

Modeling my data in Omni #

With all my data now available in Omni, it was time to start building my data model. I was able to kick things off right in the UI — pointing & clicking my way to quick aggregates, asking AI to pull in new columns, and creating calculated fields with Excel formulas. Compared to all of the previous work I’d done in R for the original TRUFFLEdash, this was seamless. With our core metrics calculated, the next step was curation.

Years ago, I learned that my fellow league mates get a whole lot more value from my analytics when I add a glossary, so I wanted to bring that into our new app in Omni, too. After adding the first few descriptions, synonyms, and drill paths from the pop-up UI, I knew some repetitive things would be easier to do right in the model code.

For example, the near identical data structure of Passing (Pa), Rushing (Ru), and Receiving (Re) statistics (each with their own respective Touchdown, First Down, and Yardage columns) lent itself perfectly to a pivot from the UI to the IDE. With a quick “find & replace” to swap column prefixes from “Pa” to “Ru” and “Re", and some easy code updates, I gave each column a helpful description tool-tip and drill path, and even added field-level AI context.

That natural language context became immediately valuable when I turned our AI assistant, Blobby, loose on my first Topic to fire off simple questions like “grab Ja’Marr Chase and Christian McCaffrey’s 2025 receiving stats, please” — always say please. More impressively though, Blobby could field broader questions like “Can you analyze scoring & contract trends by position?” — responding to open-ended questions with applicable visuals and thoughtfully written bullet point analyses. I was struck by the nuance and accuracy of our AI that was going to allow my league mates to ask questions just like they would in a text — without needing to understand the underlying schema, or even what ‘underlying schema’ means.

Last but not least, modeling in Omni allowed me to solve a handful of key user experience elements that help take the TRUFFLEdash 2.0 final product to a whole new level. By tying user attributes to default filter values, I could ensure that each of my fellow league members immediately sees their respective team’s roster and statistics anytime they log in. It also allowed me to add cross-linking to player and team name values to let users navigate across TRUFFLEdash pages — or right to the corresponding player/team page on our actual fantasy football platform.

Now, our entire league can hop on TRUFFLEdash to check out their player stats, and be one click away from setting their lineup accordingly on our host platform.

Building the app #

With the data ready under the hood, it was time to build a front-end application. And if manually maintained CSVs of team hex code colors weren’t a dead giveaway, you better believe I cared about making that front-end look good. 

As far as broad beautification goes, I started with Omni’s application and dashboard theming. The TRUFFLE logo has always featured a bright, light blue and a complementary, deep maroon. Armed with the exact hex codes, I was able to quickly bring those to all dashboard tile titles, navigation elements, and buttons — with color inversion across light, and critically, dark mode: a major new frontier for TRUFFLEdash. These extra touches may seem a little overboard (unlike the rest of this, of course), but they make a huge difference in elevating overall look and feel.

fantasy app light/dark shift

On the dashboards themselves, I had fun with a wide range of Omni visualization options. I started with some of our out-of-the-box KPI tiles and simple bar charts (with centrally stored color palettes by position), before diving deep into our table viz. Football box score statistics traditionally lend themselves to tabular consumption, and our EPD team has added a ton of features to help make standout numbers jump off the page. 

For example, I used column-level conditional formatting to apply the same positional color values, color scales for fantasy points, and bold values to highlight big performances such as 100+ rushing yard games. I was even able to bring our team logos and player headshots right into table rows using just the URLs.

maxawardslight

By far, the most fun I had was with our custom Markdown elements. While our out-of-the-box KPI tiles are extremely clean and let you add both numbers and sparklines, they do not feature custom football icons that represent different statistical categories. So, with the help of our resident Markdown wiz Sarah Waterson (check out her finest work here) and a little ChatGPT, I quickly built custom Markdown tiles featuring full interactivity, drilling, team logos, and the aforementioned football icons. And once I’d built one of them, Omni made it easy to reuse them throughout the site with column-swapper controls and minor Markdown code tweaks.

The final app-y touches also came in the form of Markdown. One of our resident product experts, James, introduced me to the powerful combination of nav bars and page anchors to let users quickly jump to key tables with HTML element references — creating a much snappier experience than scrolling. As for navigating across dashboards, a standard navbar across the top of each page allows users to feel like they’re navigating within a standalone TRUFFLEdash site, without ever needing to return to Omni’s home page or more traditional BI file system.

Finally, with all of those visuals and aesthetic touches combined, TRUFFLEdash had a front-end befitting of the powerful Omni engine under the hood.

Looking ahead #

As we enter Week 12 of our first season of TRUFFLEdash 2.0 in Omni, it has been a game-changer. Even though my team, the Roadrunners, and my Grandpa, and his Blossoms, still sit atop the standings, everybody in the league has benefited from our major analytics upgrade.

And that’s just year 1! Tune back in for a sequel to this blog when I’ve had a full offseason to make updates from embedding things into truffledash dot com, to implementing all of Omni’s upcoming new design features, and building a “trade machine” using dashboard inputs.

In the meantime, wish me luck on my fantasy football playoff quest! And if you’d like to learn more about building data products with Omni, we’d love to show you