diff --git a/doc/hooks/meson.section.md b/doc/hooks/meson.section.md
index fd7779e6468f..7496def5806f 100644
--- a/doc/hooks/meson.section.md
+++ b/doc/hooks/meson.section.md
@@ -1,16 +1,28 @@
 # Meson {#meson}
 
-Overrides the configure phase to run meson to generate Ninja files. To run these files, you should accompany Meson with ninja. By default, `enableParallelBuilding` is enabled as Meson supports parallel building almost everywhere.
+Overrides the configure, check, and install phases to run `meson setup`, `meson test`, and `meson install`.
+
+Meson is a meta-build system so you will need a secondary build system to run the generated build files in build phase. In Nixpkgs context, you will want to accompany Meson with ninja, which provides a [setup hook](#ninja) registering a ninja-based build phase.
+
+By default, `enableParallelBuilding` is enabled as Meson supports parallel building almost everywhere.
 
 ## Variables controlling Meson {#variables-controlling-meson}
 
 ### `mesonFlags` {#mesonflags}
 
-Controls the flags passed to meson.
+Controls the flags passed to `meson setup`.
+
+##### `mesonCheckFlags` {#mesoncheckflags}
+
+Controls the flags passed to `meson test`.
+
+##### `mesonInstallFlags` {#mesoninstallflags}
+
+Controls the flags passed to `meson install`.
 
 ### `mesonBuildType` {#mesonbuildtype}
 
-Which [`--buildtype`](https://mesonbuild.com/Builtin-options.html#core-options) to pass to Meson. We default to `plain`.
+Which [`--buildtype`](https://mesonbuild.com/Builtin-options.html#core-options) to pass to `meson setup`. We default to `plain`.
 
 ### `mesonAutoFeatures` {#mesonautofeatures}
 
@@ -23,3 +35,11 @@ What value to set [`-Dwrap_mode=`](https://mesonbuild.com/Builtin-options.html#c
 ### `dontUseMesonConfigure` {#dontusemesonconfigure}
 
 Disables using Meson’s `configurePhase`.
+
+##### `dontUseMesonCheck` {#dontusemesoncheck}
+
+Disables using Meson’s `checkPhase`.
+
+##### `dontUseMesonInstall` {#dontusemesoninstall}
+
+Disables using Meson’s `installPhase`.
diff --git a/doc/hooks/ninja.section.md b/doc/hooks/ninja.section.md
index 4b0e33feb5c3..bbc948108804 100644
--- a/doc/hooks/ninja.section.md
+++ b/doc/hooks/ninja.section.md
@@ -1,3 +1,5 @@
 # ninja {#ninja}
 
 Overrides the build, install, and check phase to run ninja instead of make. You can disable this behavior with the `dontUseNinjaBuild`, `dontUseNinjaInstall`, and `dontUseNinjaCheck`, respectively. Parallel building is enabled by default in Ninja.
+
+Note that if the [Meson setup hook](#meson) is also active, Ninja's install and check phases will be disabled in favor of Meson's.
diff --git a/pkgs/development/tools/build-managers/meson/setup-hook.sh b/pkgs/development/tools/build-managers/meson/setup-hook.sh
index 6305a405af21..21faac529c6d 100644
--- a/pkgs/development/tools/build-managers/meson/setup-hook.sh
+++ b/pkgs/development/tools/build-managers/meson/setup-hook.sh
@@ -28,14 +28,39 @@ mesonConfigurePhase() {
         echo "meson: enabled parallel building"
     fi
 
-    if ! [[ -v enableParallelInstalling ]]; then
-        enableParallelInstalling=1
-        echo "meson: enabled parallel installing"
+    if [[ ${checkPhase-ninjaCheckPhase} = ninjaCheckPhase && -z $dontUseMesonCheck ]]; then
+        checkPhase=mesonCheckPhase
+    fi
+    if [[ ${installPhase-ninjaInstallPhase} = ninjaInstallPhase && -z $dontUseMesonInstall ]]; then
+        installPhase=mesonInstallPhase
     fi
 
     runHook postConfigure
 }
 
+mesonCheckPhase() {
+    runHook preCheck
+
+    local flagsArray=($mesonCheckFlags "${mesonCheckFlagsArray[@]}")
+
+    echoCmd 'check flags' "${flagsArray[@]}"
+    meson test --no-rebuild "${flagsArray[@]}"
+
+    runHook postCheck
+}
+
+mesonInstallPhase() {
+    runHook preInstall
+
+    # shellcheck disable=SC2086
+    local flagsArray=($mesonInstallFlags "${mesonInstallFlagsArray[@]}")
+
+    echoCmd 'install flags' "${flagsArray[@]}"
+    meson install --no-rebuild "${flagsArray[@]}"
+
+    runHook postInstall
+}
+
 if [ -z "${dontUseMesonConfigure-}" -a -z "${configurePhase-}" ]; then
     setOutputFlags=
     configurePhase=mesonConfigurePhase