Storage Layer

Nitro provides a built-in storage layer that can abstract filesystem or database or any other data source.

useStorage() is an instance of createStorage using the memory driver.

Example: Simple (in memory) operations

await useStorage().setItem('test:foo', { hello: 'world' })await useStorage().getItem('test:foo')// You can also specify the base in useStorage(base)await useStorage('test').setItem('foo', { hello: 'world' })await useStorage('test').getItem('foo')

See Unstorage for detailed usage.

Mountpoints

You can mount storage drivers using the storage option:

nitro.config.ts
export default defineNitroConfig({  storage: {    'redis': {      driver: 'redis',      /* redis connector options */    },    'db': {      driver: 'fs',      base: './data/db'    }  }})
nuxt.config.ts
export default defineNuxtConfig({  nitro: {    storage: {      redis: {        driver: 'redis',        /* redis connector options */      },      db: {        driver: 'fs',        base: './.data/db'      }    }  }})

Runtime configuration

In scenarios where the mount point configuration is not known until runtime, Nitro can dynamically add mount points during startup using plugins:

This is a temporary workaround, with a better solution coming in the future! Keep a lookout on the GitHub issue here.
plugins/storage.ts
import redisDriver from 'unstorage/drivers/redis'export default defineNitroPlugin(() => {  const storage = useStorage()  // Dynamically pass in credentials from runtime configuration, or other sources  const driver = redisDriver({      base: 'redis',      host: useRuntimeConfig().redis.host,      port: useRuntimeConfig().redis.port,      /* other redis connector options */    })  // Mount driver  storage.mount('redis', driver)})
nitro.config.ts
export default defineNitroConfig({  runtimeConfig: {    redis: { // Default values      host: '',      port: 0,      /* other redis connector options */    }  }})
nuxt.config.ts
export default defineNuxtConfig({  runtimeConfig: {    redis: { // Default values      host: '',      port: 0,      /* other redis connector options */    }  }})

Usage:

await useStorage('redis').setItem('foo', { hello: 'world' })await useStorage('redis').getItem('foo')// orawait useStorage().setItem('redis:foo', { hello: 'world' })await useStorage().getItem('redis:foo')

Usage with generics:

await useStorage().getItem<string>('foo')// => stringawait useStorage<string>().getItem('foo')// => stringawait useStorage<string>().setItem('foo', 123) // ts errortype Foo = { data: number }await useStorage().getItem<Foo>('foo')// => Foo

You can find the list of drivers on unstorage documentation.

In development, Nitro adds the cache mountpoint using the FS driver writting to .nitro/cache or .nuxt/cache if using Nuxt.

await useStorage('cache').setItem('foo', { hello: 'world' })await useStorage('cache').getItem('foo')

Development storage

You can use the devStorage key to overwrite the storage configuration during development, very useful when you use a database in production and want to use the filesystem in development.

nitro.config.ts
export default defineNitroConfig({  // Production  storage: {    db: {      driver: 'redis',      /* redis connector options */    }  },  // Development  devStorage: {    db: {      driver: 'fs',      base: './data/db'    }  }})
nuxt.config.ts
export default defineNuxtConfig({  nitro: {    // Production    storage: {      db: {        driver: 'redis',        /* redis connector options */      }    },    // Development    devStorage: {      db: {        driver: 'fs',        base: './data/db'      }    }  }})