diff --git a/atuin-client/src/import/mod.rs b/atuin-client/src/import/mod.rs
index 3f8ea35..0b21d60 100644
--- a/atuin-client/src/import/mod.rs
+++ b/atuin-client/src/import/mod.rs
@@ -4,6 +4,7 @@ use std::io::{BufRead, BufReader, Seek, SeekFrom};
 use eyre::Result;
 
 pub mod bash;
+pub mod resh;
 pub mod zsh;
 
 // this could probably be sped up
diff --git a/atuin-client/src/import/resh.rs b/atuin-client/src/import/resh.rs
new file mode 100644
index 0000000..07f0203
--- /dev/null
+++ b/atuin-client/src/import/resh.rs
@@ -0,0 +1,56 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+pub struct ReshEntry {
+    pub cmd_line: String,
+    pub exit_code: i64,
+    pub shell: String,
+    pub uname: String,
+    pub session_id: String,
+    pub home: String,
+    pub lang: String,
+    pub lc_all: String,
+    pub login: String,
+    pub pwd: String,
+    pub pwd_after: String,
+    pub shell_env: String,
+    pub term: String,
+    pub real_pwd: String,
+    pub real_pwd_after: String,
+    pub pid: i64,
+    pub session_pid: i64,
+    pub host: String,
+    pub hosttype: String,
+    pub ostype: String,
+    pub machtype: String,
+    pub shlvl: i64,
+    pub timezone_before: String,
+    pub timezone_after: String,
+    pub realtime_before: f64,
+    pub realtime_after: f64,
+    pub realtime_before_local: f64,
+    pub realtime_after_local: f64,
+    pub realtime_duration: f64,
+    pub realtime_since_session_start: f64,
+    pub realtime_since_boot: f64,
+    pub git_dir: String,
+    pub git_real_dir: String,
+    pub git_origin_remote: String,
+    pub git_dir_after: String,
+    pub git_real_dir_after: String,
+    pub git_origin_remote_after: String,
+    pub machine_id: String,
+    pub os_release_id: String,
+    pub os_release_version_id: String,
+    pub os_release_id_like: String,
+    pub os_release_name: String,
+    pub os_release_pretty_name: String,
+    pub resh_uuid: String,
+    pub resh_version: String,
+    pub resh_revision: String,
+    pub parts_merged: bool,
+    pub recalled: bool,
+    pub recall_last_cmd_line: String,
+    pub cols: String,
+    pub lines: String,
+}
diff --git a/src/command/import.rs b/src/command/import.rs
index 09df583..c51e918 100644
--- a/src/command/import.rs
+++ b/src/command/import.rs
@@ -1,13 +1,15 @@
 use std::env;
 use std::path::PathBuf;
 
+use atuin_common::utils::uuid_v4;
+use chrono::{TimeZone, Utc};
 use directories::UserDirs;
 use eyre::{eyre, Result};
 use structopt::StructOpt;
 
-use atuin_client::database::Database;
 use atuin_client::history::History;
 use atuin_client::import::{bash::Bash, zsh::Zsh};
+use atuin_client::{database::Database, import::resh::ReshEntry};
 use indicatif::ProgressBar;
 
 #[derive(StructOpt)]
@@ -29,6 +31,12 @@ pub enum Cmd {
         aliases=&["b", "ba", "bas"],
     )]
     Bash,
+
+    #[structopt(
+        about="import history from the resh history file",
+        aliases=&["r", "re", "res"],
+    )]
+    Resh,
 }
 
 impl Cmd {
@@ -56,10 +64,75 @@ impl Cmd {
 
             Self::Zsh => import_zsh(db).await,
             Self::Bash => import_bash(db).await,
+            Self::Resh => import_resh(db).await,
         }
     }
 }
 
+async fn import_resh(db: &mut (impl Database + Send + Sync)) -> Result<()> {
+    let histpath = std::path::Path::new(std::env::var("HOME")?.as_str()).join(".resh_history.json");
+
+    println!("Parsing .resh_history.json...");
+    #[allow(clippy::filter_map)]
+    let history = std::fs::read_to_string(histpath)?
+        .split('\n')
+        .map(str::trim)
+        .map(|x| serde_json::from_str::<ReshEntry>(x))
+        .filter_map(Result::ok)
+        .map(|x| {
+            #[allow(clippy::cast_possible_truncation)]
+            #[allow(clippy::cast_sign_loss)]
+            let timestamp = {
+                let secs = x.realtime_before.floor() as i64;
+                let nanosecs = (x.realtime_before.fract() * 1_000_000_000_f64).round() as u32;
+                Utc.timestamp(secs, nanosecs)
+            };
+            #[allow(clippy::cast_possible_truncation)]
+            #[allow(clippy::cast_sign_loss)]
+            let duration = {
+                let secs = x.realtime_after.floor() as i64;
+                let nanosecs = (x.realtime_after.fract() * 1_000_000_000_f64).round() as u32;
+                let difference = Utc.timestamp(secs, nanosecs) - timestamp;
+                difference.num_nanoseconds().unwrap_or(0)
+            };
+
+            History {
+                id: uuid_v4(),
+                timestamp,
+                duration,
+                exit: x.exit_code,
+                command: x.cmd_line,
+                cwd: x.pwd,
+                session: uuid_v4(),
+                hostname: x.host,
+            }
+        })
+        .collect::<Vec<_>>();
+    println!("Updating database...");
+
+    let progress = ProgressBar::new(history.len() as u64);
+
+    let buf_size = 100;
+    let mut buf = Vec::<_>::with_capacity(buf_size);
+
+    for i in history {
+        buf.push(i);
+
+        if buf.len() == buf_size {
+            db.save_bulk(&buf).await?;
+            progress.inc(buf.len() as u64);
+
+            buf.clear();
+        }
+    }
+
+    if !buf.is_empty() {
+        db.save_bulk(&buf).await?;
+        progress.inc(buf.len() as u64);
+    }
+    Ok(())
+}
+
 async fn import_zsh(db: &mut (impl Database + Send + Sync)) -> Result<()> {
     // oh-my-zsh sets HISTFILE=~/.zhistory
     // zsh has no default value for this var, but uses ~/.zhistory.