This is an open source metabolic health app. Connect with your Dexcom CGM and visualize your glucose data in real-time.
Table of Contents
- Expo mobile app for optimizing metabolic health.
- Next.js web dashboard.
- Authentication: Sign up with Apple, Google, or email. Supabase Auth.
- Calendar: WHOOP-inspired calendar built with Flash Calendar.
- Day Slider: Quickly swipe through days of data.
- Dexcom Sandbox: Connect with Dexcom Sandbox Data.
- Glucose Graph: Visualize your Time in Range (TIR) with charts from Victory Native.
- Web Dashboard: Next.js app for visualizing metabolic health.
- React Native
- Expo
- NativeWind
- TypeScript
- tRPC
- Drizzle ORM
- Next.js
- Tailwind CSS
- Supabase
- Supabase Auth
- Jest
- Turborepo
.github
└─ workflows
└─ CI with pnpm cache setup
.vscode
├─ Recommended extensions and settings for VSCode users
└─ Multi-root Workspaces for smoother python experience in monorepo
apps
├─ expo
| ├─ Expo SDK 52
| ├─ React Native 0.76 New Architecture
| ├─ Navigation using Expo Router
| ├─ Tailwind using NativeWind
| ├─ Typesafe API calls using tRPC
| └─ Jest + React Native Testing Library for unit tests
└─ nextjs
├─ Next.js 14
├─ React 18
├─ Tailwind CSS
└─ E2E Typesafe API Server & Client
packages
├─ api
| └─ tRPC v11 router definition.
├─ db
| └─ Typesafe db calls using Drizzle & Supabase
├─ ui
| └─ shadcn/ui.
└─ validators
└─ Zod schemas for repo-wide type-safety and validation.
tooling
├─ eslint
| └─ shared, fine-grained, eslint presets
├─ prettier
| └─ shared prettier configuration
├─ tailwind
| └─ shared tailwind configuration
├─ github
| └─ shared github actions
└─ typescript
└─ shared tsconfig you can extend from
In this project, we use
@stable
as a placeholder for package names. As a user, you might want to replace it with your own organization or project name. You can use find-and-replace to change all the instances of@stable
to something like@my-company
or@project-name
.
# Install dependencies
pnpm i
# Configure environment variables
# There is an `.env.example` in the root directory you can use for reference
cp .env.example .env
cp .env.example .env.local
# Push the Drizzle schema to Supabase
pnpm db:generate
pnpm db:migrate
- Go to the Supabase dashboard and create a new project.
- Under project settings, retrieve the environment variables
reference id
,project url
&anon public key
and paste them into .env in the necessary places. You'll also need the database password you set when creating the project. - Under
Auth
, configure any auth provider(s) of your choice. This repo is using Github for Web and Apple for Mobile. - If you want to use the
Email
provider andemail confirmation
, go toAuth
->Email Templates
and change theConfirm signup
from{{ .ConfirmationURL }}
to{{ .RedirectTo }}&token_hash={{ .TokenHash }}&type=signup
, according to https://supabase.com/docs/guides/auth/redirect-urls#email-templates-when-using-redirectto..RedirectTo
will need to be added to yourRedirect URLs
in the next step. - Under
Auth
->URL Configuration
, set theSite URL
to your production URL and addhttp://localhost:3000/**
andhttps://*-username.vercel.app/**
toRedirect URLs
as detailed here https://supabase.com/docs/guides/auth/redirect-urls#vercel-preview-urls. - Set up a trigger when a new user signs up: https://supabase.com/docs/guides/auth/managing-user-data#using-triggers. You can run this in the SQL Editor.
-- inserts a row into public.profile
create function public.handle_new_user()
returns trigger
language plpgsql
security definer set search_path = public
as $$
begin
insert into public.epi_profile (id, email, name, image)
values (
new.id,
new.email,
COALESCE(
new.raw_user_meta_data ->> 'name',
new.raw_user_meta_data ->> 'full_name',
new.raw_user_meta_data ->> 'user_name',
'Guest User'
),
new.raw_user_meta_data ->> 'avatar_url'
)
on conflict (id) do update set
email = excluded.email,
name = excluded.name,
image = excluded.image;
return new;
end;
$$;
-- trigger the function every time a user is created
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
-- trigger the function when a user signs in/their email is confirmed to get missing values
create trigger on_auth_user_verified
after update on auth.users
for each row when (
old.last_sign_in_at is null
and new.last_sign_in_at is not null
) execute procedure public.handle_new_user();
-- drop a trigger if needed
drop trigger "on_auth_user_verified" on auth.users;
- Remove access to the
public
schema as we are only using the server
By default, Supabase exposes the public
schema to the PostgREST API to allow the supabase-js
client query the database directly from the client. However, since we route all our requests through the Next.js application (through tRPC), we don't want our client to have this access. To disable this, execute the following SQL query in the SQL Editor on your Supabase dashboard:
REVOKE USAGE ON SCHEMA public FROM anon, authenticated;
Note: This means you also don't need to enable row-level security (RLS) on your database if you don't want to.
-
Make sure you have XCode and XCommand Line Tools installed as shown on expo docs.
NOTE: If you just installed XCode, or if you have updated it, you need to open the simulator manually once. Run
npx expo start
in the root dir, and then enterI
to launch Expo Go. After the manual launch, you can runpnpm dev
in the root directory.+ "dev:ios": "expo start --ios",
-
Run
pnpm dev:ios
atapps/expo
to open the iOS simulator.
-
Install Android Studio tools as shown on expo docs.
-
Run
pnpm dev:android
script atapps/expo
to open the Android emulator.+ "dev:android": "expo start --android",
Share your thoughts in Discussions
We welcome contributions! Find out how you can contribute to the project in CONTRIBUTING.md
: Contributing Guidelines
Made with contrib.rocks
Distributed under the MIT License. See LICENSE
for more information.
This repo originates from create-t3-turbo. Feel free to check out the project if you are running into issues with running/deploying the starter.
Thanks as well to the following:
- Levels Health for fueling the inspiration for this project.