Following Jesus every day. A mobile devotional app for the Grow365 daily Bible study by Dr. Lou Fortier.
Grow365 is a daily Bible study that walks through Scripture over the course of a year. This repository holds the mobile app that delivers it to Android and iOS. Each day the reader gets one study built around seven parts: Encounter, Pray, Read, Process, Peek, Practice, and Ponder. The study content is written by Dr. Lou Fortier and published at grow365.net.
The app is built with Expo and React Native, and it uses Supabase for accounts, data, and image storage. It runs on its own once built, with no server of its own to maintain. The app talks to Supabase directly, and Supabase holds everything.
Today Screen |
Library |
Reader Screen |
Profile |
- A daily devotional following the seven Grow365 elements
- Email accounts, so a reader's data follows them across devices
- A reading streak that tracks the days you complete
- Bookmarks for saving days to return to
- A private journal for writing your own reflections against each day
- An archive of past days, browsable by date
- Light and dark reading modes
- In-app account deletion
Every day's study has the same shape. Encounter is a photograph to slow down and settle before God. Pray is a guided prayer. Read is a short passage, usually a few verses. Process gives background to help the passage make sense. Peek adds Dr. Fortier's own comments on the text. Practice suggests a way to live it out. Ponder is a verse to hold onto and memorize.
The app has no backend of its own. It reads and writes to Supabase directly through the Supabase client, and Supabase's row level security decides what each reader can see. Devotional content is readable by anyone signed in. A reader's bookmarks, notes, and progress stay private to them.
Study content does not get typed into the app by hand. Dr. Fortier writes each day in Adobe Express, then submits it through a Google Form. A Google Apps Script runs on each submission: it copies the text into the Supabase database and moves the day's image into Supabase Storage. The app picks it up on its next load.
flowchart TD
A[Dr. Fortier writes the day in Adobe Express] --> B[Google Form]
B --> C[Google Apps Script]
C -->|text| D[(Supabase database)]
C -->|image| E[Supabase Storage]
D --> F[Grow365 app]
E --> F
F <-->|accounts, bookmarks, journal| D
- Expo (SDK 54) and React Native, in TypeScript
- Expo Router for navigation
- Supabase for Postgres, authentication, and storage
- @supabase/supabase-js with AsyncStorage to keep sessions signed in
- Newsreader and Inter, loaded through @expo-google-fonts
- @expo/vector-icons for icons
- pnpm for packages
- EAS Build for producing the Android and iOS binaries
This is a pnpm workspace, and the app itself lives in artifacts/grow365, not at the repository root. Run all app commands from inside that folder. The root looks nearly empty, which catches people out.
.
├── artifacts/
│ └── grow365/ the mobile app (run commands here)
│ ├── app/ screens and routes (Expo Router)
│ ├── app.json Expo config, including the app IDs
│ └── package.json
└── pnpm-lock.yaml
- Node.js (LTS)
- pnpm (
npm install -g pnpm) - A Supabase project
- An Expo account, and the EAS CLI (
npm install -g eas-cli) if you plan to build
git clone <your-repo-url>
cd <repo>/artifacts/grow365
pnpm installThe app needs two values from your Supabase project. Put them in a .env file in artifacts/grow365, or set them as EAS environment variables for builds.
| Variable | Description |
|---|---|
EXPO_PUBLIC_SUPABASE_URL |
Your Supabase project URL |
EXPO_PUBLIC_SUPABASE_ANON_KEY |
Your Supabase publishable key, safe to ship in the app |
Use the publishable key here, not the secret key. The publishable key is meant to ship inside the app, and row level security is what keeps your data safe. The secret key belongs only in the content pipeline and never in the app. Keep .env out of version control.
pnpm expo startScan the QR code with Expo Go on your phone, or run it in a simulator.
The backend needs preparing once:
- Create the tables and row level security policies (the SQL lives in the setup guide).
- Create a public Storage bucket named
devotional-images. - Turn on email authentication.
- Copy your project URL and publishable key into the app's environment.
The database has five tables: devotionals for the daily content, profiles for each user, and bookmarks, notes, and reading_progress for each reader's private data.
To publish a day:
- Dr. Fortier writes the study in Adobe Express.
- He fills in the Google Form, one field per section, and uploads the Encounter image.
- The Apps Script inserts the text into
devotionalsand uploads the image to Storage. - The app shows the new day on its date.
The form upserts on the date, so resubmitting the same date updates that day instead of creating a duplicate.
Builds run in the cloud through EAS. From artifacts/grow365:
# installable APK for testing on a device
eas build --platform android --profile preview
# app bundle for the Play Store
eas build --platform android --profile production
# iOS build (needs a paid Apple Developer account)
eas build --platform ios --profile productionThe APK from the preview profile installs straight onto an Android phone. The AAB from the production profile is what you upload to Google Play. iOS builds compile without a paid account, but installing on a real device or shipping to the App Store needs the Apple Developer Program.
Back up your Android signing keystore and keep it somewhere safe. Every future update has to be signed with the same one, and losing it means you cannot update the same listing again.
A few things that are easy to get wrong on this project:
- Run every command from
artifacts/grow365, not the repo root. The workspace layout means the root has almost nothing in it, and commands run there behave as if the app is missing. - The two
EXPO_PUBLIC_variables get baked in at build time. If they are absent from the environment you build against, the app installs fine but closes the moment it opens, because it has no way to reach Supabase. Set them for each EAS environment you build (production,preview), and check witheas env:list. - Preload the font for every icon set the app imports, alongside the text fonts. If you only wait for the text fonts, Android draws the screen before the icon fonts are ready and the icons show as blank boxes. Web and iOS hide this, so it only appears on Android.
Grow365 and all of its study content are the work of Dr. Lou Fortier. Read more at grow365.net.
The application code in this repository is licensed under the MIT License. Anyone is free to use, change, and distribute it, including in commercial work, as long as they keep the copyright notice. See the LICENSE file for the full text.
The MIT License covers the code only. The Grow365 devotional content, including all daily studies and written text, belongs to Dr. Lou Fortier and is not part of this license. Do not reuse the content without his permission.



