diff --git a/espanso-clipboard/build.rs b/espanso-clipboard/build.rs
index 325e9ac..3d50903 100644
--- a/espanso-clipboard/build.rs
+++ b/espanso-clipboard/build.rs
@@ -61,12 +61,12 @@ fn cc_config() {
 
 #[cfg(target_os = "macos")]
 fn cc_config() {
-  println!("cargo:rerun-if-changed=src/mac/native.mm");
-  println!("cargo:rerun-if-changed=src/mac/native.h");
+  println!("cargo:rerun-if-changed=src/cocoa/native.mm");
+  println!("cargo:rerun-if-changed=src/cocoa/native.h");
   cc::Build::new()
     .cpp(true)
-    .include("src/mac/native.h")
-    .file("src/mac/native.mm")
+    .include("src/cocoa/native.h")
+    .file("src/cocoa/native.mm")
     .compile("espansoclipboard");
   println!("cargo:rustc-link-lib=dylib=c++");
   println!("cargo:rustc-link-lib=static=espansoclipboard");
diff --git a/espanso-clipboard/src/cocoa/ffi.rs b/espanso-clipboard/src/cocoa/ffi.rs
new file mode 100644
index 0000000..9528786
--- /dev/null
+++ b/espanso-clipboard/src/cocoa/ffi.rs
@@ -0,0 +1,28 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso.  If not, see .
+ */
+
+use std::os::raw::c_char;
+
+#[link(name = "espansoclipboard", kind = "static")]
+extern "C" {
+  pub fn clipboard_get_text(buffer: *mut c_char, buffer_size: i32) -> i32;
+  pub fn clipboard_set_text(text: *const c_char) -> i32;
+  pub fn clipboard_set_image(image_path: *const c_char) -> i32;
+  pub fn clipboard_set_html(html_descriptor: *const c_char, fallback_text: *const c_char) -> i32;
+}
diff --git a/espanso-clipboard/src/cocoa/mod.rs b/espanso-clipboard/src/cocoa/mod.rs
new file mode 100644
index 0000000..3add22e
--- /dev/null
+++ b/espanso-clipboard/src/cocoa/mod.rs
@@ -0,0 +1,100 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso.  If not, see .
+ */
+
+mod ffi;
+
+use std::{ffi::{CStr, CString}, path::PathBuf};
+
+use crate::Clipboard;
+use anyhow::Result;
+use log::error;
+use thiserror::Error;
+
+pub struct CocoaClipboard {}
+
+impl CocoaClipboard {
+  pub fn new() -> Result {
+    Ok(Self {})
+  }
+}
+
+impl Clipboard for CocoaClipboard {
+  fn get_text(&self) -> Option {
+    let mut buffer: [i8; 2048] = [0; 2048];
+    let native_result =
+      unsafe { ffi::clipboard_get_text(buffer.as_mut_ptr(), (buffer.len() - 1) as i32) };
+    if native_result > 0 {
+      let string = unsafe { CStr::from_ptr(buffer.as_ptr()) };
+      Some(string.to_string_lossy().to_string())
+    } else {
+      None
+    }
+  }
+
+  fn set_text(&self, text: &str) -> anyhow::Result<()> {
+    let string = CString::new(text)?;
+    let native_result = unsafe { ffi::clipboard_set_text(string.as_ptr()) };
+    if native_result > 0 {
+      Ok(())
+    } else {
+      Err(CocoaClipboardError::SetOperationFailed().into())
+    }
+  }
+
+  fn set_image(&self, image_path: &std::path::Path) -> anyhow::Result<()> {
+    if !image_path.exists() || !image_path.is_file() {
+      return Err(CocoaClipboardError::ImageNotFound(image_path.to_path_buf()).into());
+    }
+
+    let path = CString::new(image_path.to_string_lossy().to_string())?;
+    let native_result = unsafe { ffi::clipboard_set_image(path.as_ptr()) };
+
+    if native_result > 0 {
+      Ok(())
+    } else {
+      Err(CocoaClipboardError::SetOperationFailed().into())
+    }
+  }
+
+  fn set_html(&self, html: &str, fallback_text: Option<&str>) -> anyhow::Result<()> {
+    let html_string = CString::new(html)?;
+    let fallback_string = CString::new(fallback_text.unwrap_or_default())?;
+    let fallback_ptr = if fallback_text.is_some() {
+      fallback_string.as_ptr()
+    } else {
+      std::ptr::null()
+    };
+
+    let native_result = unsafe { ffi::clipboard_set_html(html_string.as_ptr(), fallback_ptr) };
+    if native_result > 0 {
+      Ok(())
+    } else {
+      Err(CocoaClipboardError::SetOperationFailed().into())
+    }
+  }
+}
+
+#[derive(Error, Debug)]
+pub enum CocoaClipboardError {
+  #[error("clipboard set operation failed")]
+  SetOperationFailed(),
+
+  #[error("image not found: `{0}`")]
+  ImageNotFound(PathBuf),
+}
diff --git a/espanso-clipboard/src/cocoa/native.h b/espanso-clipboard/src/cocoa/native.h
new file mode 100644
index 0000000..f22c0e8
--- /dev/null
+++ b/espanso-clipboard/src/cocoa/native.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso.  If not, see .
+ */
+
+#ifndef ESPANSO_CLIPBOARD_H
+#define ESPANSO_CLIPBOARD_H
+
+#include 
+
+extern "C" int32_t clipboard_get_text(char * buffer, int32_t buffer_size);
+extern "C" int32_t clipboard_set_text(char * text);
+extern "C" int32_t clipboard_set_image(char * image_path);
+extern "C" int32_t clipboard_set_html(char * html, char * fallback_text);
+
+#endif //ESPANSO_CLIPBOARD_H
\ No newline at end of file
diff --git a/espanso-clipboard/src/cocoa/native.mm b/espanso-clipboard/src/cocoa/native.mm
new file mode 100644
index 0000000..b60f56d
--- /dev/null
+++ b/espanso-clipboard/src/cocoa/native.mm
@@ -0,0 +1,87 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso.  If not, see .
+ */
+
+#include "native.h"
+#import 
+#import 
+#include 
+
+int32_t clipboard_get_text(char * buffer, int32_t buffer_size) {
+  NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+  for (id element in pasteboard.pasteboardItems) {
+    NSString *string = [element stringForType: NSPasteboardTypeString];
+    if (string != NULL) {
+      const char * text = [string UTF8String];
+      strncpy(buffer, text, buffer_size);
+
+      [string release];
+
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int32_t clipboard_set_text(char * text) {
+  NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+  NSArray *array = @[NSPasteboardTypeString];
+  [pasteboard declareTypes:array owner:nil];
+
+  NSString *nsText = [NSString stringWithUTF8String:text];
+  [pasteboard setString:nsText forType:NSPasteboardTypeString];
+}
+
+int32_t clipboard_set_image(char * image_path) {
+  NSString *pathString = [NSString stringWithUTF8String:image_path];
+  NSImage *image = [[NSImage alloc] initWithContentsOfFile:pathString];
+  int result = 0;
+
+  if (image != nil) {
+      NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+      [pasteboard clearContents];
+      NSArray *copiedObjects = [NSArray arrayWithObject:image];
+      [pasteboard writeObjects:copiedObjects];
+      result = 1;
+  }
+  [image release];
+
+  return result;
+}
+
+int32_t clipboard_set_html(char * html, char * fallback_text) {
+  NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+  NSArray *array = @[NSRTFPboardType, NSPasteboardTypeString];
+  [pasteboard declareTypes:array owner:nil];
+
+  NSString *nsHtml = [NSString stringWithUTF8String:html];
+  NSDictionary *documentAttributes = [NSDictionary dictionaryWithObjectsAndKeys:NSHTMLTextDocumentType, NSDocumentTypeDocumentAttribute, NSCharacterEncodingDocumentAttribute,[NSNumber numberWithInt:NSUTF8StringEncoding], nil];
+  NSAttributedString* atr = [[NSAttributedString alloc] initWithData:[nsHtml dataUsingEncoding:NSUTF8StringEncoding] options:documentAttributes documentAttributes:nil error:nil];
+
+  NSData *rtf = [atr RTFFromRange:NSMakeRange(0, [atr length])
+                                  documentAttributes:nil];
+
+  [pasteboard setData:rtf forType:NSRTFPboardType];
+
+  if (fallback_text) {
+    NSString *nsText = [NSString stringWithUTF8String:fallback_text];
+    [pasteboard setString:nsText forType:NSPasteboardTypeString];
+  }
+  
+  return 1;
+}
\ No newline at end of file
diff --git a/espanso-clipboard/src/lib.rs b/espanso-clipboard/src/lib.rs
index c60cb69..efa1adf 100644
--- a/espanso-clipboard/src/lib.rs
+++ b/espanso-clipboard/src/lib.rs
@@ -34,7 +34,7 @@ mod x11;
 mod wayland;
 
 #[cfg(target_os = "macos")]
-mod mac;
+mod cocoa;
 
 pub trait Clipboard {
   fn get_text(&self) -> Option;
@@ -66,9 +66,9 @@ pub fn get_clipboard(_: ClipboardOptions) -> Result> {
 }
 
 #[cfg(target_os = "macos")]
-pub fn get_injector(_options: InjectorCreationOptions) -> Result> {
-  info!("using MacInjector");
-  Ok(Box::new(mac::MacInjector::new()))
+pub fn get_clipboard(_: ClipboardOptions) -> Result> {
+  info!("using CocoaClipboard");
+  Ok(Box::new(cocoa::CocoaClipboard::new()?))
 }
 
 #[cfg(target_os = "linux")]