# Stable HashMap without need for an upgrade func

**URL:** <https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040>\
**Category:** Language Support\
**Tags:** Motoko\
**Created:** [January 1, 2022, 1:02pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040 "2022-01-01T13:02:27Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![ClankPan](https://avatars.discourse-cdn.com/v4/letter/c/c5a1d2/32.png) [@ClankPan](https://forum.dfinity.org/u/ClankPan)\
**Post date:** [January 1, 2022, 1:02pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/1 "2022-01-01T13:02:27Z")

</div>

Happy new year, Guys.

I ‘d like to discuss about StableHashMap that simplify upgrade steps.

When we use HashMap lib in Motoko, we have to implement these code. Because class variables can not be stable.

```auto
    var hp = HashMap.HashMap<Text, Nat>(1, Text.equal, Text.hash);
    stable var entries : [(Text, Nat)] = [];

    system func preupgrade() {
        entries := Iter.toArray(hp.entries());
    };

    system func postupgrade() {
        hp := HashMap.fromIter<Text, Nat>(entries.vals(), 1, Text.equal, Text.hash);
        entries := [];
    };

```

This way is difficult to understand and tend to make mistakes.

So, I thought much simpler way to upgrade HashMap.

```auto
    var hp = HashMap.HashMap<Text, Nat>(1, Text.equal, Text.hash);
    stable var stableVars = hp.exportVars();

    system func preupgrade() {
        stableVars := hp.exportVars();
    };
    system func postupgrade() {
        hp := HashMap.HashMap<Text, Nat>(1, Text.equal, Text.hash);
        hp.importVars(stableVars);
    };

```

This is implemented by passing the address of table variable inside HashMap class object to the stable variable in main.

If it is possible to share stable name space, we don’t need upgrade methods anymore.  
But now, stable variables are bound in compiler, not address. So they can’t pass stable as an argument either.

By changing Motoko’s syntax and allowing stable var namespaces to be shared, we will be released from the hassle of the upgrade method.

Here is a proof of concept.  
[// GitHub URL](https://github.com/ClankPan/StableHashMap/blob/master/src/StableHashMap/main.mo)

Thanks.

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 18, 2023, 1:41am UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/2 "2023-01-18T01:41:58Z")

</div>

I’m using this in my repo. Thank you. Do you still see this as a good approach?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [January 18, 2023, 11:41am UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/3 "2023-01-18T11:41:56Z")

</div>

Just use [GitHub - ZhenyaUsenko/motoko-hash-map: Stable hash maps for Motoko](https://github.com/ZhenyaUsenko/motoko-hash-map) and you’ll get 4-11x performance and a stable structure with no need to upgrade.

We’ve been using [GitHub - ZhenyaUsenko/motoko-migrations: Sample project structure to implement migrations in motoko](https://github.com/ZhenyaUsenko/motoko-migrations) as an upgrade pattern and it is working well.

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 18, 2023, 1:36pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/4 "2023-01-18T13:36:27Z")

</div>

> [@skilesare](#):
>
> Just use [GitHub - ZhenyaUsenko/motoko-hash-map: Stable hash maps for Motoko](https://github.com/ZhenyaUsenko/motoko-hash-map) and you’ll get 4-11x performance and a stable structure with no need to upgrade.
> 
> We’ve been using [GitHub - ZhenyaUsenko/motoko-migrations: Sample project structure to implement migrations in motoko](https://github.com/ZhenyaUsenko/motoko-migrations) as an upgrade pattern and it is working well.

Thanks. To be clear: those are two separate ways of doing it, right? If I use the first repo I don’t need to look into the second one, correct?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [January 18, 2023, 1:49pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/5 "2023-01-18T13:49:04Z")

</div>

No. You would use them in conjunction. You don’t need migrations, but if you ever change something in your hashmap, you need to upgrade all your objects to the new types, and migrations gives you a pattern to do that with.

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 18, 2023, 2:01pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/6 "2023-01-18T14:01:14Z")

</div>

Perfect. So, as long as the _types_ the hashmap stores don’t change, I don’t need to worry about migrations, not even through updates. Correct?

Actually I’m getting errors trying to use that repo:

 ![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/2X/4/4290dbfd3f9fad2093513c4269a3922b7e61f444.png)

Not sure if it’s due to the way I imported it:

```auto
// From https://github.com/ZhenyaUsenko/motoko-hash-map/tree/master/src/Map
import Map "Map/optimized";

```

Also tried

```auto
// From https://github.com/ZhenyaUsenko/motoko-hash-map
import Map "motoko-hash-map/src/Map/Map";

```

with no errors at import but the same errors as above on use.

How do I integrate it to the project so that

`import Map "mo:hashmap/Map";`

works?

---

<div class="post-metadata">

**Author:** ![rncrmn](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rncrmn](https://forum.dfinity.org/u/rncrmn)\
**Post date:** [February 2, 2023, 3:29pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/7 "2023-02-02T15:29:15Z")

</div>

Did you able to make it work the **import Map “mo:hashmap/Map”;**? if yes, how did you do it?

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [February 2, 2023, 3:38pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/8 "2023-02-02T15:38:41Z")

</div>

Yes, I did

`import Map "motoko-hash-map/src/Map/Map"; // From https://github.com/ZhenyaUsenko/motoko-hash-map`

and just placed the complete directory there.

There’s probably a better way though, using vessel I think, but I’m using mops and they’re mutually incompatible.

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [February 2, 2023, 3:51pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/9 "2023-02-02T15:51:42Z")

</div>

@ZhenyaUsenko Maybe we should add mops support to this library?

---

<div class="post-metadata">

**Author:** ![rncrmn](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rncrmn](https://forum.dfinity.org/u/rncrmn)\
**Post date:** [February 2, 2023, 11:57pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/10 "2023-02-02T23:57:45Z")

</div>

Thank you @blabagastered

---

<div class="post-metadata">

**Author:** ![rncrmn](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rncrmn](https://forum.dfinity.org/u/rncrmn)\
**Post date:** [February 2, 2023, 11:59pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/11 "2023-02-02T23:59:51Z")

</div>

> [@skilesare](#):
>
> @ZhenyaUsenko Maybe we should add mops support to this library?

I second that, please.

---

<div class="post-metadata">

**Author:** ![ZenVoich](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zenvoich/32/5969_2.png) [@ZenVoich](https://forum.dfinity.org/u/ZenVoich)\
**Post date:** [February 3, 2023, 7:44am UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/12 "2023-02-03T07:44:14Z")

</div>

Actually with mops you can install packages from GitHub too [How do I enable / install moc? - #8 by ZenVoich](https://forum.dfinity.org/t/how-do-i-enable-install-moc/18005/8)  
But would love to see it published to mops)

---

<div class="post-metadata">

**Author:** ![AlexandruFilipescu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alexandrufilipescu/32/9306_2.png) [@AlexandruFilipescu](https://forum.dfinity.org/u/AlexandruFilipescu)\
**Post date:** [February 5, 2023, 11:21am UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/13 "2023-02-05T11:21:03Z")

</div>

Hello, I just installed the stable hashMap library, in order to use it we just define the let like this:

```auto
let map1 = Map.new<Nat, Message>();

```

Don’t we need to use the stable keyword in front? Thank you guys!

Also is it possible to use this type for a key without receiving the error “shared function has non-shared parameter type”

```auto
 type ChatRoom = {
    id: Nat;
    creator: Text;
    messages: Map.Map<Text, Message>; //Here! is this possible?
  };

```

I am using a normal HashMap to store “ChatRooms” and each chatroom has its messages. I am having trouble to loop and delete from the Array of messages that every ChatRoom has, which would be the best data structure? Thank you!

```auto
 type ChatRoom = {
    id: Nat;
    creator: Text;
    messages: [Message];
  };

  type Message = {
    id: Nat;
    sender: Text;
    timestamp: Time.Time;
    text: Text;
  };

```

---

<div class="post-metadata">

**Author:** ![AlexandruFilipescu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alexandrufilipescu/32/9306_2.png) [@AlexandruFilipescu](https://forum.dfinity.org/u/AlexandruFilipescu)\
**Post date:** [February 5, 2023, 12:50pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/14 "2023-02-05T12:50:04Z")

</div>

\*Edit  
I started using .filterEntries()

```auto
bufferedMessages.filterEntries(
      func(_, x) = x.id != messageId
    );

```

Even though I am not sure what is the role of the first parameter in the func, the underscore.

---

<div class="post-metadata">

**Author:** ![icaten](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/icaten/32/9897_2.png) [@icaten](https://forum.dfinity.org/u/icaten)\
**Post date:** [February 17, 2023, 10:48pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/15 "2023-02-17T22:48:15Z")

</div>

Designates wildcard pattern so that argument will match any type.

---

<div class="post-metadata">

**Author:** ![augchan42](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/augchan42/32/3405_2.png) [@augchan42](https://forum.dfinity.org/u/augchan42)\
**Post date:** [January 6, 2024, 2:29pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/16 "2024-01-06T14:29:26Z")

</div>

Did you ever get an answer to your question about stable keyword? I’m thinking of using this but have some doubt on whether it will behave properly when the map is initialized with Map.new() (whether existing values are preserved on upgrade)

---

<div class="post-metadata">

**Author:** ![antinutrino](https://avatars.discourse-cdn.com/v4/letter/a/f9ae1b/32.png) [@antinutrino](https://forum.dfinity.org/u/antinutrino)\
**Post date:** [May 18, 2025, 2:26pm UTC](https://forum.dfinity.org/t/stable-hashmap-without-need-for-an-upgrade-func/10040/17 "2025-05-18T14:26:40Z")

</div>

Is this the recommend package to use for stable hashmap

or can we use

stable var map: HashMap\<K,V\> from mo:base/HashMap

Thanks
