Set Up a Storefront on Medusa.js in Under an Hour

by Emma Rodriguez
Set Up a Storefront on Medusa.js in Under an Hour

You're staring at your Shopify bill — $79, $105, maybe $299 a month — and doing the math on what that adds up to over a year. Or maybe you've outgrown a hosted platform's checkout rules and you just want control without hiring a full engineering team. Either way, you've probably heard the word "headless" thrown around and quietly wondered if it's only for companies with a dedicated dev budget.

It's not. And Medusa.js is one of the clearest proofs of that.

Medusa is a free, open-source commerce engine you host yourself. Think of it as the brains of your store — handling products, orders, customers, and payments — while you bolt on whatever front-end you like. The project has grown to over 23,000 GitHub stars, and a solo operator with basic terminal comfort can get a working storefront running in under 60 minutes. This tutorial walks you through exactly that.

Why Medusa Makes Sense for Small Stores

Before you touch a single command, it's worth knowing what you're trading and what you're gaining.

What you give up: A fully managed hosting environment and one-click installs. You'll need a server (a $6/month DigitalOcean droplet works fine to start) and a little comfort with the command line.

What you gain: Zero platform fees on revenue, full ownership of your data, and the ability to customize checkout, pricing logic, or fulfillment flows without waiting for a plugin that may never exist.

For a store doing $8,000–$15,000 a month, switching from a mid-tier Shopify plan to a self-hosted Medusa setup can realistically save $900–$2,400 a year in platform costs alone — before you factor in app subscriptions.

Medusa's architecture has three main pieces:

  • The backend — a Node.js API that manages your commerce logic
  • The admin dashboard — a React app for managing products, orders, and settings
  • The storefront — whatever front-end you build or clone (Next.js is the most common choice)

You can run all three locally first, then push to a server when you're ready. That's exactly what we'll do.

What You Need Before You Start

This isn't a zero-prerequisites setup, but the bar is lower than most tutorials admit. Here's what you actually need:

  • Node.js 18+ installed on your machine (run node -v to check)
  • PostgreSQL running locally — the Postgres.app is the easiest path on Mac; on Windows, the official installer works fine
  • Git and a basic familiarity with your terminal
  • About 60–90 minutes of focused time

If you've ever cloned a GitHub repo and run npm install, you're qualified. Seriously.

One thing worth doing first: create a fresh PostgreSQL database called medusa_db. Open your terminal and run:

createdb medusa_db

Keep that database name handy — you'll need it in the next step.

Installing and Configuring the Medusa Backend

Medusa provides a CLI tool that scaffolds your backend in one command. Run this:

npx create-medusa-app@latest my-medusa-store

The CLI will ask a few questions. When it asks about the database, enter your connection string in this format:

postgres://localhost/medusa_db

It will also ask if you want to install the Next.js starter storefront at the same time. Say yes — it saves you a separate setup step.

Once the install finishes (usually 3–5 minutes depending on your connection), you'll have two folders: my-medusa-store for the backend and my-medusa-store-storefront for the front-end.

Now open my-medusa-store/.env and double-check these three variables:

DATABASE_URL=postgres://localhost/medusa_db
JWT_SECRET=your_random_secret_here
COOKIE_SECRET=another_random_secret_here

For the secrets, just mash your keyboard — any long random string works for local development. In production you'll want something generated properly (a password manager's random generator is fine).

Start the backend:

cd my-medusa-store
npm run dev

You should see the server start on port 9000. Open http://localhost:9000/health in your browser — if you see {"status":"ok"}, you're in business.

Setting Up the Admin and Adding Your First Product

The admin dashboard runs separately. Open a new terminal tab, navigate to your backend folder, and run:

npx medusa user -e you@youremail.com -p yourpassword

This creates your admin account. Then visit http://localhost:7001 — that's the admin UI. Log in with the credentials you just created.

Here's where it starts feeling like a real store. Click Products → New Product and add something simple: a name, a description, a price, and a thumbnail image. Don't overthink it — you can always edit later. The point right now is to have at least one product so your storefront has something to display.

While you're in the admin, head to Settings → Regions and make sure you have at least one region configured with a currency. The default setup usually includes a US region, but double-check that a payment provider is attached. For testing, Medusa ships with a "fake" payment provider that lets you complete orders without real card details — perfect for confirming everything works before you wire up Stripe.

Do you have a product saved and a region set? Good. That's genuinely most of the backend work done.

Launching the Next.js Storefront

Open a third terminal tab and navigate to your storefront folder:

cd my-medusa-store-storefront

Copy the example environment file:

cp .env.template .env.local

Open .env.local and confirm this line is present:

NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://localhost:9000

Then install dependencies and start the dev server:

npm install
npm run dev

Visit http://localhost:8000. You should see the Medusa starter storefront — a clean, minimal shop with your product already listed. Click through to the product page, add it to the cart, and run a test checkout using the fake payment provider.

If the cart works and the order shows up in your admin dashboard under Orders, congratulations — you have a functioning headless store. That whole process, start to finish, is usually under 45 minutes once you've done it once.

Three Things to Do Before You Go Live

A working local setup is a milestone, not a finish line. Here are the three moves that matter most before pointing real traffic at your store.

1. Swap in a real payment provider. Medusa has official plugins for Stripe, PayPal, and Klarna. Stripe is the most straightforward. Install the plugin (@medusajs/medusa-payment-stripe), add your Stripe secret key to .env, and enable it in your region settings inside the admin. The Stripe plugin handles webhooks automatically, which saves you a headache.

2. Set up file storage for product images. By default, Medusa stores uploaded images locally, which breaks the moment you deploy to a server that doesn't persist files. The @medusajs/file-minio plugin (for self-hosted S3-compatible storage) or the AWS S3 plugin are both solid options. If you already have an AWS account, the S3 plugin takes about 15 minutes to configure.

3. Deploy backend and storefront separately. A common beginner mistake is trying to run everything on one tiny server. Your Medusa backend and your Next.js storefront have different resource profiles. A good split: deploy the backend to a $12/month DigitalOcean droplet or a Railway starter plan, and deploy the Next.js storefront to Vercel's free tier. Vercel's edge network will make your storefront fast globally at zero cost while your backend handles the commerce logic from a stable server.

A Quick Real-World Example

A candle maker I know was paying $79/month for Shopify Basic plus $29/month for a subscription app and $19/month for a custom form builder — $127 total. Her store did about $6,000 a month in revenue, so platform costs were eating 2.1% of gross before payment processing fees.

She migrated to Medusa with a Next.js storefront hosted on Vercel (free) and a $12/month DigitalOcean droplet for the backend. She built the subscription logic herself using Medusa's custom endpoints — it took one weekend and a YouTube tutorial on Node.js routes. Her monthly infrastructure cost dropped to $12. That's $1,380 saved in year one, which she reinvested in paid ads.

Her store isn't technically flashier than before. It's just cheaper to run and she owns every piece of it.

You're More Ready Than You Think

Headless commerce sounds intimidating, but Medusa.js has done a lot of the heavy lifting. The CLI, the starter storefront, the admin UI — these exist precisely so you don't have to build a commerce engine from scratch. You're assembling proven pieces, not inventing anything.

If you got through this tutorial and your local store is running, your next step is straightforward: deploy the backend to a real server this week. Railway has a free trial that's generous enough to test with real traffic before you commit to a paid plan. Get it live, run a few real test orders, and you'll have the confidence to migrate your actual catalog.

You've already done the hard part — you showed up and tried something new. The rest is just following steps you now know how to follow.