diff --git a/lib/drawer/drawer.dart b/lib/drawer/drawer.dart
index b2a4bc1867bd45d18d82aa8b1e229f2a3e3f7d27..8d6ce2b7bfb3dcf154059690ae4a0d4706c04753 100644
--- a/lib/drawer/drawer.dart
+++ b/lib/drawer/drawer.dart
@@ -1,4 +1,5 @@
 import 'package:flutter/material.dart';
+import 'package:text_search/text_search.dart';
 
 import '../context.dart';
 import '../dialogs/error_dialog.dart';
@@ -15,12 +16,22 @@ class ClassDrawer extends StatefulWidget {
 }
 
 class _ClassDrawerState extends State<ClassDrawer> {
+  String activeQuery = '';
+  late final searchTextController = TextEditingController(text: activeQuery);
+
   List<Class> get availableClasses => widget.appContext.classes ?? [];
 
   @override
   void initState() {
     super.initState();
     fetchLectures().onError((error, _) => _showErrorDialog(error));
+    searchTextController.addListener(_onSearchChanged);
+  }
+
+  @override
+  void dispose() {
+    searchTextController.removeListener(_onSearchChanged);
+    super.dispose();
   }
 
   void _showErrorDialog(Object? error) {
@@ -33,6 +44,58 @@ class _ClassDrawerState extends State<ClassDrawer> {
     );
   }
 
+  void _onSearchChanged() {
+    if (searchTextController.text != activeQuery) {
+      setState(() {
+        activeQuery = searchTextController.text;
+      });
+    }
+  }
+
+  bool _isSelected(int classId) {
+    return widget.appContext.profile.value!.selectedClasses.contains(classId);
+  }
+
+  List<Class> getFilteredClasses() {
+    if (activeQuery.trim().isEmpty) {
+      return availableClasses;
+    }
+
+    final searchables = availableClasses
+        .map((e) =>
+            TextSearchItem(e, [TextSearchItemTerm(e.codeWithoutFaculty)]))
+        .toList();
+
+    final search = TextSearch<Class>(searchables);
+    final results = search.search(activeQuery);
+
+    results.sort((a, b) {
+      if (a.score == b.score) {
+        return a.object.codeWithoutFaculty
+            .compareTo(b.object.codeWithoutFaculty);
+      }
+
+      return a.score.compareTo(b.score);
+    });
+
+    return results.map((e) => e.object).toList();
+  }
+
+  List<Class> getFilteredClassesSorted() {
+    final results = getFilteredClasses();
+
+    final modifiedResults =
+        results.where((cls) => _isSelected(cls.id)).toList();
+
+    for (final cls in results) {
+      if (!_isSelected(cls.id)) {
+        modifiedResults.add(cls);
+      }
+    }
+
+    return modifiedResults;
+  }
+
   Future<void> fetchLectures() async {
     final allLectures = await widget.appContext.untis.allLectures.fetched;
     widget.appContext.lectures = allLectures;
@@ -41,13 +104,30 @@ class _ClassDrawerState extends State<ClassDrawer> {
 
   @override
   Widget build(BuildContext context) {
+    final filteredClasses = getFilteredClasses();
+
     return Drawer(
-      child: ListView.builder(
-        itemBuilder: (context, index) {
-          final cls = availableClasses.elementAt(index);
-          return ClassListItem(cls: cls, appContext: widget.appContext);
-        },
-        itemCount: availableClasses.length,
+      child: Column(
+        children: [
+          Padding(
+            padding: const EdgeInsets.all(8.0),
+            child: TextField(
+              controller: searchTextController,
+              decoration: const InputDecoration(
+                hintText: 'Suche...',
+              ),
+            ),
+          ),
+          Expanded(
+            child: ListView.builder(
+              itemBuilder: (context, index) {
+                final cls = filteredClasses.elementAt(index);
+                return ClassListItem(cls: cls, appContext: widget.appContext);
+              },
+              itemCount: filteredClasses.length,
+            ),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/untis/class.dart b/lib/untis/class.dart
index 17fc89fa742cc621d7cc2da62027e350f6e55efb..fcb380bbe1d598df869a044e1f75168f3cea2b88 100644
--- a/lib/untis/class.dart
+++ b/lib/untis/class.dart
@@ -5,6 +5,7 @@ class Class extends UntisElement {
   String get name => json['longName'];
 
   String get code => json['name'];
+  String get codeWithoutFaculty => code.substring(1);
 
   Class(super.json);
 }
diff --git a/pubspec.lock b/pubspec.lock
index d0aa88d36257b6b15e3b594503b4ea53ef4e10e4..4f970732f47353cf4eda7c4a8b137b96aaf2bb94 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -240,6 +240,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.6.0"
+  text_search:
+    dependency: "direct main"
+    description:
+      name: text_search
+      sha256: e2e826848ba452df6702dc8f1315de90e812eb2303ecec9cc1155f7715bec934
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   vector_math:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 4772eba700e70331151dc5f8ede51364def94339..ea707458756109f471a2eef840af3c09f6ed29e3 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -37,6 +37,7 @@ dependencies:
   cupertino_icons: ^1.0.2
   path_provider: ^2.1.1
   path: ^1.8.3
+  text_search: ^1.0.1
 
 dev_dependencies:
   flutter_test: