diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..89b27754
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,33 @@
+name: CI
+
+on:
+ push:
+ branches: ['main']
+ pull_request:
+ branches: ['main']
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v3
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci --ignore-scripts
+
+ - name: Check TypeScript types
+ run: npm run check-types
+
+ - name: Check ESLint
+ run: npm run lint
+
+ - name: Check Prettier formatting
+ run: npm run check-formatting
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..505542ff
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+src/components/ui
\ No newline at end of file
diff --git a/package.json b/package.json
index e98e6fc6..f8ae9351 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
+ "check-types": "tsc --noEmit",
+ "check-formatting": "prettier -c src",
"postinstall": "prisma migrate deploy && prisma generate",
"build-image": "./scripts/build-image.sh",
"start-container": "docker compose --env-file container.env up"
diff --git a/src/app/groups/[groupId]/expenses/page.tsx b/src/app/groups/[groupId]/expenses/page.tsx
index bd4f600b..3ef84e37 100644
--- a/src/app/groups/[groupId]/expenses/page.tsx
+++ b/src/app/groups/[groupId]/expenses/page.tsx
@@ -10,7 +10,7 @@ import {
} from '@/components/ui/card'
import { Skeleton } from '@/components/ui/skeleton'
import { getGroup, getGroupExpenses } from '@/lib/api'
-import { Download, DownloadCloud, Plus } from 'lucide-react'
+import { Download, Plus } from 'lucide-react'
import { Metadata } from 'next'
import Link from 'next/link'
import { notFound } from 'next/navigation'
@@ -40,7 +40,10 @@ export default async function GroupExpensesPage({