amplify-js icon indicating copy to clipboard operation
amplify-js copied to clipboard

[Question / Feature Request] Using Different Local Storage Library Other than `react-native-async-storage` (`react-native-mmkv`)

Open ChristopherGabba opened this issue 4 months ago • 3 comments

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Cache

Amplify Version

v6

Amplify Categories

No response

Backend

None

Environment information

 System:
    OS: macOS 15.6.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 500.70 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.4.0 - ~/.nvm/versions/node/v23.4.0/bin/node
    Yarn: 1.22.22 - /opt/homebrew/bin/yarn
    npm: 11.5.2 - ~/.nvm/versions/node/v23.4.0/bin/npm
    bun: 1.2.19 - /opt/homebrew/bin/bun
    Watchman: 2025.04.14.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 139.0.7258.155
    Safari: 18.6
  npmPackages:
    %name%:  0.1.0 
    @aws-amplify/backend: ^1.11.0 => 1.16.1 
    @aws-amplify/backend-cli: ^1.8.0 => 1.8.0 
    @aws-amplify/react-native: ^1.1.10 => 1.1.10 
    @aws-amplify/rtn-web-browser: ^1.1.4 => 1.1.4 
    @aws-appsync/utils: 2.0.3 => 2.0.3 
    @aws-sdk/client-cognito-identity-provider: 3.799.0 => 3.799.0 
    @aws-sdk/client-dynamodb: 3.799.0 => 3.799.0 
    @aws-sdk/client-sso-oidc: 3.799.0 => 3.799.0 (3.622.0, 3.637.0, 3.624.0, 3.621.0)
    @aws-sdk/client-sts: 3.799.0 => 3.799.0 (3.622.0, 3.879.0, 3.624.0, 3.621.0)
    @aws-sdk/types: 3.775.0 => 3.775.0 (3.609.0, 3.387.0, 3.862.0, 3.398.0, 3.821.0, 3.734.0)
    @aws-sdk/util-dynamodb: 3.799.0 => 3.799.0 
    @babel/core: ^7.20.0 => 7.28.3 
    @babel/plugin-proposal-export-namespace-from: ^7.18.9 => 7.18.9 
    @babel/plugin-proposal-optional-chaining: ^7.0.0 => 7.21.0 
    @babel/plugin-transform-arrow-functions: ^7.0.0 => 7.27.1 
    @babel/plugin-transform-nullish-coalescing-operator: ^7.0.0 => 7.27.1 
    @babel/plugin-transform-shorthand-properties: ^7.0.0 => 7.27.1 
    @babel/plugin-transform-template-literals: ^7.0.0 => 7.27.1 
    @babel/preset-env: ^7.20.0 => 7.28.3 
    @babel/runtime: ^7.20.0 => 7.28.3 
    @config-plugins/ffmpeg-kit-react-native: 9.0.0 => 9.0.0 
    @expo-google-fonts/m-plus-1p: 0.2.3 => 0.2.3 
    @expo-google-fonts/montserrat: 0.2.3 => 0.2.3 
    @expo/config-plugins: ~11.0.5 => 11.0.5 (10.1.2)
    @expo/metro-runtime: ~6.1.0 => 6.1.1 
    @gorhom/bottom-sheet: 5.1.6 => 5.1.6 
    @legendapp/list: ^2.0.0-beta.4 => 2.0.0-next.25 
    @react-native-async-storage/async-storage: 2.2.0 => 2.2.0 
    @react-native-community/netinfo: 11.4.1 => 11.4.1 
    @react-native-menu/menu: ^1.2.4 => 1.2.4 
    @react-navigation/bottom-tabs: 7.4.6 => 7.4.6 
    @react-navigation/native: 7.1.17 => 7.1.17 
    @react-navigation/native-stack: 7.3.25 => 7.3.25 
    @sentry/react-native: ~6.20.0 => 6.20.0 
    @tanstack/query-codemods:  undefined ()
    @tanstack/react-query: ^5.85.5 => 5.85.5 
    @tanstack/react-query-persist-client: ^5.85.5 => 5.85.5 
    @types/i18n-js: 3.8.2 => 3.8.2 
    @types/jest: ^29.2.1 => 29.5.14 
    @types/lodash.filter: ^4.6.9 => 4.6.9 
    @types/node: 22.10.5 => 22.10.5 (24.3.0)
    @types/react: ~19.1.10 => 19.1.12 (18.3.24)
    @types/react-test-renderer: ^18.0.0 => 18.3.1 
    @typescript-eslint/eslint-plugin: ^8.33.1 => 8.41.0 
    @typescript-eslint/parser: ^8.33.1 => 8.41.0 
    @typescript-eslint/utils: ^8.31.1 => 8.41.0 
    ContextAPIMixpanel:  0.0.1 
    MixpanelDemo:  0.0.1 
    MixpanelExample:  0.0.1 
    SimpleMixpanel:  0.0.1 
    aws-amplify: ^6.15.5 => 6.15.5 
    aws-amplify/adapter-core:  undefined ()
    aws-amplify/adapter-core/internals:  undefined ()
    aws-amplify/analytics:  undefined ()
    aws-amplify/analytics/kinesis:  undefined ()
    aws-amplify/analytics/kinesis-firehose:  undefined ()
    aws-amplify/analytics/personalize:  undefined ()
    aws-amplify/analytics/pinpoint:  undefined ()
    aws-amplify/api:  undefined ()
    aws-amplify/api/internals:  undefined ()
    aws-amplify/api/server:  undefined ()
    aws-amplify/auth:  undefined ()
    aws-amplify/auth/cognito:  undefined ()
    aws-amplify/auth/cognito/server:  undefined ()
    aws-amplify/auth/enable-oauth-listener:  undefined ()
    aws-amplify/auth/server:  undefined ()
    aws-amplify/data:  undefined ()
    aws-amplify/data/server:  undefined ()
    aws-amplify/datastore:  undefined ()
    aws-amplify/in-app-messaging:  undefined ()
    aws-amplify/in-app-messaging/pinpoint:  undefined ()
    aws-amplify/push-notifications:  undefined ()
    aws-amplify/push-notifications/pinpoint:  undefined ()
    aws-amplify/storage:  undefined ()
    aws-amplify/storage/s3:  undefined ()
    aws-amplify/storage/s3/server:  undefined ()
    aws-amplify/storage/server:  undefined ()
    aws-amplify/utils:  undefined ()
    aws-cdk: 2.1013.0 => 2.1013.0 
    aws-cdk-lib: 2.194.0 => 2.194.0 
    babel-jest: ^29.2.1 => 29.7.0 
    buffer: 6.0.3 => 6.0.3 (4.9.2, 5.6.0, 5.7.1)
    constructs: ^10.3.0 => 10.4.2 
    date-fns: 4.1.0 => 4.1.0 
    esbuild: ^0.21.1 => 0.21.5 (0.25.9)
    eslint: ^9.28.0 => 9.34.0 
    eslint-config-prettier: 9.1.0 => 9.1.0 
    eslint-config-standard: 17.0.0 => 17.0.0 
    eslint-plugin-import: 2.26.0 => 2.26.0 
    eslint-plugin-n: ^15.0.0 => 15.7.0 
    eslint-plugin-promise: 6.6.0 => 6.6.0 
    eslint-plugin-react: ^7.37.5 => 7.37.5 
    eslint-plugin-react-native: 4.0.0 => 4.0.0 
    expo: 54.0.0-preview.11 => 54.0.0-preview.11 
    expo-application: ~7.0.4 => 7.0.4 
    expo-blur: ~15.0.4 => 15.0.4 
    expo-build-properties: ~1.0.5 => 1.0.5 
    expo-clipboard: ~8.0.4 => 8.0.4 
    expo-constants: ~18.0.5 => 18.0.5 
    expo-contacts: ~15.0.5 => 15.0.5 
    expo-dev-client: ~6.0.6 => 6.0.6 
    expo-device: ~8.0.4 => 8.0.4 
    expo-file-system: ~19.0.5 => 19.0.6 
    expo-font: ~14.0.5 => 14.0.5 
    expo-haptics: ~15.0.4 => 15.0.4 
    expo-image: ~3.0.3 => 3.0.4 
    expo-image-picker: ~17.0.5 => 17.0.5 
    expo-keep-awake: ~15.0.4 => 15.0.4 
    expo-linear-gradient: ~15.0.4 => 15.0.4 
    expo-linking: ~8.0.5 => 8.0.5 
    expo-localization: ~17.0.4 => 17.0.4 
    expo-secure-store: ~15.0.4 => 15.0.4 
    expo-share-intent: 4.1.1 => 4.1.1 
    expo-sharing: ~14.0.4 => 14.0.4 
    expo-sms: ~14.0.4 => 14.0.4 
    expo-splash-screen: ~31.0.6 => 31.0.6 
    expo-store-review: ~9.0.4 => 9.0.4 
    expo-video: ~3.0.7 => 3.0.7 
    expo-video-metadata: 1.5.0 => 1.5.0 
    expo-video-thumbnails: ~10.0.4 => 10.0.4 
    ffmpeg-kit-react-native: 6.0.2 => 6.0.2 
    follow-redirects: 1.15.9 => 1.15.9 
    i18next: 25.2.1 => 25.2.1 
    intl-pluralrules: 2.0.1 => 2.0.1 
    jest: ^29.2.1 => 29.7.0 
    jest-expo: ~54.0.5 => 54.0.5 
    libphonenumber-js: 1.11.19 => 1.11.19 (1.9.47)
    libphonenumber-js-core:  undefined (1.0.0)
    libphonenumber-js-max:  undefined (1.0.0)
    libphonenumber-js-min:  undefined (1.0.0)
    libphonenumber-js-mobile:  undefined (1.0.0)
    libphonenumber-js/build:  undefined ()
    libphonenumber-js/core:  undefined ()
    libphonenumber-js/max:  undefined ()
    libphonenumber-js/max/metadata:  undefined ()
    libphonenumber-js/min:  undefined ()
    libphonenumber-js/min/metadata:  undefined ()
    libphonenumber-js/mobile:  undefined ()
    libphonenumber-js/mobile/examples:  undefined ()
    libphonenumber-js/mobile/metadata:  undefined ()
    lodash: 4.17.21 => 4.17.21 
    lottie-react-native: ~7.3.1 => 7.3.3 
    mixpanel-react-native: 3.1.2 => 3.1.2 
    mixpanelexpo:  1.0.0 
    onesignal-expo-plugin: 2.0.3 => 2.0.3 
    patch-package: 6.4.7 => 6.4.7 
    postinstall-prepare: 1.0.1 => 1.0.1 
    prettier: 2.8.8 => 2.8.8 (2.3.2, 3.6.2, 1.19.1)
    react: 19.1.0 => 19.1.0 (19.2.0-canary-5252281c-20250408)
    react-dom: 19.1.0 => 19.1.0 (19.2.0-canary-5252281c-20250408)
    react-i18next: 15.4.1 => 15.4.1 
    react-native: 0.81.1 => 0.81.1 
    react-native-blurhash: ^2.1.1 => 2.1.2 
    react-native-compressor: ^1.12.0 => 1.12.0 
    react-native-edge-to-edge: ^1.6.2 => 1.7.0 
    react-native-gesture-handler: ~2.28.0 => 2.28.0 
    react-native-get-random-values: 1.11.0 => 1.11.0 
    react-native-ios-context-menu: 3.1.3 => 3.1.3 
    react-native-ios-utilities: 5.1.8 => 5.1.8 
    react-native-keyboard-controller: 1.18.5 => 1.18.5 
    react-native-mime-types: 2.5.0 => 2.5.0 
    react-native-mmkv: 2.12.2 => 2.12.2 
    react-native-nitro-audio-manager: 0.1.3 => 0.1.3 
    react-native-nitro-modules: 0.28.1 => 0.28.1 
    react-native-nitro-screen-recorder: ^0.3.5 => 0.3.5 
    react-native-onesignal: 5.2.13 => 5.2.13 
    react-native-reanimated: ~3.19.1 => 3.19.1 
    react-native-safe-area-context: ~5.6.0 => 5.6.1 
    react-native-screens: ~4.15.0 => 4.15.4 
    react-native-static-safe-area-insets: 2.2.0 => 2.2.0 
    react-native-url-polyfill: 2.0.0 => 2.0.0 
    react-native-vision-camera: 4.7.0 => 4.7.0 
    react-native-vision-camera-face-detector: 1.8.3 => 1.8.3 
    react-native-webview: 13.15.0 => 13.15.0 
    react-native-worklets-core: 1.5.0 => 1.5.0 
    react-native-youtube-iframe: 2.3.0 => 2.3.0 
    react-native-z-view: 0.2.4 => 0.2.4 
    react-test-renderer: 18.2.0 => 18.2.0 (19.1.0)
    ts-jest: ^29.1.1 => 29.4.1 
    ts-node: ^10.9.2 => 10.9.2 
    tsx: ^4.9.4 => 4.20.5 (4.19.4)
    typescript: ~5.9.2 => 5.9.2 (4.4.4, 4.9.5)
    uuid: 11.0.5 => 11.0.5 (9.0.1, 11.1.0, 3.3.2, 7.0.3)
    zeego: 3.0.6 => 3.0.6 
    zustand: 5.0.5 => 5.0.5 
  npmGlobalPackages:
    corepack: 0.30.0
    eas-cli: 16.17.4
    license-checker: 25.0.1
    npm: 11.5.2


