A self-hosted job application lifecycle tracker built with React, Vite, TypeScript, and Supabase.
ApplAId helps you track every application from the first click to the final decision. It keeps applications, timeline events, recruiter notes, rejection details, resume variants, compensation expectations, and offer information in one place.
The app is multi-user and uses Supabase Auth plus row-level security, so every user only sees their own data. Your data lives in your own Supabase project.
ApplAId is designed for people who want a structured overview of their job search instead of scattered notes, spreadsheets, and email threads.
You can track:
- Applications from applied to final decision
- Screening calls, interviews, offers, and rejections
- Timeline events per application
- Rejection reasons and rejection categories
- Resume variants used for each application
- Application sources such as LinkedIn, direct, referral, or recruiter
- Salary and compensation expectations
- Offer details
- Dashboard statistics
- Active, rejected, and completed applications
- React 18
- Vite 7
- TypeScript
- React Router v6
- react-i18next
- Supabase Auth
- Supabase Postgres
- Supabase Row Level Security
- date-fns
- Netlify, Vercel, or any static hosting provider
packages/
core/ — shared types, hooks, Supabase client, i18n, config
web/ — React + Vite web application
src/
supabase-schema.sql
.env.example
mobile/ — Expo React Native mobile app
src/
.env.example
README.md
package.jsonBefore running the project, make sure you have:
- Node.js 20+ installed (required for Expo SDK 54)
- npm installed
- A Supabase project
- The Supabase project URL
- The Supabase publishable key
git clone https://github.com/blattmann/applaid.git
cd applaid
npm installNote: npm install from the root installs the web and core packages only. The mobile app requires a separate installation (see "Run the mobile app" below):
cd packages/mobile && npm install --legacy-peer-depsCreate a new Supabase project at supabase.com.
Then open the Supabase SQL Editor and run the contents of:
packages/web/supabase-schema.sqlThis creates the required tables, relationships, and row-level security policies.
Copy the example environment file for the web app:
cp packages/web/.env.example packages/web/.env.localThen edit packages/web/.env.local:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=your-publishable-key-hereYou can find both values in Supabase under:
Project Settings → APIStart the local development server:
npm run webVite will print the local URL in the terminal, usually:
http://localhost:5173Open that URL in your browser.
Create a production build:
npm run buildPreview the production build locally:
cd packages/web && npm run previewIn Supabase, go to:
Authentication → URL ConfigurationSet the site URL to your deployed app URL, for example:
https://your-app.netlify.appAdd redirect URLs for local development and production:
http://localhost:5173/**
https://your-app.netlify.app/**For personal use, you can optionally disable email confirmation:
Authentication → Email → Confirm email → OffIf you want to keep the app private, create your own account first and then disable public signups:
Authentication → Providers → Email → Enable Sign Ups → OffRecommended settings:
Build command: npm run build
Publish directory: distAdd these environment variables in Netlify:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=your-publishable-key-hereVercel has known issues injecting VITE_* environment variables into the build for Vite projects, particularly on team accounts.
The reliable workaround is to commit a .env.production file to the repo:
- Copy packages/web/.env.example to packages/web/.env.production
- Fill in your real values
- Remove .env.production from .gitignore in packages/web (it needs to be committed so Vite picks it up at build time)
- Deploy to Vercel — Vite reads .env.production automatically during vite build
Note: Your publishable key is a public key by design — it is safe to commit. Supabase Row Level Security handles data access control.
Also note: On Vercel Hobby plan, private GitHub repos can only be deployed from a personal account, not a team account. If you hit a "Hobby Plan does not support collaboration" error, either use Netlify instead or deploy from your personal Vercel account.
The mobile app is in packages/mobile and uses Expo with React Navigation.
- Install dependencies:
cd packages/mobile
npm install --legacy-peer-deps- Copy the environment file:
cp .env.example .env- Fill in packages/mobile/.env:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_PUBLISHABLE_KEY=your-publishable-key-here- Start the Expo development server:
npx expo start- Scan the QR code with Expo Go on your device (iOS or Android). Expo Go must be SDK 54 or later.
- The mobile app shares business logic with the web app via packages/core
- Authentication uses the same Supabase project as the web app
- No Apple Developer account or Google Play account required for local development via Expo Go
Resume variant suggestions are stored in:
packages/core/src/config.jsonExample:
{
"resumeVariants": [
"Senior Frontend Engineer",
"Staff Frontend Engineer",
"Engineering Manager"
]
}These values are suggestions only. You can still enter a custom resume variant in the application form.
All user-facing strings are stored in:
packages/core/src/i18n/locales/en.jsonTo add another language:
- Copy
packages/core/src/i18n/locales/en.json - Rename the copy, for example
de.json - Translate the values
- Keep the keys unchanged
- Register the locale in
packages/core/src/i18n/index.ts
ApplAId is designed to run against your own Supabase project.
That means:
- You own the database
- You control authentication
- You control deployment
- You control access
- No third-party job tracking service owns your data
MIT