A lightweight issue tracker for engineering teams โ built with Next.js and Supabase.
Track engineering work, collaborate with your team, and keep issues moving toward completion.
IssueFlow is a modern issue tracker for engineering teams. It lets you create, organize, search, sort, and filter issues โ and share a filtered view of your board with anyone via the URL.
The project is a hands-on, end-to-end build covering a production-style Next.js App Router application backed by Supabase (Postgres), including database design, migrations, seed data, server-side data fetching, and a polished UI.
- ๐๏ธ Issue list with rich cards showing status, priority, labels, and assignee
- ๐ Search across issue titles and descriptions
โ๏ธ Sorting by created date, priority, or title (ascending/descending)- ๐๏ธ Filtering by status, priority, and assignee โ all combinable
- ๐ Shareable filters โ active filters are reflected in the URL so you can copy and share a filtered view
- ๐ Pagination with configurable page size
- ๐ Dashboard with issue statistics (To do / In progress / Done)
- โก Loading, empty, and error states throughout
Follow along with the full build on YouTube:
๐ Build IssueFlow โ watch the video
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| UI Library | React 19 |
| Language | TypeScript |
| Styling | Tailwind CSS 4 |
| Database / Backend | Supabase (Postgres) |
| Supabase Client | @supabase/supabase-js + @supabase/ssr |
| Testing | Vitest |
| Linting | ESLint |
- Node.js 20+ (the project is developed on Node 22)
- npm (or your preferred package manager)
- A Supabase project โ cloud or local (see Supabase setup)
git clone https://github.com/tapascript/issueflow.git
cd issueflownpm install
Create a .env.local file in the project root and add your Supabase credentials:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_supabase_publishable_key
You can find these in your Supabase dashboard under Project Settings โ API (see Supabase setup below).
npm run dev
Open http://localhost:3000 to see the app.
IssueFlow uses Supabase (Postgres) for storage. All schema definitions live in the supabase/ directory as SQL migrations.
- Create a project at supabase.com.
- From your project dashboard, open Project Settings โ API and copy:
- The Project URL โ
NEXT_PUBLIC_SUPABASE_URL - The publishable key (or
anonkey) โNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
- The Project URL โ
- Run the migrations and seed data against your project:
npm install -g supabase supabase link --project-ref <your-project-ref> supabase db push
supabase db push applies the migrations in supabase/migrations/ (including the seed data) to your remote database.
If you prefer to develop against a local database:
supabase start supabase db reset
supabase startboots a local Postgres + API (default API URL:http://127.0.0.1:54321).supabase db resetapplies migrations and seeds fresh local data.
Then point your .env.local at the local instance:
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321 NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=<local-anon-key-from-supabase-status>
The database consists of four tables:
| Column | Type | Notes |
|---|---|---|
id |
uuid |
Primary key |
name |
text |
Not null |
avatar_url |
text |
Nullable |
created_at |
timestamptz |
Defaults to now() |
| Column | Type | Notes |
|---|---|---|
id |
bigint |
Identity primary key |
title |
text |
Not null |
description |
text |
Nullable |
status |
text |
One of todo, in_progress, done |
priority |
text |
One of low, medium, high, critical |
assignee_id |
uuid |
FK โ profiles.id (ON DELETE SET NULL) |
created_at |
timestamptz |
Defaults to now() |
updated_at |
timestamptz |
Auto-updated by trigger |
| Column | Type | Notes |
|---|---|---|
id |
bigint |
Identity primary key |
name |
text |
Not null, unique |
color |
text |
Hex color for the label |
created_at |
timestamptz |
Defaults to now() |
| Column | Type | Notes |
|---|---|---|
issue_id |
bigint |
FK โ issues.id (ON DELETE CASCADE) |
label_id |
bigint |
FK โ labels.id (ON DELETE CASCADE) |
Primary key is the composite
(issue_id, label_id).
The schema also includes:
- Indexes on
status,priority,assignee_id, andcreated_atfor fast filtering/sorting. - A
set_updated_at()trigger that keepsissues.updated_atin sync. - Row Level Security (RLS) policies for
profiles,issues,labels, andissue_labels.
| File | Purpose |
|---|---|
20261008051341_create_issueflow_schema.sql |
Creates tables, indexes, trigger, and RLS policies |
20261008051643_seed_issueflow_data.sql |
Seeds team members and labels |
20261008054452_seed_issueflow_issues.sql |
Seeds sample issues |
20261008054638_seed_issueflow_issue_labels.sql |
Seeds issue โ label relationships |
| Command | Description |
|---|---|
npm run dev |
Start the development server |
npm run build |
Create a production build |
npm run start |
Serve the production build |
npm run lint |
Run ESLint |
npm run test |
Run the Vitest test suite |
If you find IssueFlow helpful, please consider supporting the work:
- โญ Star this repository โ it really helps!
- ๐ฅ Watch the build video โ youtu.be/Ms9VOyoWDpI
- ๐บ Follow the tapaScript channel for tech career growth, tutorials, and more โ youtube.com/tapasadhikary
MIT ยฉ tapaScript