npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mariosplen/expo-template-auth

v1.0.1

Published

A template for a React Native Expo app with Supabase authentication and React Query.

Readme

@mariosplen/expo-template-auth

An Expo + expo-router template with Supabase email/password authentication called over plain fetch (no supabase-js dependency), session persistence in expo-secure-store, refresh-on-401 token renewal, and React Query wired up for protected data fetching.

Usage

Scaffold a new project from this template:

npx create-expo-app@latest my-app --template @mariosplen/expo-template-auth

Then set up your environment variables:

cd my-app
cp .env.local.example .env.local

Fill in .env.local with your Supabase project's URL and publishable key:

EXPO_PUBLIC_SUPABASE_URL=<your-supabase-url>
EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY=<your-supabase-publishable-key>

Apply the database schema in supabase/schema.sql to your Supabase project (via the SQL editor or the Supabase CLI), then start the app:

npm install
npm start

What's included

  • src/app — expo-router routes, split into an (app) group and an (auth) group that the root layout guards with Stack.Protected, plus a +not-found screen. The root layout holds the native splash screen until the persisted session has resolved, so logged-in users never see a login-screen flash on cold start.
  • src/lib/auth/ — everything that knows about tokens
    • store.ts — the zustand store holding the session, plus setSession()/loadSession(), which write the store and its persisted copy (SecureStore on native, localStorage on web) together so the two never drift
    • actions.ts — every operation that changes the session (signIn, signUp, signOut, refreshSession), each hitting a GoTrue endpoint and writing the result through setSession(). Clears the React Query cache on sign-out so one account's cached data can never leak to the next.
    • request.tsauthorizedRequest(), the only place a data request carries a token. On a 401 it refreshes once and replays the request, so token renewal is driven by the server rejecting a token — no timers, no auth listeners.
  • src/lib/api.ts — session-agnostic transport shared by every feature: supabaseFetch() (base URL + apikey/Authorization headers) and parseJson(), which throws the raw response body as a plain Error rather than a custom error type
  • src/lib/query.ts — the QueryClient the app's provider and sign-out cache clear share
  • src/lib/i18n/ — react-i18next with English only; locales/en.json holds the strings. Screens translate with the useTranslation() hook, and t() keys are type-checked against en.json.
  • src/lib/theme.ts — minimal color tokens so screens don't hardcode hex values
  • src/lib/env.ts — required environment variable validation
  • supabase/schema.sql — database schema used by the template

Session storage notes

  • Native sessions live in the device keychain via expo-secure-store. SecureStore warns above ~2048 bytes per value and can fail on some Android versions — if your JWTs grow large (many custom claims), switch to the LargeSecureStore pattern from the Supabase docs (AES key in SecureStore, encrypted session in AsyncStorage).
  • Web sessions persist in localStorage, so they survive tab closes and are shared across tabs like a normal web app. Tokens in localStorage are readable by any script that gets XSS'd into the page — the standard tradeoff for persisting a session in a browser, but worth knowing.
  • Sign-up with email confirmation enabled (the Supabase default) returns no session and no error — extend the login screen to show a "check your inbox" message if you keep confirmations on.

License

MIT