diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 8f3b778a..44d26788 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,19 +10,11 @@ on:
 
 jobs:
   check:
-    name: Check
+    name: Check (msrv)
     runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        rust: [stable, msrv]
     steps:
       - name: Checkout sources
         uses: actions/checkout@v3
-
-      - name: Use MSRV rust toolchain
-        if: matrix.rust == 'msrv'
-        run: cp .github/workflows/msrv-rust-toolchain.toml rust-toolchain.toml
-
       - name: Install stable toolchain
         uses: helix-editor/rust-toolchain@v1
         with:
@@ -45,7 +37,7 @@ jobs:
         uses: actions/checkout@v3
 
       - name: Install stable toolchain
-        uses: dtolnay/rust-toolchain@1.61
+        uses: dtolnay/rust-toolchain@1.63
 
       - uses: Swatinem/rust-cache@v2
 
@@ -74,7 +66,7 @@ jobs:
         uses: actions/checkout@v3
 
       - name: Install stable toolchain
-        uses: dtolnay/rust-toolchain@1.61
+        uses: dtolnay/rust-toolchain@1.63
         with:
           components: rustfmt, clippy
 
@@ -99,7 +91,7 @@ jobs:
         uses: actions/checkout@v3
 
       - name: Install stable toolchain
-        uses: dtolnay/rust-toolchain@1.61
+        uses: dtolnay/rust-toolchain@1.63
 
       - uses: Swatinem/rust-cache@v2
 
diff --git a/.github/workflows/msrv-rust-toolchain.toml b/.github/workflows/msrv-rust-toolchain.toml
deleted file mode 100644
index b169d31e..00000000
--- a/.github/workflows/msrv-rust-toolchain.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[toolchain]
-channel = "1.61.0"
-components = ["rustfmt", "rust-src"]
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 157d19f7..e6cbed2c 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -73,13 +73,15 @@ use grep_searcher::{sinks, BinaryDetection, SearcherBuilder};
 use ignore::{DirEntry, WalkBuilder, WalkState};
 use tokio_stream::wrappers::UnboundedReceiverStream;
 
+pub type OnKeyCallback = Box<dyn FnOnce(&mut Context, KeyEvent)>;
+
 pub struct Context<'a> {
     pub register: Option<char>,
     pub count: Option<NonZeroUsize>,
     pub editor: &'a mut Editor,
 
     pub callback: Option<crate::compositor::Callback>,
-    pub on_next_key_callback: Option<Box<dyn FnOnce(&mut Context, KeyEvent)>>,
+    pub on_next_key_callback: Option<OnKeyCallback>,
     pub jobs: &'a mut Jobs,
 }
 
diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs
index 2e4a2e20..bcb3e449 100644
--- a/helix-term/src/compositor.rs
+++ b/helix-term/src/compositor.rs
@@ -7,6 +7,7 @@ use helix_view::graphics::{CursorKind, Rect};
 use tui::buffer::Buffer as Surface;
 
 pub type Callback = Box<dyn FnOnce(&mut Compositor, &mut Context)>;