Describe the bug

Currently react-native-async-storage is the default dependency for aws-amplify

See docs: https://docs.amplify.aws/react-native/start/quickstart/ Image

It's currently the slowest storage alternative out there in the react-native ecosystem and the community is slowly migrating to react-native-mmkv which is a synchronous local storage system that is much faster. See benchmarks:

Image

I currently use mmkv for everything except amplify, and I have to keep react-native-async-storage as a dependency in my app, just to serve this one purpose. Is there a way to replace the storage instance / persister to mmkv in Amplify.configure?

Here would be some sort of API to explain it:

const amplifyStorageOverwrite = {
  setItem: (key: string, value: string) => {
    mmkv.set(key, value);
    return Promise.resolve();
  },
  getItem: (key: string) => {
    const value = mmkv.getString(key);
    return Promise.resolve(value ?? null);
  },
  removeItem: (key: string) => {
    mmkv.delete(key);
    return Promise.resolve();
  },
  clear: () => {
    mmkv.clearAll();
    return Promise.resolve();
  },
};

// Add storage configuration to Auth
config.Auth = {
  ...config.Auth,
  localStorage: amplifyStorageOverwrite,
};
Amplify.configure(config)

Tanstack query allows this: https://tanstack.com/query/v5/docs/framework/react/plugins/persistQueryClient#building-a-persister

