diff --git a/Cargo.lock b/Cargo.lock
index 8acbe88..b30db4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1823,6 +1823,15 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 
+[[package]]
+name = "stdin"
+version = "0.1.0"
+dependencies = [
+ "abi_stable",
+ "anyrun-plugin",
+ "fuzzy-matcher",
+]
+
 [[package]]
 name = "strsim"
 version = "0.10.0"
diff --git a/Cargo.toml b/Cargo.toml
index c87583f..5599cef 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,4 +10,5 @@ members = [
   "plugins/kidex",
   "plugins/translate",
   "plugins/randr",
+  "plugins/stdin",
 ]
\ No newline at end of file
diff --git a/README.md b/README.md
index 1fb8fc8..7474e6e 100644
--- a/README.md
+++ b/README.md
@@ -126,19 +126,22 @@ cp examples/config.ron ~/.config/anyrun/config.ron # Copy the default config fil
 Anyrun requires plugins to function, as they provide the results for input. The list of plugins in this repository is as follows:
 
 - [Applications](plugins/applications)
-  - Search and run system & user specific desktop entries
+  - Search and run system & user specific desktop entries.
 - [Symbols](plugins/symbols)
-  - Search unicode symbols
+  - Search unicode symbols.
   - [User defined symbols](plugins/symbols/README.md#User-defined-symbols)
 - [Rink](plugins/rink)
-  - Calculator & unit conversion
+  - Calculator & unit conversion.
 - [Shell](plugins/shell)
-  - Run shell commands
+  - Run shell commands.
 - [Kidex](plugins/kidex)
-  - File search provided by [Kidex](https://github.com/Kirottu/kidex)
+  - File search provided by [Kidex](https://github.com/Kirottu/kidex).
 - [Randr](plugins/randr)
   - Rotate and resize; quickly change monitor configurations on the fly.
   - TODO: Only supports Hyprland, needs support for other compositors.
+- [Stdin](plugins/stdin)
+  - Turn Anyrun into a dmenu like fuzzy selector.
+  - Should generally be used exclusively with the `-o` argument.
 
 ## Configuration
 
diff --git a/anyrun-interface/src/lib.rs b/anyrun-interface/src/lib.rs
index 146e85f..efd6dca 100644
--- a/anyrun-interface/src/lib.rs
+++ b/anyrun-interface/src/lib.rs
@@ -56,6 +56,8 @@ pub enum HandleResult {
     Refresh(bool),
     /// Copy the content, due to how copying works it must be done like this.
     Copy(RVec<u8>),
+    /// Output the content to stdout, printing to stdout has issues in plugins.
+    Stdout(RVec<u8>),
 }
 
 #[repr(C)]
diff --git a/anyrun/src/main.rs b/anyrun/src/main.rs
index 474828f..4079fd6 100644
--- a/anyrun/src/main.rs
+++ b/anyrun/src/main.rs
@@ -1,4 +1,12 @@
-use std::{cell::RefCell, env, fs, mem, path::PathBuf, rc::Rc, time::Duration};
+use std::{
+    cell::RefCell,
+    env, fs,
+    io::{self, Write},
+    mem,
+    path::PathBuf,
+    rc::Rc,
+    time::Duration,
+};
 
 use abi_stable::std_types::{ROption, RVec};
 use anyrun_interface::{HandleResult, Match, PluginInfo, PluginRef, PollResult};
@@ -492,6 +500,13 @@ fn activate(app: &gtk::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
                         window.close();
                         Inhibit(true)
                     }
+                    HandleResult::Stdout(bytes) => {
+                        if let Err(why) = io::stdout().lock().write_all(&bytes) {
+                            eprintln!("Error outputting content to stdout: {}", why);
+                        }
+                        window.close();
+                        Inhibit(true)
+                    }
                 }
             }
             _ => Inhibit(false),
diff --git a/plugins/stdin/Cargo.toml b/plugins/stdin/Cargo.toml
new file mode 100644
index 0000000..a45bc28
--- /dev/null
+++ b/plugins/stdin/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "stdin"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib"]
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+anyrun-plugin = { path = "../../anyrun-plugin" }
+fuzzy-matcher = "0.3.7"
+abi_stable = "0.11.1"
diff --git a/plugins/stdin/src/lib.rs b/plugins/stdin/src/lib.rs
new file mode 100644
index 0000000..2e048de
--- /dev/null
+++ b/plugins/stdin/src/lib.rs
@@ -0,0 +1,52 @@
+use std::io::stdin;
+
+use abi_stable::std_types::{ROption, RString, RVec};
+use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo};
+use fuzzy_matcher::FuzzyMatcher;
+
+fn init(_config_dir: RString) -> Vec<String> {
+    stdin().lines().filter_map(|line| line.ok()).collect()
+}
+
+fn handler(_match: Match, _lines: &mut Vec<String>) -> HandleResult {
+    HandleResult::Stdout(_match.title.into_bytes())
+}
+
+fn get_matches(input: RString, lines: &mut Vec<String>) -> RVec<Match> {
+    let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case();
+
+    let mut lines = lines
+        .clone()
+        .into_iter()
+        .filter_map(|line| {
+            matcher
+                .fuzzy_match(&line, &input)
+                .map(|score| (line, score))
+        })
+        .collect::<Vec<_>>();
+
+    lines.sort_by(|a, b| b.1.cmp(&a.1));
+
+    lines.truncate(5);
+
+    lines
+        .into_iter()
+        .map(|(line, _)| Match {
+            title: line.into(),
+            description: ROption::RNone,
+            use_pango: false,
+            icon: ROption::RNone,
+            id: ROption::RNone,
+        })
+        .collect::<Vec<_>>()
+        .into()
+}
+
+fn plugin_info() -> PluginInfo {
+    PluginInfo {
+        name: "Stdin".into(),
+        icon: "format-indent-more".into(),
+    }
+}
+
+plugin!(init, plugin_info, get_matches, handler, Vec<String>);