Log 02: Early UI Demo and Database Decisions

By Sara Baqla11/12/2025
#IMRSprojectLogs#TanStack#learning#React

Pulling in iNaturalist Data (Very Rough Draft UI)

On this installment of the IMRS Project Logs, I am unveiling my very basic UI that is pulling in actual data from iNaturalist (Hudspeth County observations) plus 10 dummy species from a JSON file. Nothing is optimized, I haven’t separated the logic that’s making the calls, the JSON calls are duplicated, the iNaturalist data is capped at the 20 most recent observations, and I still haven’t narrowed it down to Indio Mountains Research Station observations.

Screen shot of iNaturalist observations in grid viewAside from refactoring these files and making my calls with Tan Stack Query, next on the research list is figuring out how to add a geofence delineating IMRS property and somehow use the iNaturalist API to cross reference the coordinates of an observation in Hudspeth County and determine if it's inside or outside the IMRS geofence. Sounds kind of janky. There's gotta be a better way!

Screenshot of Species Index UI with list, tabs, and search inputFiguring Out the SQL Data Structure

As for the SQL data structure, I kept flip flopping on how I wanted to set up the table(s). Initially I thought I would be storing about 5,000 species but it turns out to only be about 1,200 so I'm going to call my database "small". Columns will include taxonomic ranks (Kingdom → Phylum → Order → Family → Genus → Species), plus notes, collectors’ field numbers, authorship, etc. Growth is minimal with maybe 1–2 new species per year, so the dataset is pretty stable.

My conundrum was deciding whether or not to keep it as one wide table or break it into multiple related tables, a more normalized SQL DB. The data is hierarchical, which suggests reducing duplicate taxonomic levels. I got this idea from the BioSQL Schema Overview, which describes SQL DBs holding genomic data that can be around 1.5 GB for just one full human sequence. I’m not even going to guess how many rows that is. Decision no. 1 – single wide table for a small database.

Choosing a Relational Database

Now which relational db will I actually use? I thought of Supabase because the app will potentially have authentication down the road for admins to add/edit/delete species in the database, but the free tier didn't seem like it would be enough memory for my needs. Then I stumbled upon an oldie but goodie, SQLite! I know it's super popular and used in pretty much all mobile apps. Since my data is small and pretty stable, I thought this would be the perfect fit. Decision no. 2 - SQLite as the database engine.

Hosting the SQLite Database

Of course, that immediately raised the question of where to host it. My initial search made me believe that Vercel did not have the ability to host a SQLite DB, so I started looking at Heroku, Turso, AWS, DigitalOcean, and other relatively cheap hosting options but my goal budget is $0, so I had to keep looking. Turns out I didn’t dig very deep the first time, and I eventually found out Vercel has partnered with Turso to host SQLite databases. Five GB of storage and 500M monthly reads, all for free?!?! Sign me up! Decision no. 3 – cloud hosting on Turso connected through Vercel.

Next Steps: Converting the PDF and Exploring TanStack Query

Now that I have these major DB decisions made, I need to convert the PDF into CSV data to import into SQLite. I’ll definitely leverage AI to do the grunt work of formatting the text into columns. We’ll see how that goes. While I’m getting the data situated, next steps are to look into TanStack Query and take advantage of all the cool features it offers out of the box. Stay tuned!

If you want to poke around the very rough-but-functional UI, here's the latest deployed version:

https://imrs.vercel.app/

Powered by wisp

Log 01: A TanStack Adventure

The WHY and possible HOW behind IMRS Biodiversity Explorer.

On The Hunt
Sep 14, 2025

Meet Sara at the start of her job hunting journey.

CYC 2025 Recap
Oct 01, 2025

Takeaways from CYC '25