+pub type SyncCallback = Box<dyn FnOnce(&mut Compositor, &mut Context) + Sync>;
 
 // Cursive-inspired
 pub enum EventResult {
diff --git a/helix-term/src/job.rs b/helix-term/src/job.rs
index 2888b6eb..19f2521a 100644
--- a/helix-term/src/job.rs
+++ b/helix-term/src/job.rs
@@ -5,9 +5,12 @@ use crate::compositor::Compositor;
 use futures_util::future::{BoxFuture, Future, FutureExt};
 use futures_util::stream::{FuturesUnordered, StreamExt};
 
+pub type EditorCompositorCallback = Box<dyn FnOnce(&mut Editor, &mut Compositor) + Send>;
+pub type EditorCallback = Box<dyn FnOnce(&mut Editor) + Send>;
+
 pub enum Callback {
-    EditorCompositor(Box<dyn FnOnce(&mut Editor, &mut Compositor) + Send>),
-    Editor(Box<dyn FnOnce(&mut Editor) + Send>),
+    EditorCompositor(EditorCompositorCallback),
+    Editor(EditorCallback),
 }
 
 pub type JobFuture = BoxFuture<'static, anyhow::Result<Option<Callback>>>;
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index f297b44e..493f8d50 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -1,5 +1,5 @@
 use crate::{
-    commands,
+    commands::{self, OnKeyCallback},
     compositor::{Component, Context, Event, EventResult},
     job::{self, Callback},
     key,
@@ -37,7 +37,7 @@ use super::{document::LineDecoration, lsp::SignatureHelp};
 
 pub struct EditorView {
     pub keymaps: Keymaps,
-    on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
+    on_next_key: Option<OnKeyCallback>,
     pseudo_pending: Vec<KeyEvent>,
     last_insert: (commands::MappableCommand, Vec<InsertEvent>),
     pub(crate) completion: Option<Completion>,
diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs
index 3ae00703..8aa10c08 100644
--- a/helix-term/src/ui/menu.rs
+++ b/helix-term/src/ui/menu.rs
@@ -43,6 +43,8 @@ impl Item for PathBuf {
     }
 }
 
+pub type MenuCallback<T> = Box<dyn Fn(&mut Editor, Option<&T>, MenuEvent)>;
+
 pub struct Menu<T: Item> {
     options: Vec<T>,
     editor_data: T::Data,
@@ -55,7 +57,7 @@ pub struct Menu<T: Item> {
 
     widths: Vec<Constraint>,
 
-    callback_fn: Box<dyn Fn(&mut Editor, Option<&T>, MenuEvent)>,
+    callback_fn: MenuCallback<T>,
 
     scroll: usize,
     size: (u16, u16),
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index 5190fc53..803e2d65 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -70,6 +70,8 @@ impl From<DocumentId> for PathOrId {
     }
 }
 
+type FileCallback<T> = Box<dyn Fn(&Editor, &T) -> Option<FileLocation>>;
+
 /// File path and range of lines (used to align and highlight lines)
 pub type FileLocation = (PathOrId, Option<(usize, usize)>);
 
@@ -80,7 +82,7 @@ pub struct FilePicker<T: Item> {
     preview_cache: HashMap<PathBuf, CachedPreview>,
     read_buffer: Vec<u8>,
     /// Given an item in the picker, return the file path and line number to display.
-    file_fn: Box<dyn Fn(&Editor, &T) -> Option<FileLocation>>,
+    file_fn: FileCallback<T>,
 }
 
 pub enum CachedPreview {
@@ -394,6 +396,8 @@ impl Ord for PickerMatch {
     }
 }
 
+type PickerCallback<T> = Box<dyn Fn(&mut Context, &T, Action)>;
+
 pub struct Picker<T: Item> {
     options: Vec<T>,
     editor_data: T::Data,
@@ -415,7 +419,7 @@ pub struct Picker<T: Item> {
     /// Constraints for tabular formatting
     widths: Vec<Constraint>,
 
-    callback_fn: Box<dyn Fn(&mut Context, &T, Action)>,
+    callback_fn: PickerCallback<T>,
 }
 
 impl<T: Item> Picker<T> {
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs
index 5fb6745a..f438231f 100644
--- a/helix-term/src/ui/prompt.rs
+++ b/helix-term/src/ui/prompt.rs
@@ -14,8 +14,11 @@ use helix_view::{
     Editor,
 };
 
-pub type Completion = (RangeFrom<usize>, Cow<'static, str>);
 type PromptCharHandler = Box<dyn Fn(&mut Prompt, char, &Context)>;
+pub type Completion = (RangeFrom<usize>, Cow<'static, str>);
+type CompletionFn = Box<dyn FnMut(&Editor, &str) -> Vec<Completion>>;
+type CallbackFn = Box<dyn FnMut(&mut Context, &str, PromptEvent)>;
+pub type DocFn = Box<dyn Fn(&str) -> Option<Cow<str>>>;
 
 pub struct Prompt {
     prompt: Cow<'static, str>,
@@ -25,9 +28,9 @@ pub struct Prompt {
     selection: Option<usize>,
     history_register: Option<char>,
     history_pos: Option<usize>,
-    completion_fn: Box<dyn FnMut(&Editor, &str) -> Vec<Completion>>,
-    callback_fn: Box<dyn FnMut(&mut Context, &str, PromptEvent)>,
-    pub doc_fn: Box<dyn Fn(&str) -> Option<Cow<str>>>,
+    completion_fn: CompletionFn,
+    callback_fn: CallbackFn,
+    pub doc_fn: DocFn,
     next_char_handler: Option<PromptCharHandler>,
 }
 
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index b169d31e..ace4f5f9 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "1.61.0"
+channel = "1.63.0"
 components = ["rustfmt", "rust-src"]