diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js
index e539b2a428..723a6a7e48 100644
--- a/packages/backend-rs/index.js
+++ b/packages/backend-rs/index.js
@@ -310,7 +310,7 @@ if (!nativeBinding) {
   throw new Error(`Failed to load native binding`)
 }
 
-const { AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, secureRndstr, IdConvertType, convertId, getTimestamp, genId, initIdGenerator } = nativeBinding
+const { AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr, IdConvertType, convertId } = nativeBinding
 
 module.exports.AntennaSrcEnum = AntennaSrcEnum
 module.exports.MutedNoteReasonEnum = MutedNoteReasonEnum
@@ -322,9 +322,9 @@ module.exports.RelayStatusEnum = RelayStatusEnum
 module.exports.UserEmojimodpermEnum = UserEmojimodpermEnum
 module.exports.UserProfileFfvisibilityEnum = UserProfileFfvisibilityEnum
 module.exports.UserProfileMutingnotificationtypesEnum = UserProfileMutingnotificationtypesEnum
+module.exports.initIdGenerator = initIdGenerator
+module.exports.getTimestamp = getTimestamp
+module.exports.genId = genId
 module.exports.secureRndstr = secureRndstr
 module.exports.IdConvertType = IdConvertType
 module.exports.convertId = convertId
-module.exports.getTimestamp = getTimestamp
-module.exports.genId = genId
-module.exports.initIdGenerator = initIdGenerator
diff --git a/packages/backend-rs/src/lib.rs b/packages/backend-rs/src/lib.rs
index f18e69a48f..fcb2323380 100644
--- a/packages/backend-rs/src/lib.rs
+++ b/packages/backend-rs/src/lib.rs
@@ -1,3 +1,5 @@
+pub use macro_rs::napi as export;
+
 pub mod database;
 pub mod macros;
 pub mod model;
diff --git a/packages/backend-rs/src/util/id.rs b/packages/backend-rs/src/util/id.rs
index a37b3c2ea7..3d9281efd3 100644
--- a/packages/backend-rs/src/util/id.rs
+++ b/packages/backend-rs/src/util/id.rs
@@ -21,7 +21,8 @@ const TIME_2000: i64 = 946_684_800_000;
 const TIMESTAMP_LENGTH: u16 = 8;
 
 /// Initializes Cuid2 generator. Must be called before any [create_id].
-pub fn init_id(length: u16, fingerprint: &str) {
+#[cfg_attr(feature = "napi", crate::export)]
+pub fn init_id_generator(length: u16, fingerprint: &str) {
     FINGERPRINT.get_or_init(move || format!("{}{}", fingerprint, cuid2::create_id()));
     GENERATOR.get_or_init(move || {
         cuid2::CuidConstructor::new()
@@ -47,6 +48,7 @@ pub fn create_id(datetime: &NaiveDateTime) -> Result<String, ErrorUninitialized>
     }
 }
 
+#[cfg_attr(feature = "napi", crate::export)]
 pub fn get_timestamp(id: &str) -> i64 {
     let n: Option<u64> = BASE36.decode_var_len(&id[0..8]);
     match n {
@@ -57,29 +59,17 @@ pub fn get_timestamp(id: &str) -> i64 {
 
 cfg_if! {
     if #[cfg(feature = "napi")] {
-        use napi_derive::napi;
         use chrono::{DateTime, Utc};
 
-        /// Calls [init_id] inside. Must be called before [native_create_id].
-        #[napi(js_name = "initIdGenerator")]
-        pub fn native_init_id_generator(length: u16, fingerprint: String) {
-            init_id(length, &fingerprint);
-        }
-
         /// The generated ID results in the form of `[8 chars timestamp] + [cuid2]`.
         /// The minimum and maximum lengths are 16 and 24, respectively.
         /// With the length of 16, namely 8 for cuid2, roughly 1427399 IDs are needed
         /// in the same millisecond to reach 50% chance of collision.
         ///
         /// Ref: https://github.com/paralleldrive/cuid2#parameterized-length
-        #[napi]
+        #[napi_derive::napi]
         pub fn gen_id(date: Option<DateTime<Utc>>) -> String {
-            create_id(&date.unwrap_or_else(|| Utc::now()).naive_utc()).unwrap()
-        }
-
-        #[napi(js_name = "getTimestamp")]
-        pub fn native_get_timestamp(id: String) -> i64 {
-            get_timestamp(&id)
+            create_id(&date.unwrap_or_else(Utc::now).naive_utc()).unwrap()
         }
     }
 }
@@ -95,7 +85,7 @@ mod unit_test {
     fn can_create_and_decode_id() {
         let now = Utc::now().naive_utc();
         assert_eq!(id::create_id(&now), Err(id::ErrorUninitialized));
-        id::init_id(16, "");
+        id::init_id_generator(16, "");
         assert_eq!(id::create_id(&now).unwrap().len(), 16);
         assert_ne!(id::create_id(&now).unwrap(), id::create_id(&now).unwrap());
         let id1 = thread::spawn(move || id::create_id(&now).unwrap());
diff --git a/packages/backend-rs/src/util/random.rs b/packages/backend-rs/src/util/random.rs
index b622d47534..31befbd978 100644
--- a/packages/backend-rs/src/util/random.rs
+++ b/packages/backend-rs/src/util/random.rs
@@ -9,8 +9,7 @@ pub fn gen_string(length: u16) -> String {
         .collect()
 }
 
-#[cfg(feature = "napi")]
-#[napi_derive::napi(js_name = "secureRndstr")]
+#[cfg_attr(feature = "napi", crate::export(js_name = "secureRndstr"))]
 pub fn native_random_str(length: Option<u16>) -> String {
     gen_string(length.unwrap_or(32))
 }