Expected behavior

Ideally you could just overwrite the get, set, and clear, etc functions to write to mmkv instead, and open up the flexibility away from react-native-async-storage.

I did notice some examples on the React docs on how to do this using different storage mechanisms: https://docs.amplify.aws/gen1/react/build-a-backend/auth/manage-user-session/#understand-token-management-options

Reproduction steps

N/A

Code Snippet

N/A

Log output

N/A

aws-exports.js

N/A

Manual configuration

N/A

Additional configuration

N/A

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

ChristopherGabba avatar Aug 30 '25 17:08 ChristopherGabba

Hi @ChristopherGabba ,

Thank you for this feature request! We love hearing ideas from the community on how to improve our library. We will review it with the team and get back to you once we have an update.

osama-rizk avatar Sep 01 '25 12:09 osama-rizk

Thanks @osama-rizk, I could say something very similar with the other react native dependency of Amplify (@react-native-community/net-info). I use Expo-network in my app and I can't get rid of this net-info dependency that effectively does the same thing.

Tanstack handles this by creating an OnlineManager. Getting rid of these dependencies would benefit amplify greatly.

ChristopherGabba avatar Sep 01 '25 12:09 ChristopherGabba

Tanstack handles this by creating an OnlineManager. Getting rid of these dependencies would benefit amplify greatly.

Thank you for this valuable feedback. You raise an excellent point about TanStack's OnlineManager . I'll share your suggestion with our team to explore how we might implement that.

osama-rizk avatar Sep 01 '25 15:09 osama-rizk