docs: adds tutorial (#323)

* docs: adds installation guide for tutorial

* docs: adds creating your medusa server guide

* add quick starter

* rename to reflect docker usage

* docs: adds custom functionality tutorial

* docs: adds linking with medusa cloud

* fix: PR

Co-authored-by: olivermrbl <oliver@mrbltech.com>
This commit is contained in:
Sebastian Rindom
2021-07-25 09:58:16 +02:00
committed by GitHub
parent 06fd882a67
commit 804a2f6ed9
6 changed files with 543 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
# Quick Start w. Docker
This quick start is intended for developers, that have already configured their local development environment and familiarised them selves with all the technologies and frameworks used throughout the Medusa eco-system.
If this is not the case, please head over to our Getting Started tutorial for a thorough walkthrough.
## Introduction
With all the tools and technologies in place, let's get started by setting up a default project. Our starter is shipped with a very basic configuration, that includes the following plugins:
- Stripe as payment provider
- SendGrid as email notification provider
- Manual fulfilment as fulfilment provider
Additionally, we will spin up a PostgreSQL database and a Redis server, both required for Medusa to run. In this quick start, we will use docker to seamlessly set up these resources.
## Get started
1. Clone our starter project from Github
```bash
git clone https://github.com/medusajs/medusa-starter-default.git my-medusa-starter
```
2. Once cloned, we will jump into our project directory and get started with our configuration.
```bash
cd my-medusa-starter
```
3. Get your environment variables ready using our template
```bash
mv .env.template .env
```
4. Setup accounts for included plugins. This step is optional but required for placing orders.
Create a Stripe account and add your API key and webhook secret to `.env`
Create a SendGrid account and add your API key to `.env`
```bash
...
STRIPE_API_KEY="some_stripe_key"
STRIPE_WEBHOOK_SECRET="some_webhook_secret"
SENDGRID_API_KEY="some_sendgrid_key"
..
```
5. Start your server
```bash
docker-compose up --build
```
We will use docker-compose and Docker to start up our development environment. Running the above command will do the following:
1. Build images for our Medusa project, a PostgreSQL database and a Redis server
2. Run migrations for our newly created database
3. Seed our database with some entities, that will allow us to easily get started.
These include:
- A user with email `admin@medusa-test.com` and password `supersecret`
- A region called Default Region with a small subset of countries
- A shipping option called Standard Shipping, that costs 10 EUR
- A product called Cool Test Product
- A variant of that product that costs 195 EUR
Once done, our server will be accessible at `http://localhost:9000`.
## Try it out
Let's try out our Medusa server by fetching some products.
```bash
curl -X GET localhost:9000/store/products | python -m json.tool
```
## What's next?
Add custom endpoint to your Medusa project
Install and configure additional plugins
Build a storefront using our [Gatsby Starter](https://github.com/medusajs/gatsby-starter-medusa)

View File

@@ -0,0 +1,235 @@
# Adding custom functionality
## Introduction
In the previous part of the tutorial we set up your Medusa project using the `medusa new` and started your Medusa server locally. In this part we will start adding some custom functionality that extends the core. In particular this tutorial will take you through adding custom serverices, custom endpoints and subscribers. The custom functionality that we will be adding will create an endpoint called `/welcome/:cart_id` which customers of your store can use to opt-in to receiving a welcome in their email inbox after completing their order.
The custom functionality will do a number of things:
- Create a custom service that handles the logic around opting in. The service will ensure that only first time buyers will receive a welcome.
- Create a custom endpoint at `/welcome/:cart_id` which will take a `optin` parameter as part of its request body, and call our custom service.
- Create a subscriber that listens for the `order.placed` event and tells the custom service to send a welcome.
## Services
We will begin our custom implementation by adding a custom service. In you project create a new file at `/src/services/welcome.js`. Open the newly created file and add a class:
```javascript
import { BaseService } from "medusa-interfaces"
class WelcomeService extends BaseService {
constructor({}) {
super()
}
async registerOptin(cartId, optin) {}
async sendWelcome(orderId) {}
}
export default WelcomeService
```
We will be filling out each of the methods in turn, but before we get to that it should be noted that placing files in `/src/services` has a special meaning in Medusa projects. When Medusa starts up it will look for files in this folder and register exports from these files to the global container. The global container holds all services and repositories in your Medusa project allowing for dependency injection. Dependency injection is a software development technique in which objects only receive other objects that it depends upon.
### `constructor`
We will see dependency injection in action now when implementing the constructor:
```javascript
constructor({ cartService, orderService }) {
super()
this.cartService_ = cartService
this.orderService_ = orderService
}
```
In the constructor we specify that our `WelcomeService` will depend upon the `cartService` and `orderService` and Medusa will make sure to provide those as the first argument to the constructor when starting up Medusa. We then keep a reference to these services within the `WelcomeService` so that we can use them later on.
> Note: Just like we can depend on the `cartService` and `orderService` other services will be able to depend on our newly created `WelcomeService`. The registration name of our service is the camelCased version of our file name with the registration type appended. I.e. `/src/services/welcome.js` -> `welcomeService`.
### `registerOptin`
The `registerOption` function will take to arguments: `cartId` and `optin`, where `cartId` holds the id of the cart that we wish to register optin for and `optin` is a boolean to indicate if the customer has accepted or optin or not. We will save the `optin` preferences in the cart's `metadata` field, so that it can be persisted for the future when we need to evaluate if we should send the welcome or not.
```javascript
async registerOptin(cartId, optin) {
if (typeof optin !== "boolean") {
throw new Error("optin must be a boolean value.")
}
return await this.cartService_.update(cartId, {
metadata: { welcome_optin: optin }
})
}
```
The `registerOptin` implementation simply validates that the provided argument is of the correct type and calls the CartService function `update`. `update` takes two arguments: the first is the id of the cart to update and the second is an object that with the key/value pairs that we want to update. In this case we are updating the metadata on the cart. The `metadata` field on the cart is itself an object so we need to pass an object when updating this field.
> Note: Most entities in Medusa have a `metadata` field that can be used for customizations or integrations when it is necessary to persist some data relating to the entity. Metadata cannot be overridden by other plugins.
### `sendWelcome`
The final function to implement in our class is the `sendWelcome` function that takes one argument `orderId` which holds the id of an order that we will evaluate whether to send a welcome for. In the implementation we leverage that when an order is created from a cart all the cart's metadata is copied to the order. We can therefore check `metadata.welcome_optin` to evaluate if the customer has allowed us to send a welcome to their email.
```javascript
async sendWelcome(orderId) {
const order = await this.orderService_.retrieve(orderId, {
select: ["email", "customer_id", "metadata"]
})
const prevOrders = await this.orderService_.list({
customer_id: order.customer_id
}, {
select: ["id"]
})
if (prevOrders.length > 0) {
// We only send welcomes to new customers. This customer
// has already completed an order before so we can stop.
return
}
if (order.metadata && order.metadata.welcome_optin) {
// Customer opted in so we should send an email
return await someEmailSender.send({
to: order.email,
subject: "Welcome to our Medusa Store!",
body: `We are so happy to have you!`
})
}
}
```
In the above implementation we are first retrieving the order that we need to check if we should send a welcome for. We are selecting only the fields that we need. In this case the `email` on the order, we will use this if we need to send out the welcome email, the `customer_id` which is used to determine if the customer has completed prior orders and `metadata` to check if the customer opted in to receiving the welcome email.
After retrieving the order we list all orders that have the same `customer_id` as the order we just retrieved. We are only interested in the count of these orders so it is sufficient for us to just select the ids of these orders.
We then check if the number of previous orders is 0, indicating that the customer has not previously purchased anything from our store. If the number of previous orders is greater than 0 we can exit our function prematurely as we only send welcomes to new customers.
The final part of the implementation checks if the `welcome_optin` metadata has been set to true. If the customer has opted in we use `someEmailService.send` to trigger and email dispatch to the email stored on the order. In this case `someEmailSender` could be any email service for example Sendgrid, SES, Mailgun, etc.
> Note: If you have `medusa-plugin-sendgrid` installed you can use `sendgridService` in your constructor to use it later in `sendWelcome`. You will then be able to do `sendgridService.send({ ... })`.
We have completed the implementation of our custom service and we will now be able to call it from elsewhere in our project.
## Endpoints
Similarly to the `/src/services` directory, the `/src/api` directory has a special meaning in Medusa. Exports from this directory are assumed to be functions that return an express router instance that will be registered on the internal express app that Medusa creates when starting your server. This allows you to create custom endpoints for custom functionality. We will use this to create the custom endpoint that customers can use to give there welcome opt-in.
Create a new file at `/src/api/index.js` and add the following controller:
```javascript
import { Router } from "express"
import bodyParser from "body-parser"
export default () => {
const app = Router()
app.post("/welcome/:cart_id", bodyParser.json(), async (req, res) => {
// TODO
})
return app
}
```
### Controller implementation
Our endpoint controller's implementation will be very simple. It will extract the `id` from the path paramater and the `optin` flag from the request body. We will then use these values to call our the `WelcomeService`, which will take care of updating the cart metadata for later.
```javascript
app.post("/welcome/:cart_id", bodyParser.json(), async (req, res) => {
const { cart_id } = req.params
const { optin } = req.body
// Validate that the optin value was provided.
// If not respond with a Bad Request status
if (typeof optin !== "boolean") {
res.status(400).json({
message: "You must provide an boolean optin value in the request body"
})
return
}
const welcomeService = req.scope.resolve("welcomeService")
try {
await welcomeService.registerOptin(id, optin)
res.status(200).json({
success: true
})
} catch (err) {
// This is not supposed to happen.
res.status(500).json({
message: "Something unexpected happened."
})
}
})
```
In the implementation above we are first validating that the request body is structured correctly so that we can proceed with our opt-in registration. If the validation fails we respond with 400 Bad Request which is an HTTP code that indicates that the client that sent the request has not provided the correct values.
After validation is passed we leverage Medusa's container system again to fetch our custom service. When Medusa starts up it places an object on the express `req` object called `scope` which contains the function `resolve` that can be used to get any of the services registered in Medusa by simply providing the registration name as a string. In this case we are resolving our custom `welcomeService`, but you can resolve any service such as the `cartService` or `orderService` using this function.
We put our `registerOptin` function call in a try-catch block to ensure that we can handle unexpected errors. If the call to `registerOptin` succeeds we respond with 200 OK and if for some reason we encounter an error we respond with 500 Internal Server Error.
We have now completed the implementation necessary to complete opt-in registration on a cart. To test that your implementation is working correctly start up your Medusa server using: `medusa develop`. You can now send requests to the server, first create a new cart using:
```shell
curl -X POST localhost:9000/store/carts | python -m json.tool
```
The copy the cart id (the one that starts with `cart_`) and use it to opt-in to the welcome pack using:
```shell
curl -X POST \
-H 'Content-Type: application/json' \
-d '{ "optin": true }' \
localhost:9000/welcome/[copied cart id]
```
The endpoint should respond with `{"success":true}`. If you wish to check that the `metadata` field has been updated you can fetch the created cart by doing:
```shell
curl -X GET localhost:9000/store/carts/[copied cart id] | python -m json.tool
```
The response should contain the cart with the metadata field set like this:
```
{
"cart": {
...,
"metadata": {
"welcome_optin": true
},
...
}
}
```
## Subscribers
The final thing that we will add in this part of the tutorial is the subscriber that listens for the `order.placed` event and sends out emails if the user has opted in for welcomes. Again we will leverage one of the special directories in Medusa that makes dependency injection easy and automatic. The directory to place a file in this time is the `/src/subscribers` directory, which treats exports as subscribers and makes sure the inject dependencies in a similar fashion to what we saw with services. To get started with our implementation create a file at `/src/subscribers/welcome.js` and add the following:
```javascript
class WelcomeSubscriber {
constructor({ welcomeService, eventBusService }) {
this.welcomeService_ = welcomeService
eventBusService.subscribe("order.placed", this.handleWelcome)
}
handleWelcome = async (data) => {
return await this.welcomeService_.sendWelcome(data.id);
};
}
export default WelcomeSubscriber;
```
The implementation above is all that is needed to automate the `sendWelcome` function to be called every time a new order is created. The subscriber class here delegates all of the business logic to the `sendWelcome` function, where we are checking for opt-in and first time buyers.
If we take a closer look at the constructor it will seem pretty familiar. Just like with our custom service, we are indicating which dependencies we would like to receive and Medusa will make sure to pass these on as the first argument to our constructor. In this case we are depending on the `welcomeService` which is used to take care of sending welcomes, and the `eventBusService` which is a core service in Medusa that handles events across your server allowing you to subscribe to events of interest. In this case we are using the `eventBusService` to subscribe to the `order.placed` event which is emitted every time a new order is created. The subscription is registered by the `eventBusService.subscribe` function which takes the event name to subscribe to as its first argument and a callback function to call when the event occurs, as its second argument.
In this case we are using the `handleWelcome` function as our callback. The callback function receives the data that is passed for the event. The `order.placed` event contains the order id in the data object which is what the `welcomeService` needs to handle the sending logic so we simply call `sendWelcome` with `data.id`.
You can now start up your server and test out the subscriber. Given that you have opted in to receiving welcome emails you can complete an order and you should receive an email with the welcome message.
## Summary
You have now learned how to add custom functionality to your Medusa server, which is one of the most powerful features of the Medusa core. The example above is quite simple, yet we have covered many of the customization capabilities available. We first looked at how to include custom business logic in Medusa by using services and dependency injection. Afterwards we put that logic to use when implementing our custom endpoint and in the final part of the tutorial we added some simple automation that handles sending the welcome message on every new order.
### What's next?
You have now been introduced to many of the key parts of Medusa and with your knowledge of customization you can now begin creating some really powerful commerce experiences. If you have an idea for a cool customization go ahead and make it right now! If you are not completely ready yet you can browse the reference docs further.
In the next part of this tutorial we will look into linking your local project with Medusa Cloud to make develpment smoother while leveraging the powerful management tools that merchants use to manage their Medusa store.

View File

@@ -0,0 +1,75 @@
# Creating your Medusa server
## Introduction
With the required software installed on your computer you are ready to start working on your first Medusa project.
In this part of the tutorial we will setup the skeleton for a Medusa store and will be making the first requests to your Medusa server.
Once you have completed this part of the tutorial you will have a powerful backend for digital commerce experiences. The server will be capable of handling orders, ensuring payments are going through, keeping basic product and customer data in sync, etc. You can use on of the frontend starters to quickly hook up your server to a presentation layer ([Gatsby](https://github.com/medusajs/gatsby-starter-medusa) or [Next](https://github.com/medusajs/nextjs-starter-medusa)).
## Setup a Medusa project
With Medusa CLI installed it is very easy to setup a new Medusa project, with the `new` command. In your command line run:
```shell
medusa new my-medusa-server --seed
```
The command will do a number of things:
- build a new project in a folder called my-medusa-server
- install the dependencies through yarn or npm
- setup a new git environment for version controlling your project
- create a database in postgres with the name my-medusa-server
- the `--seed` flag indicates that the database should be populated with some test data after the project has been set up
If you navigate to the root folder of your new project you will see the following files in your directory:
```
.
├── node_modules
├── src
│ ├── api
│ └── services
├── .babelrc
├── .gitignore
├── medusa-config.js
├── README.md
└── package.json
```
There is not a lot of files needed to get your Medusa store setup and this is all due to the fact that the main Medusa core (`@medusajs/medusa`) is installed as a dependency in your project giving you all the fundamental needs for a digital commerce experience.
Much of Medusa's power lies in the `medusa-config.js` which is the file that configures your store and orchestrates the plugins that you wish to use together with your store. There are some different types of plugin categories such as payment plugins, notification plugins and fulfillment plugins, but plugins can contain any form of extension that enhances your store.
For customizations that are more particular to your project you can extend your Medusa server by adding files in the `api` and `services` directories. More about customizing your server will follow in the following parts.
## Starting your Medusa server
After your project has been set up with `medusa new`, you can run the following commands to start your server:
```shell
cd my-medusa-server
medusa develop
```
If you ran the new command with the `--seed` flag you will already have products available in your store. To view these you can run the following command in your command line:
```shell
curl -X GET localhost:9000/store/products | python -m json.tool
```
## What's next?
At this point you are all set to start creating amazing digital commerce experiences. You can take a number of different routes from here and the next part of this tutorial will revolve around creating custom functionality within your Medusa project.
Other options you could take are:
### Add a frontend to your server
We have created two starters for you that can help you lay a foundation for your storefront. The starters work with your new server with minimal configuration simply clone the starters from here:
- [Nextjs Starter](https://github.com/medusajs/nextjs-starter-medusa)
- [Gatsby Starter](https://github.com/medusajs/gatsby-starter-medusa)
### Browse the API reference
In the API reference docs you can find all the available requests that are exposed by your new Medusa server. Interacting with the API is the first step to creating truly unique experiences.
### Setup Stripe as a payment provider (Guide coming soon)
One of the first things you may want to do when building out your store would be to add a payment provider. Your starter project comes with a dummy payment provider that simply fakes payments being processed. In the real world you want a payment provider that can handle credit card information securely and make sure that funds are being transfered to your account. Stripe is one of the most popular payment providers and Medusa has an official plugin that you can easily install in your project.
## Summary
In this part of the tutorial we have setup your first Medusa project using the `medusa new` command. You have now reached a key milestone as you are ready to start building your Medusa store; from here there are no limits to how you can use Medusa as you can customize and extend the functionality of the core. In the next part of the tutorial we will be exploring how you can add custom services and endpoints to fit your exact needs.

View File

@@ -0,0 +1,42 @@
# Linking your local project with Medusa Cloud
## Introduction
In this part of the tutorial you will learn how to link your local Medusa project to Medusa Cloud. Doing this will enhance you development experience as you will closely mimic how Medusa would work in a production environment. Furthermore, you will be able to easily manage orders and products in your local project directly from Medusa Cloud. Linking Medusa is easily done with the Medusa CLI which you should already be installed when you set up your development environment.
## Creating a Medusa Cloud account and CLI authentication
To link your local project you must first authenticate to Medusa using your CLI. Authenticating with the CLI is done by running:
```shell
medusa login
```
The `login` command will open your browser where you will be presented with the authentication options available. If you already have an account you can simply authenticate and you CLI will automatically be authenticated.
If you don't have an account yet you can easily create one as part of the CLI authentication. First, choose the method that you want to login with we support logging in with GitHub, Google or simple email/password authentication. If choosing GitHub or Google without an existing account you will be taken straight to the sign up form where you can fill in your details and create an account. If you wish to sign up with an email/password combination simply click "Log in with email" and at the bottom of the form click "Sign up". Once you have filled out the sign up form your CLI will be authenticated.
To test that you have successfully authenticated you can run:
```shell
medusa whoami
```
This will print out your account details.
## Linking your local project
Once you have authenticated your CLI for your Medusa Cloud account you are ready to perform local linking. To link your project first naviagate to your project root - where your `medusa-config.js` file is. You can now run the following command:
```shell
medusa link --develop
```
The `link` command will first check that you have authenticated your CLI which we did in the previous step. Then it will perform the local linking, which essentially adds an admin user in the local database specified in `medusa-config.js`. Finally, your browser will open Medusa Cloud to perform the linking there, which tells Medusa Cloud where your local server is running. On succesful linking in the browser you will see a confirmation page with a "Go to orders" button. If you click this button you will be taken to an overview of the orders made in your local project.
You should note that the `--develop` flag is optional for the `link` command. If provided it tells the CLI to start up your server after linking is completed; you may leave it out if you'd rather start your server separately.
> Note: For local linking to work you must make sure to have your CORS settings configured correctly. This is done by adding `https://app.medusa-commerce.com` to your `cors_admin` config in `medusa-config.js`.
> Note: If you change the port that your local server is running on you will have to run `medusa link` again. `medusa link` uses your `PORT` environment variable to specify where Medusa Cloud should look for your local server.
## Summary
You are now able to run a local development environment that is nearly identical to a production environment. This is made possible by linking your local project using the `medusa link` command. In Medusa Cloud you will be able to manage your store and test the features you are developing.
### What's next?
You are all set to start developing on your Medusa project. If you haven't already now would be a good time to add a front-end to your Medusa server. We have two starters that you can use to get going:
- [Nextjs Starter](https://github.com/medusajs/nextjs-starter-medusa)
- [Gatsby Starter](https://github.com/medusajs/gatsby-starter-medusa)
The final step to take from here is to deploy your Medusa project. We will cover how this is done in the next part of the tutorial (Coming soon!).

View File

@@ -0,0 +1,101 @@
---
title: Set up your development environment
---
# Set up your development environment
## Introduction
Welcome to Medusa - we are so excited to get you on board!
This tutorial will walk you through the steps to take to set up your local development environment. You will familiarize yourself with some of the core parts that make Medusa work and learn how to configure your development environment. Furthermore you will be introduced to how the plugin architecture works and how to customize your commerce functionalities with custom logic and endpoints.
As a final part of the tutorial you will be linking your local project to Medusa Cloud where you can leverage advanced tools that make it easy to develop, test and deploy your Medusa project.
## Background Knowledge and Prerequisites
This tutorial aims to be as inclusive as possible so that most people with a bit of web development exeperience will be able to follow along and understand what is going on. In case you are completely new to programming and are just setting out to start working on your first project it will be helpful to familiarize yourself with a couple of the technologies that Medusa is build on
- **JavaScript**: The programming language that Medusa is written in. It is the language that runs in your browser to create dynamic web applications and has over the past decade gained a lot of traction as a backend language. If you wish to customize or extend Medusa it is highly recommended that you learn how JavaScript works. You can learn more about JavaScript with the [Basic JavaScript course from freeCodeCamp.](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/#basic-javascript)
- **SQL & Postgresql**: Medusa uses the relational database PostgreSQL as the database layer where data is persisted. To understand how different entities relate to each other in Medusa it is helpful to have a good understanding of SQL. You can learn more about SQL and relational databases with the [SQL and Databases course from freeCodeCamp.](https://www.freecodecamp.org/news/sql-and-databases-full-course/)
- The **command line**: The command line is a text interface for your computer. It is used to run commands such as starting a program, performing a task or interfacing with the files on your computer. If you have never used the command line before you can check out [this tutorial](https://www.learnenough.com/command-line-tutorial) to get the basics in place.
To get a further understanding of what powers Medusa you can lookup these concepts:
- [**REST APIs**](https://en.wikipedia.org/wiki/Representational_state_transfer)
- [**Dependency Injection**](https://en.wikipedia.org/wiki/Dependency_injection)
- [**Idempotency Keys**](https://brandur.org/idempotency-keys)
## Installations
To get your development environment ready you need to install the following tools:
- Node.js
- Git
- Postgresql
- Redis
- Medusa CLI
### Node.js
Node.js is an environment that can execute JavaScript code on outside of the browser making it possible to run on a server. Node.js is the environment that makes it possible for Medusa to run so you must install Node.js on your computer to start Medusa development.
Node.js has a bundled package manager called npm. npm helps you install "packages" which are small pieces of code that you can leverage in your Node.js applications. Medusa's core is itself a package distributed via npm and so are all of the plugins that exist around the core. [You can install Node.js from here.](https://nodejs.org/en/)
If you prefer using something like homebrew you can also run:
```
brew install node
```
> **Mac users**: Make sure that you have Xcode command line tools installed; if not run `xcode-select --install`
### Git
Git is a version control system that keeps track on files within a project and makes it possible to do things like going back in history if you have made mistakes or collaborate with teammates without overriding each other's work. Almost all developers use Git for version control. Medusa uses git behind the scenes when you create a new project so you'll have to install it on your computer to get started.
If you are a Mac user you will already have Git installed as part of the Xcode command line tools, but for good measure check out installation of Git on different systems below:
- [Install Git on macOS](https://www.atlassian.com/git/tutorials/install-git)
- [Install Git on Windows](https://www.atlassian.com/git/tutorials/install-git#windows)
- [Install Git on Linux](https://www.atlassian.com/git/tutorials/install-git#linux)
### PostgreSQL
PostgreSQL is an open-source relational database system with more than 30 years of active development. It is robust, reliable and ensures data integrity so there's no need to worry about those when you scale your project. Medusa uses PostgreSQL as its database and you will need to install it on your computer to get going. [Install PostgreSQL from here.](https://www.postgresql.org/download/).
If you prefer to use homebrew you may install PostgreSQL by running:
```
brew install postgresql
brew services start postgresql
createdb
```
### Redis
Redis is an open-source in memory data structure store which is used in Medusa to emit messages in the system and cache data. [Install Redis from here.](https://redis.io/download)
If you prefer to use homebrew you may install Redis by running:
```
brew install redis
brew services start redis
```
### Medusa CLI
The final installation to do to get started with Medusa is the Medusa CLI, which is an npm package you can install globally on your computer to get instant access to commands that help you manage and run your Medusa project. As the Medusa CLI is distributed as an npm package it is very easily installed by running:
```
npm install -g @medusajs/medusa-cli
```
We like to use Yarn instead of npm; if you wish to do the same you can install the CLI with:
```
yarn global add @medusajs/medusa-cli
```
### Text editor
If you don't already have a text editor of choice you should find one you like - here is a couple of candidates:
- [Neovim](https://neovim.io/) (if you are super oldschool there's also plain [Vim](https://www.vim.org/))
- [VS Code](https://code.visualstudio.com/)
- [Atom](https://atom.io/)
It is not important which editor you use as long as you feel comfortable working with it.
## Medusa Cloud account
As the final step in this part of the tutorial you should create a Medusa Cloud account. Medusa Cloud is the platform that works with Medusa; the platform is where you view and manage your store, but is also a key part of the development process as you will be linking your local project to the platform so that you can manage your store while in development.
[Sign up for Medusa Cloud](https://app.medusa-commerce.com)
## Summary
You now have all required software installed on your computer and have been introduced to a bit of our tech stack. In the next part of this tutorial we will be setting up a Medusa project for the first time and start making API requests.