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 installCreate 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_keyYou can find these in your Supabase dashboard under Project Settings β API (see Supabase setup below).
npm run devOpen 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 pushsupabase 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 resetsupabase 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