UT Dining is your companion app for exploring dining options at the University of Texas at Austin. Browse menus, check dining hours, and find the perfect meal on campus.
This project has been adopted by Longhorn Developers. Originally created by Ethan Lanting.
- Features
- Tech Stack
- How it Works
- Getting Started
- Project Structure
- Contributing
- Frequently Asked Questions
- Related Repositories
- License
- Real-time Menu Updates: View current menus for all UT Austin dining locations
- Favorites: Save your favorite food items and get notified when they appear on menus
- Meal Planning: Create daily meal plans with nutrition tracking
- Allergen Information: Filter food items based on dietary restrictions and allergens
- Location Information: Check operating hours, location details, and whether dining halls are currently open
- Microwave Map: Find microwaves on campus to heat up your food
- Framework: Expo + React Native
- Navigation: Expo Router
- Global State Management: Zustand
- Database:
- Remote: Supabase
- Local: SQLite with Drizzle ORM (learn more here)
- Styling: NativeWind (Tailwind CSS for React Native)
- Icons: Lucide React Native
At the core of the system is a remote Render instance, which is scheduled to run every 24 hours at 7:00 AM UTC (or 1:00 AM CST). This instance is responsible for scraping the dining menus from UT Austin, sourced from this page. Once the menus are scraped, the data is stored in a Supabase database.
Every 24 hours, the Expo mobile application fetches the latest menu data from the database, keeping the application up-to-date. To optimize performance and reduce loading times, the data is cached locally in an SQLite database using Drizzle ORM. This local cache allows the app to quickly retrieve the necessary information, ensuring a smooth, offline-first user experience.
- Node.js (LTS version recommended)
- pnpm
- Docker Desktop
- Expo CLI
- An iOS or Android emulator. Follow the guide here to set up an Android emulator or here for an iOS simulator.
We recommend using the following VSCode extensions to improve your development experience:
- ESLint: For identifying and fixing linting issues.
- Prettier: For automatic code formatting.
- Tailwind CSS IntelliSense: For Tailwind CSS class autocomplete and IntelliSense.
-
Fork the Repository
Go to the UT Dining repository and click the Fork button in the top-right corner of the page.
After forking, clone the repository to your local machine:
git clone https://github.com/<your-username>/ut-dining.git cd ut-dining
-
Install Dependencies
pnpm install
-
Run Local Supabase Instance
For this step, you need Docker Desktop installed on your machine. Follow the guide to install it on your system.
Next, install the Supabase CLI. Follow the guide here.
After installing the Supabase CLI, run the following command to start a local Supabase instance:
supabase start
Once it's up and running, you should see a message like this in the terminal:
Started supabase local development setup. API URL: http://localhost:54321 DB URL: postgresql://postgres:postgres@localhost:54322/postgres Studio URL: http://localhost:54323 Inbucket URL: http://localhost:54324 anon key: eyJh...... service_role key: eyJh......
The
API URL
andanon key
are the environment variables you need to configure in the next step.Optional (but HIGHLY recommend): Setting up Related Services
If you want to work with the complete UT Dining ecosystem, you can also set up:
- UT Dining Scraper: To seed your local Supabase database with menu data, clone the scraper repository in a separate directory and use the same
API_URL
andanon key
from your local Supabase instance in the.env
file. - UT Dining Dashboard: To manage location information and other admin features through a web interface, clone the dashboard repository in a separate directory and use the same Supabase credentials in the
.env
file.
- UT Dining Scraper: To seed your local Supabase database with menu data, clone the scraper repository in a separate directory and use the same
-
Configure Environment Variables
Copy the
.env-example
file to create a.env
file:cp .env-example .env
Update with your Supabase
API URL
andanon key
credentials:EXPO_PUBLIC_SUPABASE_URL=<supabase-url> EXPO_PUBLIC_SUPABASE_ANON_KEY=<supabase-anon-key>
-
Create an Expo Account
Create an account at expo.dev. Once you create the account, you can log in with:
npx expo login
-
Setup the Development Build
Since the app uses react-native-mmkv instead of
AsyncStorage
, you must run it with a development build rather than Expo Go.Run the following commands to build the development version:
-
For iOS:
pnpm run ios
-
For Android:
pnpm run android
If you're developing for both platforms, run both commands.
Note: The build process may take some time. Please wait until it completes.
-
-
Download to physical device (OPTIONAL)
If you want to test the app on a physical device, connect your device to your computer with a USB cable and run the following command:
- For iOS:
npx expo run:ios --device
- For Android:
npx expo run:android --device
Note: Make sure to enable USB debugging on your Android device. You can find the instructions here.
This will install the development build onto your device.
-
Start the Development Server
pnpm run start
Make sure that you are using
development build
instead ofExpo Go
when running the app. You can switch to the development build by pressings
in the terminal.Tunneling for Physical Devices
If you're using a physical device on a public Wi-Fi network, use the following commands to tunnel the server to your device:
pnpm run start --tunnel
Note: Tunneling may have limitations with Supabase connections. Using an emulator or development build is recommended for full functionality.
Debugging Drizzle with Drizzle Studio
While the development server is running, press
Shift + M
in the terminal and selectexpo-drizzle-studio-plugin
to open Drizzle Studio in your browser. You can use this tool to inspect the SQLite database and troubleshoot any issues related to the local cache with SQLite and Drizzle ORM. Read more about Drizzle Studio here. -
Launch Emulators
To open the app on an emulator, press either of the following keys in the terminal:
i
to open on iOS simulatora
to open on Android emulator
ut-dining/
├── app/ # Expo Router screens and local UI components
├── assets/ # Images and static assets
├── components/ # Global reusable UI components
├── data/ # Static data and constants
├── db/ # SQLite Database schema and utilities
├── drizzle/ # Drizzle ORM migrations and metadata
├── hooks/ # Custom React hooks
├── store/ # Zustand state management
├── supabase/ # Supabase local client and utilities
├── types/ # TypeScript type definitions
└── utils/ # Helper functions and utilities
Q: Is this app officially affiliated with UT Austin?
A: No, this is a student-created project that aims to improve the dining experience at UT Austin. While we use publicly available data from UT's University Housing and Dining, we are not officially affiliated with the university (yet 👀).
Q: Where does the menu data come from?
A: The menu data is scraped daily from UT Austin's official dining page using our UT Dining Scraper.
Q: How often is the menu data updated?
A: The menu data is updated every day at 1:00 AM CST (7:00 AM UTC) to ensure you have the most current information.
Q: Do I need to run the scraper to test the app locally?
A: No, you can develop and test the app without running the scraper, but we highly recommend you do to be able to fully test all of the app's features. If you want to work with real menu data, you'll need to set up the UT Dining Scraper with your local Supabase instance.
Q: What is local Supabase development and why do I need it?
A: Local Supabase development means running Supabase on your own computer instead of using a hosted service. This gives you:
- A completely isolated development environment
- Freedom to experiment without affecting production data
- No need for external credentials or API keys
- Faster development since you're working with a local database
The setup requires Docker Desktop and Supabase CLI, but once configured, it provides a full Supabase environment including database, authentication, and real-time features. Check the Supabase Local Development docs for more details.
Q: Why can't I use Expo Go?
A: The app uses react-native-mmkv for storage, which requires native code. Expo Go doesn't support native modules, so you need to use a development build instead.
Q: I'm getting SQLite errors, what should I do?
A: Make sure you're using a development build and not Expo Go. If the error persists, try:
- Delete the app from your device/emulator
- Rebuild using
pnpm run ios
orpnpm run android
- If issues continue, check Drizzle Studio (press
Shift + M
in terminal) to inspect the database
Q: How do I test admin features?
A: Admin features can be tested by:
- Setting up the UT Dining Dashboard locally
- Using the same Supabase credentials from your local instance
- Accessing the dashboard through your web browser
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes using conventional commit messages:
feat: add new feature fix: resolve issue with X docs: update documentation style: format code (no functional changes) refactor: restructure code without changing behavior test: add or update tests chore: update dependencies or configuration
- Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Here are the repositories related to the UT Dining project:
-
UT Dining Scraper
This repository contains the code for scraping dining menus from UT Austin and storing them in the Supabase database. -
UT Dining Dashboard
This repository contains the code for the UT Dining admin dashboard, which is used to manage the menus, locations, and other admin features through a web interface. -
UT Dining Website
This repository hosts the code for the UT Dining website.
This project is licensed under the MIT License.
You are free to use, modify, and distribute this software under the terms of the MIT License. See the LICENSE file for more details.