---
url: https://mikrojs.dev/getting-started.md
description: Set up your first Mikro.js project and blink an LED
---

::: warning Early development
Mikro.js is in its early days and is not intended for safety-critical or production use.
Expect APIs to change, and expect bugs (but we'd love to [hear about](https://github.com/mikrojs/mikro/issues) them!)
:::

# Getting Started

Mikro.js is for learners, hobbyists, and creators who want to tinker with hardware and build cool stuff.

This guide walks you through creating a Mikro.js project, flashing firmware to a board, and deploying your first TypeScript program.

## Prerequisites

* [Node.js](https://nodejs.org/) >= 24
* [pnpm](https://pnpm.io/installation) recommended, but npm, yarn, and bun work too
* An ESP32 development board
* A USB cable matching your board's port (for example USB-C)

::: tip Which board should I use?
Any ESP32, ESP32-S3, ESP32-C5, or ESP32-C6 board works with the default setup. We recommend the [Seeed Studio XIAO ESP32C6](https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C6-p-5884.html) as the default: small, cheap (~$5), USB-C, and the primary board Mikro.js is developed and tested against.

For network-heavy or memory-intensive apps, the [Seeed Studio XIAO ESP32C5](https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C5-p-6609.html) is a better pick. Its 8 MB PSRAM gives you room for things like graphics with a display framebuffer, audio buffers, larger HTTP payloads, and apps that hold significant state in memory.
:::

## Create a project

::: code-group

```sh [pnpm]
pnpm create mikro
```

```sh [npm]
npm create mikro
```

```sh [yarn]
yarn create mikro
```

```sh [bun]
bun create mikro
```

:::

This scaffolds a project with the following structure:

```
my-app/
├── app/
│   └── main.ts       # Your program entry point
├── package.json
└── tsconfig.json
```

::: tip Renamed from `mikrojs`
The package and CLI were renamed from `mikrojs` to `mikro` with no compatibility shim. Use the `mikro` dependency, the `mikro` command, and `mikro/`-prefixed imports (for example `import {DigitalOut} from 'mikro/gpio'`). The `@mikrojs/*` package scope is unchanged.
:::

::: details pnpm reports "Ignored build scripts: @mikrojs/quickjs"
`@mikrojs/quickjs` builds a small bytecode compiler (`qjsc`) in its postinstall script, and pnpm skips dependency build scripts unless they are approved. For the regular app workflow this is safe to ignore. You only need `qjsc` when building firmware from source (see [Custom Firmware](/develop/custom-firmware)); in that case run `pnpm approve-builds`, select `@mikrojs/quickjs`, and install again. Otherwise the firmware build fails with "qjsc not found".
:::

## Plug in your board

Connect your ESP32 board to your computer with a USB cable.

## Flash the firmware

::: code-group

```sh [pnpm]
pnpm mikro flash
```

```sh [npm]
npx mikro flash
```

```sh [yarn]
yarn mikro flash
```

```sh [bun]
bunx mikro flash
```

:::

This writes the Mikro.js runtime firmware into the board's flash memory. The firmware is the environment your TypeScript code runs in. You only need to do this once per board (or when updating Mikro.js).

## Develop

Run `mikro dev`:

::: code-group

```sh [pnpm]
pnpm mikro dev
```

```sh [npm]
npx mikro dev
```

```sh [yarn]
yarn mikro dev
```

```sh [bun]
bunx mikro dev
```

:::

This connects to your board, deploys your code, and watches for changes. Now open `app/main.ts` in your preferred code editor or IDE and write a blink program:

```ts twoslash
import {DigitalOut} from 'mikro/gpio'
import {sleep} from 'mikro/sleep'

// GPIO 15 is the built-in LED on XIAO ESP32C6. Replace with your board's LED pin.
const led = DigitalOut(15).orPanic('Failed to configure LED pin')

while (true) {
  led.write(1)
  await sleep(500)
  led.write(0)
  await sleep(500)
}
```

Every time you save, the new code is deployed to the device within seconds.

## Deploy it

When you're happy with your program, deploy it permanently:

::: code-group

```sh [pnpm]
pnpm mikro deploy
```

```sh [npm]
npx mikro deploy
```

```sh [yarn]
yarn mikro deploy
```

```sh [bun]
bunx mikro deploy
```

:::

This writes your program to the device's flash storage. It will keep running after reboot, without a computer connected.

## Next steps

* [Error Handling](/error-handling): learn how Mikro.js uses typed Results instead of exceptions
* [WiFi + Fetch example](/examples/wifi-fetch): connect to the internet and make HTTP requests
* [API Reference](/api/): explore the full API surface

Using an AI coding assistant? Point it at [llms.txt](https://mikrojs.dev/llms.txt) for an index of these docs, or [llms-full.txt](https://mikrojs.dev/llms-full.txt) for everything in a single file.
