diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 9ee413d3befc27fe78c576ffbea7108b4f13bdd3..f2150fe9335335ec530742d6ab51b2aa01f2608b 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -58,3 +58,6 @@
   padding: 0 8px;
   border-right: 1px dashed gray;
 }
+.hidden {
+  display: none;
+}
diff --git a/app/javascript/controllers/filteredlist_controller.js b/app/javascript/controllers/filteredlist_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef334ef616e23b05daeb1f649e868cd7b871a88b
--- /dev/null
+++ b/app/javascript/controllers/filteredlist_controller.js
@@ -0,0 +1,21 @@
+import { Controller } from "@hotwired/stimulus";
+
+export default class extends Controller {
+  static targets = ["input", "list"];
+
+  connect() {
+    //this.options = Array.from(this.listTarget.children)
+  }
+
+  filter() {
+    const query = this.inputTarget.value.toLowerCase()
+    // Filter options by the `data-filteredlist-match` attribute
+    for (const option of this.listTarget.children) {
+      if (option.dataset.filteredlistMatch.includes(query)) {
+        option.classList.remove("hidden")
+      } else {
+        option.classList.add("hidden")
+      }
+    }
+  }
+}
diff --git a/app/views/assignments/_filteredlist.html.erb b/app/views/assignments/_filteredlist.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..bfbba5bd4af27f0383f179dddeee14b73cd383ae
--- /dev/null
+++ b/app/views/assignments/_filteredlist.html.erb
@@ -0,0 +1,17 @@
+<div class="relative inline-block w-64" data-controller="filteredlist">
+  <div class="relative">
+    <input
+      type="text"
+      data-filteredlist-target="input"
+      data-action="input->filteredlist#filter"
+      autocomplete="off"
+      class="w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-sm focus:ring-indigo-500 focus:border-indigo-500"
+      placeholder="Filter..."
+    />
+    <ul data-filteredlist-target="list" class="flex flex-row flex-wrap gap-1 my-1 flex-shrink-0">
+      <% users.each do |user| %>
+        <%= render partial: 'assignments/filteredlist_option', locals: { session: session, user: user } %>
+      <% end %>
+    </ul>
+  </div>
+</div>
diff --git a/app/views/assignments/_filteredlist_option.html.erb b/app/views/assignments/_filteredlist_option.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..6579860aa51f988258ba990b2164be8cc7c2d7f6
--- /dev/null
+++ b/app/views/assignments/_filteredlist_option.html.erb
@@ -0,0 +1,6 @@
+<li
+  data-filteredlist-match="<%= user.name.downcase %>"
+  data-turbo-track="dynamic"
+>
+  <%= render partial: 'assignments/user_add', locals: { user: user, session: session } %>
+</li>
diff --git a/app/views/assignments/_user_add.html.erb b/app/views/assignments/_user_add.html.erb
index 65c56c26f5803261fc9ad57a11a67e204cb0c501..819b115163d328c5927b7a8d415f73297f95c9cc 100644
--- a/app/views/assignments/_user_add.html.erb
+++ b/app/views/assignments/_user_add.html.erb
@@ -1,4 +1,5 @@
 <% disabled = local_assigns.fetch(:disabled, false) %>
+<span class="unassigned-user">
 <% if not disabled %>
 <span class="inline-flex items-center gap-x-0.5 rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10" style="background-color: <%= user.avatar_color %>" title="<%= user.name %>">
   <span style="color: <%= user.text_color %>"><%= user.name %></span>
@@ -23,4 +24,5 @@
       <span class="absolute -inset-1"></span>
   </button>
 </span>
-<% end %>
\ No newline at end of file
+<% end %>
+</span>
diff --git a/app/views/sessions/_session.html.erb b/app/views/sessions/_session.html.erb
index 46217df1934429beff20f117133484bf6d06c9e3..dd370bfb8555099549b62de8472fd2c992f8949e 100644
--- a/app/views/sessions/_session.html.erb
+++ b/app/views/sessions/_session.html.erb
@@ -1,5 +1,5 @@
 <% unassigned_users = User.all - session.assignments.collect(&:user) %>
-<%= turbo_frame_tag dom_id(session) do %>
+<%= turbo_frame_tag dom_id(session), method: "morph" do %>
   <div class="session shadow hover:shadow-lg overflow-scroll text-sm w-full !h-full min-h-full hover:!min-h-max <%= session.translators_needed? ? "translators-needed" : "no-translators-needed" %> <%= session.backup_needed? ? "backup-needed" : "no-backup-needed" %> <%= session.assignees? ? "has-assignees" : "no-assignees" %> <%= (session.ends_at < Time.now ? "past" : "") %>">
     <h4>
       <small class="text-2xs uppercase font-light bg-black/10 rounded-sm p-1 mr-1 lang-<%= session.language %>"><%= session.language %></small>
@@ -58,12 +58,6 @@
       </div>
     <% end %>
     <small>unassigned (<%= unassigned_users.length %>)</small>
-    <ul class="flex flex-row flex-wrap gap-1 my-1 flex-shrink-0">
-      <% unassigned_users.each do |user| %>
-        <li>
-          <span class="unassigned-user"><%= render partial: 'assignments/user_add', locals: { user: user, session: session } %></span>
-        </li>
-      <% end %>
-    </ul>
+    <%= render partial: 'assignments/filteredlist', locals: { session: session, users: unassigned_users } %>
   </div>
 <% end %>