Skip to main content

Installation

This guide covers installing and configuring the Medusa JavaScript SDK in your application.

Prerequisites

  • Node.js 20 or higher
  • A Medusa backend instance running (local or hosted)
  • Package manager: npm, yarn, or pnpm

Install the SDK

Install the @medusajs/js-sdk package using your preferred package manager:
npm install @medusajs/js-sdk

Basic Initialization

Storefront Usage

For customer-facing applications, initialize the SDK with your backend URL and publishable API key:
import Medusa from "@medusajs/js-sdk"

const sdk = new Medusa({
  baseUrl: "http://localhost:9000", // Your Medusa backend URL
  publishableKey: "pk_01234567890abcdef" // Your publishable API key
})

export default sdk

Admin Usage

For administrative applications, use an API key for authentication:
import Medusa from "@medusajs/js-sdk"

const sdk = new Medusa({
  baseUrl: "http://localhost:9000",
  apiKey: "sk_01234567890abcdef" // Your secret API key
})

export default sdk
Never expose admin API keys in client-side code. Use environment variables and keep them server-side only.

Configuration Options

The SDK accepts a Config object with the following options:

Required Options

baseUrl
string
required
The base URL of your Medusa backend API. In browser environments, you can use / or an empty string to use the current origin.
baseUrl: "https://api.example.com"

Authentication Options

publishableKey
string
The publishable API key for storefront requests. Required for store API access.
publishableKey: "pk_01234567890abcdef"
apiKey
string
The secret API key for admin requests. Use only in server-side environments.
apiKey: "sk_01234567890abcdef"
auth
object
Advanced authentication configuration.

Request Options

globalHeaders
ClientHeaders
Headers to include in all requests.
globalHeaders: {
  "x-custom-header": "value",
  "cache-control": {
    tags: ["all-requests"] // Next.js cache tags
  }
}

Debugging Options

debug
boolean
default:"false"
Enable debug logging to console.
debug: process.env.NODE_ENV === "development"
logger
Logger
Custom logger implementation.
logger: {
  error: (...messages: string[]) => void,
  warn: (...messages: string[]) => void,
  info: (...messages: string[]) => void,
  debug: (...messages: string[]) => void
}

Common Setup Examples

React Application

Create a dedicated SDK instance file:
src/lib/medusa.ts
import Medusa from "@medusajs/js-sdk"

const sdk = new Medusa({
  baseUrl: process.env.NEXT_PUBLIC_MEDUSA_API_URL || "http://localhost:9000",
  publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
  debug: process.env.NODE_ENV === "development"
})

export default sdk
Use in components:
src/components/ProductList.tsx
import { useEffect, useState } from "react"
import sdk from "@/lib/medusa"
import type { HttpTypes } from "@medusajs/types"

export function ProductList() {
  const [products, setProducts] = useState<HttpTypes.StoreProduct[]>([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    sdk.store.product.list()
      .then(({ products }) => setProducts(products))
      .finally(() => setLoading(false))
  }, [])

  if (loading) return <div>Loading...</div>

  return (
    <div>
      {products.map((product) => (
        <div key={product.id}>{product.title}</div>
      ))}
    </div>
  )
}

Next.js Application

Client Components

src/lib/sdk/client.ts
import Medusa from "@medusajs/js-sdk"

export const sdk = new Medusa({
  baseUrl: process.env.NEXT_PUBLIC_MEDUSA_API_URL!,
  publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
  auth: {
    type: "session",
    fetchCredentials: "include"
  }
})

Server Components

src/lib/sdk/server.ts
import Medusa from "@medusajs/js-sdk"

export async function getServerSDK() {
  return new Medusa({
    baseUrl: process.env.MEDUSA_API_URL!,
    publishableKey: process.env.MEDUSA_PUBLISHABLE_KEY
  })
}
Use in server components:
app/products/page.tsx
import { getServerSDK } from "@/lib/sdk/server"

export default async function ProductsPage() {
  const sdk = await getServerSDK()
  const { products } = await sdk.store.product.list({
    fields: "id,title,thumbnail"
  })

  return (
    <div>
      {products.map((product) => (
        <div key={product.id}>{product.title}</div>
      ))}
    </div>
  )
}

React Native Application

Use AsyncStorage for token persistence:
src/lib/medusa.ts
import Medusa from "@medusajs/js-sdk"
import AsyncStorage from '@react-native-async-storage/async-storage'

const sdk = new Medusa({
  baseUrl: "https://api.example.com",
  publishableKey: "pk_...",
  auth: {
    type: "jwt",
    jwtTokenStorageMethod: "custom",
    jwtTokenStorageKey: "medusa_token",
    storage: {
      getItem: async (key) => {
        return await AsyncStorage.getItem(key)
      },
      setItem: async (key, value) => {
        await AsyncStorage.setItem(key, value)
      },
      removeItem: async (key) => {
        await AsyncStorage.removeItem(key)
      }
    }
  }
})

export default sdk

Node.js/Express Backend

Use API key authentication:
src/lib/medusa.ts
import Medusa from "@medusajs/js-sdk"

const sdk = new Medusa({
  baseUrl: process.env.MEDUSA_API_URL || "http://localhost:9000",
  apiKey: process.env.MEDUSA_API_KEY
})

export default sdk

Vanilla JavaScript

Use via CDN or bundler:
<!DOCTYPE html>
<html>
<head>
  <title>Medusa Store</title>
</head>
<body>
  <div id="products"></div>

  <script type="module">
    import Medusa from "@medusajs/js-sdk"

    const sdk = new Medusa({
      baseUrl: "http://localhost:9000",
      publishableKey: "pk_..."
    })

    async function loadProducts() {
      const { products } = await sdk.store.product.list()
      const container = document.getElementById("products")
      
      products.forEach(product => {
        const div = document.createElement("div")
        div.textContent = product.title
        container.appendChild(div)
      })
    }

    loadProducts()
  </script>
</body>
</html>

Environment Variables

Store your configuration in environment variables:
.env.local
# Medusa API Configuration
NEXT_PUBLIC_MEDUSA_API_URL=http://localhost:9000
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_01234567890abcdef

# Admin API Key (server-side only)
MEDUSA_API_KEY=sk_01234567890abcdef
Always prefix client-side environment variables with NEXT_PUBLIC_ (Next.js) or your framework’s convention. Never expose admin API keys in client-side code.

Verify Installation

Test your SDK setup:
import sdk from "./lib/medusa"

async function testConnection() {
  try {
    const { regions } = await sdk.store.region.list()
    console.log("Connected! Found", regions.length, "regions")
  } catch (error) {
    console.error("Failed to connect:", error)
  }
}

testConnection()

Next Steps

SDK Methods

Learn about available methods and how to use the client

API Authentication

Implement user authentication and session management

Build docs developers (and LLMs) love