diff --git a/docs/content/development/backend/prepare-environment.mdx b/docs/content/development/backend/prepare-environment.mdx
index be696beb34..9c78534b34 100644
--- a/docs/content/development/backend/prepare-environment.mdx
+++ b/docs/content/development/backend/prepare-environment.mdx
@@ -191,25 +191,6 @@ For other distributions, you can check out [PostgreSQL’s website for more guid
You can download PostgreSQL on your macOS using [the installer on their website](https://www.postgresql.org/download/macosx/).
-
-
-
-Make sure the Docker Desktop app is running, then run the following command to quickly spin up a PostgreSQL instance:
-
-```bash
-docker run --name postgres -e POSTGRES_USER=postgres \
- -e POSTGRES_PASSWORD=postgres -e \
- POSTGRES_DB=medusa-docker -p 5432:5432 -d postgres
-```
-
-Where:
-
-- `--name` creates a new container named `postgres`.
-- `-e` creates environment variables `POSTGRES_USER`, `POSTGRES_PASSWORD` and `POSTGRES_DB`. These will be used to set up a database named `medusa-docker` with the username and password being `postgres`.
-- `-p` maps the container port `5432` to the external host `5432`. This allows you to connect to the database backend from outside of the container.
-- `-d` enables Docker to run the container in the background.
-- The last section of the command, `postgres` grabs the latest postgres image from the Docker hub.
-
diff --git a/docs/content/modules/products/admin/manage-products.mdx b/docs/content/modules/products/admin/manage-products.mdx
new file mode 100644
index 0000000000..c399c3b740
--- /dev/null
+++ b/docs/content/modules/products/admin/manage-products.mdx
@@ -0,0 +1,1169 @@
+---
+description: 'Learn how to manage products using the admin APIs. Learn how to create, update, and delete products, and how to manage their options and variants.'
+addHowToData: true
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# How to Manage Products
+
+In this document, you’ll learn how to manage products using the admin APIs.
+
+## Overview
+
+Using the admin APIs, you can manage products, their options, and their variants.
+
+### Scenario
+
+You want to add or use the following admin functionalities:
+
+- Manage products. This includes listing, adding, updating, and deleting products.
+- Manage product options. This includes adding, updating, or deleting options.
+- Manage product variants. This includes listing, adding, updating, or deleting variants.
+
+---
+
+## Prerequisites
+
+### Medusa Components
+
+It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../../development/backend/install.mdx) to get started.
+
+### JS Client
+
+This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
+
+If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../../js-client/overview.md) installed and have [created an instance of the client](../../../js-client/overview.md#configuration).
+
+### Medusa React
+
+This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
+
+If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
+
+### Authenticated Admin User
+
+You must be an authenticated admin user before following along with the steps in the tutorial.
+
+You can learn more about [authenticating as an admin user in the API reference](/api/admin/#section/Authentication).
+
+---
+
+## List Products
+
+You can list products as an admin using the [List Products endpoint](/api/admin#tag/Products/operation/GetProducts):
+
+
+
+
+```ts
+medusa.admin.products.list()
+.then(({ products, limit, offset, count }) => {
+ console.log(products.length)
+})
+```
+
+
+
+
+```tsx
+import { useAdminProducts } from "medusa-react"
+
+const Products = () => {
+ const { products, isLoading } = useAdminProducts()
+
+ return (
+
+ )
+}
+
+export default Products
+```
+
+
+
+
+```ts
+fetch(`/admin/products`, {
+ credentials: "include",
+})
+.then((response) => response.json())
+.then(({ products, limit, offset, count }) => {
+ console.log(products.length)
+})
+```
+
+
+
+
+```bash
+curl -L -X GET '/admin/products' \
+-H 'Authorization: Bearer '
+```
+
+
+
+
+This endpoint does not require any parameters. You can pass parameters to search and filter through the retrieved products. For example, you can pass the `q` parameter which searches through product titles, descriptions, and more. You can learn more about available parameters in the [API reference](/api/admin#tag/Products/operation/GetProducts).
+
+You can also specify which fields to returns or which relations to expand using the `fields` and `expand` query parameters. You can learn more about them in the [API reference](/api/admin#section/Expanding-Fields).
+
+The request returns an array of products along with [pagination parameters](/api/admin#section/Pagination).
+
+---
+
+## Create a Product
+
+You can create a product by sending a request to the [Create a Product endpoint](https://docs.medusajs.com/api/admin#tag/Products/operation/PostProducts):
+
+
+
+
+```ts
+medusa.admin.products.create({
+ title: "Shirt",
+ is_giftcard: false,
+ discountable: true,
+ options: [
+ {
+ title: "Color",
+ },
+ {
+ title: "Size",
+ },
+ ],
+ variants: [
+ {
+ title: "White Small Shirt",
+ prices: [
+ {
+ amount: 1000,
+ currency_code,
+ },
+ ],
+ options: [
+ {
+ value: "White",
+ },
+ {
+ value: "Small",
+ },
+ ],
+ },
+ ],
+ collection_id,
+ categories: [
+ {
+ id: categoryId,
+ },
+ ],
+ type: {
+ value: typeValue,
+ },
+ tags: [
+ {
+ value: tagValue,
+ },
+ ],
+})
+.then(({ product }) => {
+ console.log(product.id)
+})
+```
+
+
+
+
+```tsx
+import { useAdminCreateProduct } from "medusa-react"
+
+const CreateProduct = () => {
+ const createProduct = useAdminCreateProduct()
+ // ...
+
+ const handleCreate = () => {
+ createProduct.mutate({
+ title: "Shirt",
+ is_giftcard: false,
+ discountable: true,
+ options: [
+ {
+ title: "Color",
+ },
+ {
+ title: "Size",
+ },
+ ],
+ variants: [
+ {
+ title: "White Small Shirt",
+ prices: [
+ {
+ amount: 1000,
+ currency_code,
+ },
+ ],
+ options: [
+ {
+ value: "White",
+ },
+ {
+ value: "Small",
+ },
+ ],
+ },
+ ],
+ collection_id,
+ categories: [
+ {
+ id: categoryId,
+ },
+ ],
+ type: {
+ value: typeValue,
+ },
+ tags: [
+ {
+ value: tagValue,
+ },
+ ],
+ })
+ }
+
+ // ...
+}
+
+export default CreateProduct
+```
+
+
+
+
+```ts
+fetch(`/admin/products`, {
+ credentials: "include",
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ title: "Shirt",
+ options: [
+ {
+ title: "Color",
+ },
+ {
+ title: "Size",
+ },
+ ],
+ variants: [
+ {
+ title: "White Small Shirt",
+ prices: [
+ {
+ amount: 1000,
+ currency_code,
+ },
+ ],
+ options: [
+ {
+ value: "White",
+ },
+ {
+ value: "Small",
+ },
+ ],
+ },
+ ],
+ collection_id,
+ categories: [
+ {
+ id: categoryId,
+ },
+ ],
+ type: {
+ value: typeValue,
+ },
+ tags: [
+ {
+ value: tagValue,
+ },
+ ],
+ }),
+})
+.then((response) => response.json())
+.then(({ product }) => {
+ console.log(product.id)
+})
+```
+
+
+
+
+```bash
+curl -L -X POST '/admin/products' \
+-H 'Authorization: Bearer ' \
+-H 'Content-Type: application/json' \
+--data-raw '{
+ "title": "Shirt 2",
+ "options": [
+ {
+ "title": "Color"
+ },
+ {
+ "title": "Size"
+ }
+ ],
+ "variants": [
+ {
+ "title": "White Shirt",
+ "prices": [
+ {
+ "amount": 1000,
+ "currency_code": "USD"
+ }
+ ],
+ "options": [
+ {
+ "value": "White"
+ },
+ {
+ "value": "Small"
+ }
+ ]
+ }
+ ],
+
+ "collection_id": "",
+ "categories": [
+ {
+ "id": ""
+ }
+ ],
+ "type": {
+ "value": ""
+ },
+ "tags": [
+ {
+ "value": ""
+ }
+ ]
+}'
+```
+
+
+
+
+This endpoint only requires the `title` body parameter, which is the name of the product. Other parameters passed in the example are optional. They are:
+
+- `is_giftcard`: a boolean value that determines whether a product is a gift card. By default, it’s `false`.
+- `is_discountable`: a boolean value that determines whether discounts can be applied on the product. By default, it’s `true`.
+- `options`: an array of objects, each object has the required property `title`. This only defines the option names and not their values, as their values are defined within the product variant. The array length must be the same as that of the values passed for each variant.
+- `variants`: an array of objects, each object has the required properties `title` and `prices`:
+ - `title` is a string indicating the name of the variant.
+ - `prices` is an array of objects, each indicating the different prices of the product variant. You can specify prices for different contexts, such as a price for different currencies or regions. You can learn more about possible properties to pass in a price object in the API reference.
+ - `options` is an array of objects, each object requires the `value` property. `value` is a string indicating the value of the option. Each object within this array is matched with the object of the product’s `options` array at the same index. So, in the example above, the “White” value is matched with the “Color” option, and the “Small” value is matched with the “Size” option.
+- `collection_id`: an optional ID of the collection to associate the product with.
+- `categories`: an optional array of product category IDs to associate the product with.
+- `type`: an optional object that holds a value of the type to associate the product with. If you don’t pass an ID in the object, a new product type will be created. Otherwise, the product will be associated with an existing product type.
+- `tags`: an optional array of objects, each object requires the `value` property. If you don’t pass an ID in an object, a new product tag will be created. Otherwise, the product will be associated with an existing product tag.
+
+You can learn about other available parameters in the [API reference](https://docs.medusajs.com/api/admin#tag/Products/operation/PostProducts).
+
+The request returns the created product as an object.
+
+### Product Handle
+
+If you don’t pass the `handle` body parameter, the handle of the product will be automatically set to the slug version of the `title` parameter.
+
+### Product Variant Prices
+
+It’s recommended to set the prices of product variants as the actual amount multiplied by a hundred. This behavior is implemented within the Medusa admin, and the Next.js storefront divides all prices by a hundred before displaying the price.
+
+So, in the example above, if the `amount` is set to `1000`, it means the price is actually `10`.
+
+---
+
+## Retrieve a Product
+
+You can retrieve a single product as an admin by sending a request to the [Get a Product endpoint](https://docs.medusajs.com/api/admin#tag/Products/operation/GetProductsProduct):
+
+
+
+
+```ts
+medusa.admin.products.retrieve(productId)
+.then(({ product }) => {
+ console.log(product.id)
+})
+```
+
+
+
+
+```tsx
+import { useAdminProduct } from "medusa-react"
+
+const Product = () => {
+ const {
+ product,
+ isLoading,
+ } = useAdminProduct(productId)
+
+ return (
+